diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 69e8fa7d1e3..d4d7816e0d5 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -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; } diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c b/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c new file mode 100644 index 00000000000..a73289cb83f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c b/gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c new file mode 100644 index 00000000000..0b59acdb6e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c @@ -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; +} diff --git a/gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f90 b/gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f90 new file mode 100644 index 00000000000..34cc25da01d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f90 @@ -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