OSDN Git Service

PR c++/26261
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 18 Feb 2010 16:27:18 +0000 (16:27 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 18 Feb 2010 16:27:18 +0000 (16:27 +0000)
PR c++/43101
* pt.c (tsubst_qualified_id): Do normal lookup in non-dependent scope.
(maybe_update_decl_type): New fn.
* parser.c (cp_parser_init_declarator): Use it.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156865 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/dependent-name6.C [new file with mode: 0644]

index 357b925..1fdeef4 100644 (file)
@@ -1,5 +1,11 @@
 2010-02-18  Jason Merrill  <jason@redhat.com>
 
+       PR c++/26261
+       PR c++/43101
+       * pt.c (tsubst_qualified_id): Do normal lookup in non-dependent scope.
+       (maybe_update_decl_type): New fn.
+       * parser.c (cp_parser_init_declarator): Use it.
+
        PR c++/43109
        * semantics.c (begin_class_definition): Don't crash on unnamed ns.
 
index b5330a3..8b5bb56 100644 (file)
@@ -4896,6 +4896,7 @@ extern tree process_template_parm         (tree, location_t, tree,
                                                 bool, bool);
 extern tree end_template_parm_list             (tree);
 extern void end_template_decl                  (void);
+extern tree maybe_update_decl_type             (tree, tree);
 extern bool check_default_tmpl_args             (tree, tree, int, int, int);
 extern tree push_template_decl                 (tree);
 extern tree push_template_decl_real            (tree, bool);
index 690f2c0..55d0517 100644 (file)
@@ -13477,6 +13477,11 @@ cp_parser_init_declarator (cp_parser* parser,
      we compute it now.  */
   scope = get_scope_of_declarator (declarator);
 
+  /* Perform any lookups in the declared type which were thought to be
+     dependent, but are not in the scope of the declarator.  */
+  decl_specifiers->type
+    = maybe_update_decl_type (decl_specifiers->type, scope);
+
   /* If we're allowing GNU extensions, look for an asm-specification
      and attributes.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
index 0165a7d..9e159a2 100644 (file)
@@ -3672,6 +3672,55 @@ current_template_args (void)
   return args;
 }
 
+/* Update the declared TYPE by doing any lookups which were thought to be
+   dependent, but are not now that we know the SCOPE of the declarator.  */
+
+tree
+maybe_update_decl_type (tree orig_type, tree scope)
+{
+  tree type = orig_type;
+
+  if (type == NULL_TREE)
+    return type;
+
+  if (TREE_CODE (orig_type) == TYPE_DECL)
+    type = TREE_TYPE (type);
+
+  if (scope && TYPE_P (scope) && dependent_type_p (scope)
+      && dependent_type_p (type)
+      /* Don't bother building up the args in this case.  */
+      && TREE_CODE (type) != TEMPLATE_TYPE_PARM)
+    {
+      /* tsubst in the args corresponding to the template parameters,
+        including auto if present.  Most things will be unchanged, but
+        make_typename_type and tsubst_qualified_id will resolve
+        TYPENAME_TYPEs and SCOPE_REFs that were previously dependent.  */
+      tree args = current_template_args ();
+      tree auto_node = type_uses_auto (type);
+      if (auto_node)
+       {
+         tree auto_vec = make_tree_vec (1);
+         TREE_VEC_ELT (auto_vec, 0) = auto_node;
+         args = add_to_template_args (args, auto_vec);
+       }
+      push_scope (scope);
+      type = tsubst (type, args, tf_warning_or_error, NULL_TREE);
+      pop_scope (scope);
+    }
+
+  if (type == error_mark_node)
+    return orig_type;
+
+  if (TREE_CODE (orig_type) == TYPE_DECL)
+    {
+      if (same_type_p (type, TREE_TYPE (orig_type)))
+       type = orig_type;
+      else
+       type = TYPE_NAME (type);
+    }
+  return type;
+}
+
 /* Return a TEMPLATE_DECL corresponding to DECL, using the indicated
    template PARMS.  If MEMBER_TEMPLATE_P is true, the new template is
    a member template.  Used by push_template_decl below.  */
@@ -10609,14 +10658,9 @@ tsubst_qualified_id (tree qualified_id, tree args,
   else
     expr = name;
 
-  if (dependent_type_p (scope))
-    {
-      tree type = NULL_TREE;
-      if (DECL_P (expr) && !dependent_scope_p (scope))
-       type = TREE_TYPE (expr);
-      return build_qualified_name (type, scope, expr,
-                                  QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
-    }
+  if (dependent_scope_p (scope))
+    return build_qualified_name (NULL_TREE, scope, expr,
+                                QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
 
   if (!BASELINK_P (name) && !DECL_P (expr))
     {
index dbc8226..4225d99 100644 (file)
@@ -1,5 +1,8 @@
 2010-02-18  Jason Merrill  <jason@redhat.com>
 
+       PR c++/26261
+       * g++.dg/template/dependent-name6.C: New.
+
        PR c++/43109
        * g++.dg/parse/namespace12.C: New.
 
diff --git a/gcc/testsuite/g++.dg/template/dependent-name6.C b/gcc/testsuite/g++.dg/template/dependent-name6.C
new file mode 100644 (file)
index 0000000..e08bbe1
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/26261
+// { dg-final { scan-assembler "_ZN1YIiE1fIiEE1XILi1EEv" } }
+
+template <int dim> class X {};
+
+template <class T> struct Y {
+  static const unsigned int dim = 1;
+  template <class U> X<Y<T>::dim> f();
+};
+
+template <class T> template <class U>
+X<Y<T>::dim> Y<T>::f() { return X<dim>(); }
+
+int main()
+{
+  Y<int>().f<int>();
+}