analyzer: const functions have no side effects [PR104576]

PR analyzer/104576 tracks that we issue a false positive from
-Wanalyzer-use-of-uninitialized-value for the reproducers of PR 63311
when optimization is disabled.

The root cause is that the analyzer was considering that a call to
__builtin_sinf could have side-effects.

This patch fixes things by generalizing the handling for "pure"
functions to also consider "const" functions.

gcc/analyzer/ChangeLog:
	PR analyzer/104576
	* region-model.cc: Include "calls.h".
	(region_model::on_call_pre): Use flags_from_decl_or_type to
	generalize check for DECL_PURE_P to also check for ECF_CONST.

gcc/testsuite/ChangeLog:
	PR analyzer/104576
	* gcc.dg/analyzer/torture/uninit-pr63311.c: New test.
	* gcc.dg/analyzer/uninit-pr104576.c: New test.
	* gfortran.dg/analyzer/uninit-pr63311.f90: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
David Malcolm 2022-02-16 18:21:58 -05:00
parent cb3afcd2a3
commit 5fbcbcaff7
4 changed files with 193 additions and 2 deletions

View File

@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-phinodes.h"
#include "tree-ssa-operands.h"
#include "ssa-iterators.h"
#include "calls.h"
#if ENABLE_ANALYZER
@ -1271,13 +1272,14 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt,
in region-model-impl-calls.cc.
Having them split out into separate functions makes it easier
to put breakpoints on the handling of specific functions. */
int callee_fndecl_flags = flags_from_decl_or_type (callee_fndecl);
if (fndecl_built_in_p (callee_fndecl, BUILT_IN_NORMAL)
&& gimple_builtin_call_types_compatible_p (call, callee_fndecl))
switch (DECL_UNCHECKED_FUNCTION_CODE (callee_fndecl))
{
default:
if (!DECL_PURE_P (callee_fndecl))
if (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE)))
unknown_side_effects = true;
break;
case BUILT_IN_ALLOCA:
@ -1433,7 +1435,7 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt,
/* Handle in "on_call_post". */
}
else if (!fndecl_has_gimple_body_p (callee_fndecl)
&& !DECL_PURE_P (callee_fndecl)
&& (!(callee_fndecl_flags & (ECF_CONST | ECF_PURE)))
&& !fndecl_built_in_p (callee_fndecl))
unknown_side_effects = true;
}

View File

@ -0,0 +1,134 @@
/* { dg-additional-options "-Wno-analyzer-too-complex" } */
int foo ()
{
static volatile int v = 42;
int __result_foo;
__result_foo = (int) v;
return __result_foo;
}
void test (int * restrict n, int * restrict flag)
{
int i;
int j;
int k;
double t;
int tt;
double v;
if (*flag)
{
t = 4.2e+1;
tt = foo ();
}
L_1: ;
v = 0.0;
{
int D_3353;
D_3353 = *n;
i = 1;
if (i <= D_3353)
{
while (1)
{
{
int D_3369;
v = 0.0;
if (*flag)
{
if (tt == i)
{
{
double M_0;
M_0 = v;
if (t > M_0 || (int) (M_0 != M_0))
{
M_0 = t;
}
v = M_0;
}
}
L_5:;
}
L_4:;
{
int D_3359;
D_3359 = *n;
j = 1;
if (j <= D_3359)
{
while (1)
{
{
int D_3368;
{
int D_3362;
D_3362 = *n;
k = 1;
if (k <= D_3362)
{
while (1)
{
{
int D_3367;
{
double D_3366;
double M_1;
M_1 = v;
D_3366 = (double) __builtin_sinf ((float) (j * k));
if (D_3366 > M_1 || (int) (M_1 != M_1))
{
M_1 = D_3366;
}
v = M_1;
}
L_8:;
D_3367 = k == D_3362;
k = k + 1;
if (D_3367) goto L_9;
}
}
}
L_9:;
}
L_6:;
D_3368 = j == D_3359;
j = j + 1;
if (D_3368) goto L_7;
}
}
}
L_7:;
}
L_2:;
D_3369 = i == D_3353;
i = i + 1;
if (D_3369) goto L_3;
}
}
}
L_3:;
}
}
int main ()
{
int flag;
int n;
n = 4;
flag = 0;
test (&n, &flag);
return 0;
}

View File

@ -0,0 +1,16 @@
float
test_1 (int *flag, float theta)
{
float t;
float f;
if (*flag)
t = 2.0f;
f = __builtin_sinf (theta);
if (*flag)
f *= t;
return f;
}

View File

@ -0,0 +1,39 @@
! { dg-additional-options "-O0" }
MODULE M1
IMPLICIT NONE
CONTAINS
INTEGER FUNCTION foo()
INTEGER, VOLATILE :: v=42
foo=v
END FUNCTION
SUBROUTINE test(n,flag)
INTEGER :: n,i,j,k,l,tt
LOGICAL :: flag
REAL(KIND=8) :: v,t
IF (flag) THEN
t=42
tt=foo()
ENDIF
v=0
DO i=1,n
v=0
IF (flag) THEN
IF (tt==i) v=MAX(v,t)
ENDIF
DO j=1,n
DO k=1,n
v=MAX(v,sin(REAL(j*k)))
ENDDO
ENDDO
ENDDO
END SUBROUTINE
END MODULE M1
USE M1
INTEGER :: n
LOGICAL :: flag
n=4
flag=.FALSE.
CALL test(n,flag)
END