aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/analyzer/region-model.cc6
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr63311.c134
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/uninit-pr104576.c16
-rw-r--r--gcc/testsuite/gfortran.dg/analyzer/uninit-pr63311.f9039
4 files changed, 193 insertions, 2 deletions
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 69e8fa7..d4d7816 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 0000000..a73289c
--- /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 0000000..0b59acd
--- /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 0000000..34cc25d
--- /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