PR c++/85815 - reference to member of enclosing template.
authorJason Merrill <jason@redhat.com>
Fri, 25 May 2018 21:03:07 +0000 (17:03 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 25 May 2018 21:03:07 +0000 (17:03 -0400)
* 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.

From-SVN: r260782

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/parser.c
gcc/cp/search.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-dependent1.C [new file with mode: 0644]

index 9c2548d53779529ee0c88a2a6962d5d26299b74a..58fc696c571cf1b2984e524eb59416d065c9ac9c 100644 (file)
@@ -1,5 +1,10 @@
 2018-05-25  Jason Merrill  <jason@redhat.com>
 
+       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.
+
        CWG 616, 1213 - value category of subobject references.
        * tree.c (lvalue_kind): Fix handling of ARRAY_REF of pointer.
 
index a17c8ed8b4593018745dbc6429d0953c328018c9..ab68b9be42a661c18feb4c159d1854f05c1279a0 100644 (file)
@@ -7462,8 +7462,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.  */
 
index f5a6d940601044c269fbc59cc949b2c3836a0a68..d17beb8f93078194596f934b516631911e2cddd3 100644 (file)
@@ -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)
index e343a15c042488a6c83d63176810bf9ca290a303..c2860b0dc9a8e20e7d4690971afcfa4953e9ee62 100644 (file)
@@ -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 (file)
index 0000000..6fd2bb3
--- /dev/null
@@ -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();
+    };
+}