diff mbox series

[PR,c++/86374] Name lookup failure in enclosing template

Message ID 5e721933-1bfe-7911-7b86-856ed0a9bc9b@acm.org
State New
Headers show
Series [PR,c++/86374] Name lookup failure in enclosing template | expand

Commit Message

Nathan Sidwell July 13, 2018, 3:32 p.m. UTC
This was a latent problem exposed by Jason's fix for 85815.  There we 
needed to find the class in the scope stack.  Unfortunately, here we'd 
pushed an (incomplete) instantiation list<T>, rather than the general 
template list<T>.  We were previously getting away with that because 
we'd do the lookup in the a tsubstd scope, that had found the general 
template in another way.

The fix is to have lookup_template call tsubst_aggr_class directly for 
contexts that are classes, with the entering_scope flag set.  That way 
we figure that list<T> is the general template.  This matches the code 
in tsubst_aggr_class itself, when it's tsubsting the context of the 
class it is dealing with.

A small drive-by cleanup in the parser.

Committing to trunk now. will commit to gcc-8 after testing there.

nathan
diff mbox series

Patch

2018-07-13  Nathan Sidwell  <nathan@acm.org>

	PR c++/86374
	* pt.c (lookup_template_class_1): Use tsubst_aggr_type for
	contexts that are classes.
	* parser.c (cp_parser_template_id): Combine entering_scope decl &
	initializer.

	PR c++/86374
	* g++.dg/pr86374.C: New.

Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 262582)
+++ cp/parser.c	(working copy)
@@ -15973,15 +15973,14 @@  cp_parser_template_id (cp_parser *parser
   else if (DECL_TYPE_TEMPLATE_P (templ)
 	   || DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
     {
-      bool entering_scope;
       /* In "template <typename T> ... A<T>::", A<T> is the abstract A
 	 template (rather than some instantiation thereof) only if
 	 is not nested within some other construct.  For example, in
 	 "template <typename T> void f(T) { A<T>::", A<T> is just an
 	 instantiation of A.  */
-      entering_scope = (template_parm_scope_p ()
-			&& cp_lexer_next_token_is (parser->lexer,
-						   CPP_SCOPE));
+      bool entering_scope
+	= (template_parm_scope_p ()
+	   && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE));
       template_id
 	= finish_template_type (templ, arguments, entering_scope);
     }
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 262582)
+++ cp/pt.c	(working copy)
@@ -9368,8 +9368,15 @@  lookup_template_class_1 (tree d1, tree a
 	  return found;
 	}
 
-      context = tsubst (DECL_CONTEXT (gen_tmpl), arglist,
-			complain, in_decl);
+      context = DECL_CONTEXT (gen_tmpl);
+      if (context && TYPE_P (context))
+	{
+	  context = tsubst_aggr_type (context, arglist, complain, in_decl, true);
+	  context = complete_type (context);
+	}
+      else
+	context = tsubst (context, arglist, complain, in_decl);
+
       if (context == error_mark_node)
 	return error_mark_node;
 
Index: testsuite/g++.dg/pr86374.C
===================================================================
--- testsuite/g++.dg/pr86374.C	(revision 0)
+++ testsuite/g++.dg/pr86374.C	(working copy)
@@ -0,0 +1,20 @@ 
+// pr C++/86374
+// bogus lookup error
+template<typename LIST>
+struct list {
+  static const int index = 1;
+  template <typename> struct addWithChecking {};
+};
+
+template<typename container, int ix = container::index>
+struct find {
+  static const int result = 0;
+};
+
+template <class LIST>
+template<class O>
+struct list<LIST>::addWithChecking<O*>
+{
+  static const int xres =
+    find<list<LIST> >::result; // bogus error about index here.
+};