When we see INSTANCE->moo(), the type of INSTANCE is an opaque version
of A<T> that has no members.  We need to recognize that it's a type
we're currently inside, and use the version we're building up when
looking for a base or member.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 675b027654850c182c8eb5b148e8164ecb2a4c4f
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu May 24 12:31:08 2018 -0400

            PR c++/85815 - reference to member of enclosing template.
    
            * search.c (lookup_base): Use currently_open_class.
            (lookup_member): Use it regardless of -fconcepts.
            * parser.c (cp_parser_postfix_dot_deref_expression): Check it.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 25753d4c45f..c15390f4043 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -7463,8 +7463,8 @@ pop_class_stack (void)
     --current_class_stack[current_class_depth - 1].hidden;
 }
 
-/* Returns 1 if the class type currently being defined is either T or
-   a nested type of T.  Returns the type from the current_class_stack,
+/* If the class type currently being defined is either T or
+   a nested type of T, returns the type from the current_class_stack,
    which might be equivalent to but not equal to T in case of
    constrained partial specializations.  */
 
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d3e73488e84..c8d4e296ac3 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7488,10 +7488,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
 	 access (5.2.5) outside the member function body.  */
       if (postfix_expression != current_class_ref
 	  && scope != error_mark_node
-	  && !(processing_template_decl
-	       && current_class_type
-	       && (same_type_ignoring_top_level_qualifiers_p
-		   (scope, current_class_type))))
+	  && !currently_open_class (scope))
 	{
 	  scope = complete_type (scope);
 	  if (!COMPLETE_TYPE_P (scope)
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 22c0492f535..d4214d4198a 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -192,6 +192,9 @@ lookup_base (tree t, tree base, base_access access,
   else
     {
       t = complete_type (TYPE_MAIN_VARIANT (t));
+      if (dependent_type_p (t))
+	if (tree open = currently_open_class (t))
+	  t = open;
       t_binfo = TYPE_BINFO (t);
     }
 
@@ -1117,7 +1120,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type,
 
   /* Make sure we're looking for a member of the current instantiation in the
      right partial specialization.  */
-  if (flag_concepts && dependent_type_p (type))
+  if (dependent_type_p (type))
     if (tree t = currently_open_class (type))
       type = t;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-dependent1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-dependent1.C
new file mode 100644
index 00000000000..6fd2bb379bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-dependent1.C
@@ -0,0 +1,19 @@
+// PR c++/85815
+// { dg-do compile { target c++11 } }
+
+template<class T>
+class A {
+    static A* INSTANCE;
+    void foobar();
+    void moo() {}
+};
+
+template<class T>
+A<T>* A<T>::INSTANCE = nullptr;
+
+template<class T>
+void A<T>::foobar() {
+    auto x = []() {
+        INSTANCE->moo();
+    };
+}

Reply via email to