Patchwork C++ (RFC) PATCH fix for PR55076 and PR53921

login
register
mail settings
Submitter Markus Trippelsdorf
Date Oct. 27, 2012, 7:02 a.m.
Message ID <20121027070243.GA13009@x4>
Download mbox | patch
Permalink /patch/194602/
State New
Headers show

Comments

Markus Trippelsdorf - Oct. 27, 2012, 7:02 a.m.
The problem here is that we end up with an INDIRECT_REF TREE_CODE with a
null TREE_TYPE in lvalue_kind. Is this possible at that point, or does
it point to a deeper underlying problem?

Bootstraped and tested on x86_64-pc-linux-gnu.

2012-10-27  Markus Trippelsdorf  <markus@trippelsdorf.de>

	PR c++/50089
	PR c++/53921
	PR c++/55076
	* tree.c (lvalue_kind): Guard against null TREE_TYPE.
Markus Trippelsdorf - Nov. 2, 2012, 11:50 a.m.
On 2012.10.27 at 09:02 +0200, Markus Trippelsdorf wrote:
> The problem here is that we end up with an INDIRECT_REF TREE_CODE with a
> null TREE_TYPE in lvalue_kind. Is this possible at that point, or does
> it point to a deeper underlying problem?

It looks like there is indeed a deeper problem. See PR53137, PR53697 and 
PR54431 (which are all dups of one another). 

For example:

template<class>struct A
{
  void blah();
  void bar()
  {
    [this] { blah(); } (); // crash without this->blah()
  }
};

int main()
{
  A<int> a;
  a.bar();
}

Patch

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 8d555c2..0f1a75d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -145,7 +145,7 @@  lvalue_kind (const_tree ref)
     case ARRAY_REF:
     case PARM_DECL:
     case RESULT_DECL:
-      if (TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
+      if (TREE_TYPE (ref) && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
 	return clk_ordinary;
       break;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template8.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template8.C
new file mode 100644
index 0000000..76b6376
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template8.C
@@ -0,0 +1,12 @@ 
+// PR c++/50089 c++/53921 c++/55076
+// { dg-do compile { target c++11 } }
+void a (int);
+template <bool>
+struct A
+{
+    int b;
+    void c ()
+    {
+        [=] { a (b); }; //ICE without this->b
+    };
+};