Hi All,

This patch fixes an ICE that occurs when attempting to fold nested INDIRECT_REF
trees that have conversions in between the indirect references.  For example:

constexpr unsigned long b = *((ul_ptr)(*((ul_ptr)0x0)));

What happens is that 'cxx_fold_indirect_ref' gets the top indirect reference,
strips out all the conversions ending up with the nested indirect reference,
and then asserts that the type is a pointer type, which (obviously) it isn't.

This patch fixes the problem by exiting the fold for non-pointer sub-trees
instead of doing the assert.  'fold_indirect_ref_1' already does things this

Tested on x86_64 GNU/Linux.  OK?

Also, This fixes the problem on trunk, but I have reproduced the issue back to
the 4.6 branch as well.  On the 4.6 branch I think it is OK to just remove the
'gcc_assert (POINTER_TYPE_P (subtype))' assert.  I tested this and saw no

P.S.  If it is OK can some please commit for me?  I don't have write access.

Meador Inge
CodeSourcery / Mentor Embedded
2012-03-26  Meador Inge  <mead...@codesourcery.com>

	PR c++/52672
	* gcc/cp/semantics.c (cxx_fold_indirect_ref): Don't attempt to fold
	stripped child trees that are not pointer types.

2012-03-26  Meador Inge  <mead...@codesourcery.com>

	PR c++/52672
	* g++.dg/cpp0x/constexpr-52672.C: New testcase.
Index: gcc/testsuite/g++.dg/cpp0x/constexpr-52672.C
--- gcc/testsuite/g++.dg/cpp0x/constexpr-52672.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-52672.C	(revision 0)
@@ -0,0 +1,8 @@
+// PR c++/52672
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+typedef unsigned long * ul_ptr;
+constexpr unsigned long a = *((ul_ptr)0x0); // { dg-error "" }
+constexpr unsigned long b = *((ul_ptr)(*((ul_ptr)0x0))); // { dg-error "" }
+constexpr unsigned long c = *((ul_ptr)*((ul_ptr)(*((ul_ptr)0x0)))); // { dg-error "" }
Index: gcc/cp/semantics.c
--- gcc/cp/semantics.c	(revision 185750)
+++ gcc/cp/semantics.c	(working copy)
@@ -7202,7 +7202,8 @@ cxx_fold_indirect_ref (location_t loc, tree type,
   sub = op0;
   STRIP_NOPS (sub);
   subtype = TREE_TYPE (sub);
-  gcc_assert (POINTER_TYPE_P (subtype));
+  if (!POINTER_TYPE_P (subtype))
+    return NULL_TREE;
   if (TREE_CODE (sub) == ADDR_EXPR)

Reply via email to