Patchwork C++ PATCH for c++/57658 (ICE with decltype of captured variable)

login
register
mail settings
Submitter Jason Merrill
Date July 9, 2013, 6:44 p.m.
Message ID <51DC5A1F.8020606@redhat.com>
Download mbox | patch
Permalink /patch/257852/
State New
Headers show

Comments

Jason Merrill - July 9, 2013, 6:44 p.m.
I've recently adjusted finish_id_expression to return the identifier for 
various uses of outer local variables that aren't captures.  This is 
another.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit a9fe694d4756d7cd35a35c4fd8f0dd09543ba559
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jul 8 23:43:23 2013 -0400

    	PR c++/57658
    	* semantics.c (finish_id_expression): Return the id for an
    	unevaluated outer variable.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index b5bcb00..8da1af4 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3056,15 +3056,15 @@  finish_id_expression (tree id_expression,
 
       /* Disallow uses of local variables from containing functions, except
 	 within lambda-expressions.  */
-      if (!outer_var_p (decl)
-	  /* It's not a use (3.2) if we're in an unevaluated context.  */
-	  || cp_unevaluated_operand)
-	/* OK.  */;
-      else if (TREE_STATIC (decl))
+      if (!outer_var_p (decl))
+	/* OK */;
+      else if (TREE_STATIC (decl)
+	       /* It's not a use (3.2) if we're in an unevaluated context.  */
+	       || cp_unevaluated_operand)
 	{
 	  if (processing_template_decl)
-	    /* For a use of an outer static var, return the identifier so
-	       that we'll look it up again in the instantiation.  */
+	    /* For a use of an outer static/unevaluated var, return the id
+	       so that we'll look it up again in the instantiation.  */
 	    return id_expression;
 	}
       else
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template12.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template12.C
new file mode 100644
index 0000000..635af97
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template12.C
@@ -0,0 +1,19 @@ 
+// PR c++/57568
+// { dg-require-effective-target c++11 }
+
+template < class T >
+struct remove_reference
+{ typedef int type; };
+template < class T >
+class X
+{
+    enum Q { };
+    bool f ()
+    {
+        Q a;
+        [&a]{
+            typename remove_reference < decltype (a) >::type t;
+        };
+    }
+};
+template class X< int >;