]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/54986 (segfault on constant initialized to object address...
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 5 Nov 2012 21:39:02 +0000 (21:39 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 5 Nov 2012 21:39:02 +0000 (21:39 +0000)
PR tree-optimization/54986
* gimple-fold.c (canonicalize_constructor_val): Strip again all no-op
conversions on entry but add them back on exit if needed.

From-SVN: r193188

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/20121105-1.C [new file with mode: 0644]

index d0ba9426b2a80ecdc07719b01afdcca25e23e4fa..5fab821eb76e70c05b2af71bf506ca1dc26a6705 100644 (file)
@@ -1,3 +1,9 @@
+2012-11-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR tree-optimization/54986
+       * gimple-fold.c (canonicalize_constructor_val): Strip again all no-op
+       conversions on entry but add them back on exit if needed.
+
 2012-11-05  Andreas Schwab  <schwab@linux-m68k.org>
 
        * final.c (final_scan_insn) [HAVE_cc0]: Handle all comparison
index 66d076664cc3cadda3d2a7b67af77840c44733f5..969cfeb582929315cdaeeb2c89ebc78fba2e8556 100644 (file)
@@ -139,7 +139,8 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
 tree
 canonicalize_constructor_val (tree cval, tree from_decl)
 {
-  STRIP_USELESS_TYPE_CONVERSION (cval);
+  tree orig_cval = cval;
+  STRIP_NOPS (cval);
   if (TREE_CODE (cval) == POINTER_PLUS_EXPR
       && TREE_CODE (TREE_OPERAND (cval, 1)) == INTEGER_CST)
     {
@@ -182,8 +183,12 @@ canonicalize_constructor_val (tree cval, tree from_decl)
       /* Fixup types in global initializers.  */
       if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
        cval = build_fold_addr_expr (TREE_OPERAND (cval, 0));
+
+      if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
+       cval = fold_convert (TREE_TYPE (orig_cval), cval);
+      return cval;
     }
-  return cval;
+  return orig_cval;
 }
 
 /* If SYM is a constant variable with known value, return the value.
index af92ce4c7f58b689ff2c8b5d30be401346756429..e870aa5bb9fb6bcfa0336c3d44a9afc88ec8e782 100644 (file)
@@ -1,3 +1,7 @@
+2012-11-05  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * g++.dg/torture/20121105-1.C: New test.
+
 2012-11-05  Andreas Schwab  <schwab@linux-m68k.org>
 
        * gcc.dg/torture/fp-compare.c: New testcase.
diff --git a/gcc/testsuite/g++.dg/torture/20121105-1.C b/gcc/testsuite/g++.dg/torture/20121105-1.C
new file mode 100644 (file)
index 0000000..0332342
--- /dev/null
@@ -0,0 +1,42 @@
+// PR tree-optimization/54986
+// Reported by Remi Vanicat <vanicat@debian.org>
+// Reduced testcase by Markus Trippelsdorf <markus@trippelsdorf.de> 
+
+struct A;
+struct B
+{
+  int *_ptr;
+  bool operator==(B *p1)
+  {
+    return p1->_ptr;
+  }
+};
+struct C {
+  A* ref_SYMBptr();
+};
+struct A
+{
+  B sommet;
+};
+typedef C *gen_op_context;
+struct D
+{
+  D(gen_op_context) {}
+};
+
+D c(0);
+const long d = (long)&c;
+B *const   e = (B *)&d;
+
+static bool
+fn1(C& p1)
+{
+  return p1.ref_SYMBptr()->sommet == e;
+}
+
+void
+fn2()
+{
+  C b;
+  fn1(b);
+}