]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
analyzer: fix ICEs on complex constants [PR105365,105366]
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 25 Apr 2022 23:36:37 +0000 (19:36 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Mon, 25 Apr 2022 23:36:37 +0000 (19:36 -0400)
gcc/analyzer/ChangeLog:
PR analyzer/105365
PR analyzer/105366
* svalue.cc
(cmp_cst): Rename to...
(cmp_csts_same_type): ...this.  Convert all recursive calls to
calls to...
(cmp_csts_and_types): ....this new function.
(svalue::cmp_ptr): Update for renaming of cmp_cst

gcc/testsuite/ChangeLog:
PR analyzer/105365
PR analyzer/105366
* gcc.dg/analyzer/pr105365.c: New test.
* gcc.dg/analyzer/pr105366.c: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
gcc/analyzer/svalue.cc
gcc/testsuite/gcc.dg/analyzer/pr105365.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/analyzer/pr105366.c [new file with mode: 0644]

index a1403f0fbefe320d687731833fe54d33bd36aadd..ed289c6fc317c2806b7a8640086e12f57f5b1c5e 100644 (file)
@@ -59,6 +59,8 @@ along with GCC; see the file COPYING3.  If not see
 
 namespace ana {
 
+static int cmp_csts_and_types (const_tree cst1, const_tree cst2);
+
 /* class svalue and its various subclasses.  */
 
 /* class svalue.  */
@@ -304,7 +306,7 @@ svalue::implicitly_live_p (const svalue_set *, const region_model *) const
    of the same type.  */
 
 static int
-cmp_cst (const_tree cst1, const_tree cst2)
+cmp_csts_same_type (const_tree cst1, const_tree cst2)
 {
   gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
   gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
@@ -323,9 +325,10 @@ cmp_cst (const_tree cst1, const_tree cst2)
                     TREE_REAL_CST_PTR (cst2),
                     sizeof (real_value));
     case COMPLEX_CST:
-      if (int cmp_real = cmp_cst (TREE_REALPART (cst1), TREE_REALPART (cst2)))
+      if (int cmp_real = cmp_csts_and_types (TREE_REALPART (cst1),
+                                            TREE_REALPART (cst2)))
        return cmp_real;
-      return cmp_cst (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
+      return cmp_csts_and_types (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
     case VECTOR_CST:
       if (int cmp_log2_npatterns
            = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
@@ -340,17 +343,26 @@ cmp_cst (const_tree cst1, const_tree cst2)
        {
          const_tree elt1 = VECTOR_CST_ENCODED_ELT (cst1, i);
          const_tree elt2 = VECTOR_CST_ENCODED_ELT (cst2, i);
-         int t1 = TYPE_UID (TREE_TYPE (elt1));
-         int t2 = TYPE_UID (TREE_TYPE (elt2));
-         if (int cmp_type = t1 - t2)
-           return cmp_type;
-         if (int el_cmp = cmp_cst (elt1, elt2))
+         if (int el_cmp = cmp_csts_and_types (elt1, elt2))
            return el_cmp;
        }
       return 0;
     }
 }
 
+/* Comparator for imposing a deterministic order on constants that might
+   not be of the same type.  */
+
+static int
+cmp_csts_and_types (const_tree cst1, const_tree cst2)
+{
+  int t1 = TYPE_UID (TREE_TYPE (cst1));
+  int t2 = TYPE_UID (TREE_TYPE (cst2));
+  if (int cmp_type = t1 - t2)
+    return cmp_type;
+  return cmp_csts_same_type (cst1, cst2);
+}
+
 /* Comparator for imposing a deterministic order on svalues.  */
 
 int
@@ -382,7 +394,7 @@ svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
        const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
        const_tree cst1 = constant_sval1->get_constant ();
        const_tree cst2 = constant_sval2->get_constant ();
-       return cmp_cst (cst1, cst2);
+       return cmp_csts_same_type (cst1, cst2);
       }
       break;
     case SK_UNKNOWN:
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105365.c b/gcc/testsuite/gcc.dg/analyzer/pr105365.c
new file mode 100644 (file)
index 0000000..aa576d0
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-require-effective-target int128 } */
+
+typedef _Float32 f32;
+typedef _Complex _Float32 cf32;
+_Float32 g;
+__int128 i;
+
+extern void bar(int);
+
+void
+foo(_Float32 k) {
+  f32 f = 0;
+  f /= (_Complex char)__builtin_llround(g);
+  k /= (cf32)__builtin_copysignf(0, i);
+  bar(f + k);
+  foo(0);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105366.c b/gcc/testsuite/gcc.dg/analyzer/pr105366.c
new file mode 100644 (file)
index 0000000..3dba870
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-require-effective-target int128 } */
+/* { dg-additional-options "-O" } */
+
+extern void bar(int);
+extern void baz(void);
+
+typedef unsigned u32;
+
+void
+foo(u32 u, __int128 i) {
+  baz();
+  _Complex int c = i;
+  c /= (u32)(__UINTPTR_TYPE__)foo;
+  short s = (short)(__UINTPTR_TYPE__)foo;
+  u /= (_Complex short)s;
+  u32 r = u + c;
+  bar(r);
+  foo(0, 0);
+}