diff mbox

PR c++/52672

Message ID 4F7079C8.1070900@codesourcery.com
State New
Headers show

Commit Message

Meador Inge March 26, 2012, 2:14 p.m. UTC
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
way.

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
regressions.

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

Comments

Meador Inge March 30, 2012, 12:18 a.m. UTC | #1
On 03/26/2012 09:14 AM, Meador Inge wrote:

> 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
> way.
> 
> 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
> regressions.
> 
> P.S.  If it is OK can some please commit for me?  I don't have write access.

Hi Jason,

I saw where the fix for this got committed in r185890.  Thanks for applying
it for me.  What about the release branches?  I can reproduce the ICE in 4.6
and 4.7.  The patch from trunk applies to 4.7.  For 4.6 I think we can just
drop the assert.
diff mbox

Patch

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)
     {