OSDN Git Service

PR tree-optimization/54986
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Nov 2012 21:41:32 +0000 (21:41 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Nov 2012 21:41:32 +0000 (21:41 +0000)
* gimple-fold.c (canonicalize_constructor_val): Strip again all no-op
conversions on entry but add them back on exit if needed.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@193189 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 778c7a6..52aa6f5 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  Richard Sandiford  <rdsandiford@googlemail.com>
 
        PR target/55204
index 5980854..5e4bd23 100644 (file)
@@ -115,7 +115,8 @@ can_refer_decl_in_current_unit_p (tree decl)
 tree
 canonicalize_constructor_val (tree cval)
 {
-  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)
     {
@@ -146,8 +147,12 @@ canonicalize_constructor_val (tree cval)
       /* 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 5dd0d28..8e2c69b 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  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
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);
+}