Patchwork C++ PATCH for c++/51554 (ICE on constant initialization with pointer arithmetic)

login
register
mail settings
Submitter Jason Merrill
Date Dec. 14, 2011, 10:10 p.m.
Message ID <4EE91ED9.9080300@redhat.com>
Download mbox | patch
Permalink /patch/131483/
State New
Headers show

Comments

Jason Merrill - Dec. 14, 2011, 10:10 p.m.
Here we were assuming that the type of a POINTER_PLUS_EXPR would reflect 
the underlying type of the object, which is not the case with this 
testcase.  So now we keep looking until we find the ADDR_EXPR.

Tested x86_64-pc-linux-gnu, applying to trunk.
Gabriel Dos Reis - Dec. 14, 2011, 11:49 p.m.
On Wed, Dec 14, 2011 at 4:10 PM, Jason Merrill <jason@redhat.com> wrote:
> Here we were assuming that the type of a POINTER_PLUS_EXPR would reflect the
> underlying type of the object, which is not the case with this testcase.  So
> now we keep looking until we find the ADDR_EXPR.
>
> Tested x86_64-pc-linux-gnu, applying to trunk.

my fault.  Thanks.

Patch

commit 482c1bb6a00cdd911df18d2fd3486ee00fc2fad5
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Dec 14 16:38:13 2011 -0500

    	PR c++/51554
    	* semantics.c (cxx_eval_indirect_ref): Fix sanity check.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 7e1a396..ef85e45 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7329,9 +7329,15 @@  cxx_eval_indirect_ref (const constexpr_call *call, tree t,
     {
       tree sub = op0;
       STRIP_NOPS (sub);
-      if (TREE_CODE (sub) == ADDR_EXPR
-	  || TREE_CODE (sub) == POINTER_PLUS_EXPR)
+      if (TREE_CODE (sub) == POINTER_PLUS_EXPR)
 	{
+	  sub = TREE_OPERAND (sub, 0);
+	  STRIP_NOPS (sub);
+	}
+      if (TREE_CODE (sub) == ADDR_EXPR)
+	{
+	  /* We couldn't fold to a constant value.  Make sure it's not
+	     something we should have been able to fold.  */
 	  gcc_assert (!same_type_ignoring_top_level_qualifiers_p
 		      (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
 	  /* DR 1188 says we don't have to deal with this.  */
diff --git a/gcc/testsuite/g++.dg/init/constant1.C b/gcc/testsuite/g++.dg/init/constant1.C
new file mode 100644
index 0000000..386b926
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/constant1.C
@@ -0,0 +1,17 @@ 
+// PR c++/51554
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+const uint32 XX[] = { 1, 3, 7 };
+
+const uint8 V[] = {
+  *(((const uint8*)&XX[0]) + 0),
+  *(((const uint8*)&XX[0]) + 1),
+  *(((const uint8*)&XX[0]) + 2),
+  *(((const uint8*)&XX[0]) + 3),
+  *(((const uint8*)&XX[1]) + 0),
+  *(((const uint8*)&XX[1]) + 1),
+  *(((const uint8*)&XX[1]) + 2),
+  *(((const uint8*)&XX[1]) + 3),
+};