OSDN Git Service

PR c++/11987
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Nov 2009 14:40:13 +0000 (14:40 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Nov 2009 14:40:13 +0000 (14:40 +0000)
* parser.c (cp_parser_direct_declarator): Give helpful error about
trying to define member of a dependent typedef.
* pt.c (resolve_typename_type): Don't resolve a typedef typename.
* tree.c (typedef_variant_p): New.
* cp-tree.h: Declare it.

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

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

index 988b602..1ffa86a 100644 (file)
@@ -1,3 +1,12 @@
+2009-11-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/11987
+       * parser.c (cp_parser_direct_declarator): Give helpful error about
+       trying to define member of a dependent typedef.
+       * pt.c (resolve_typename_type): Don't resolve a typedef typename.
+       * tree.c (typedef_variant_p): New.
+       * cp-tree.h: Declare it.
+
 2009-11-12  Jason Merrill  <jason@redhat.com>
 
        PR c++/27078
index f66a009..a71dc73 100644 (file)
@@ -5098,6 +5098,7 @@ extern bool type_has_nontrivial_copy_init (const_tree);
 extern bool class_tmpl_impl_spec_p             (const_tree);
 extern int zero_init_p                         (const_tree);
 extern tree strip_typedefs                     (tree);
+extern bool typedef_variant_p                  (tree);
 extern tree copy_binfo                         (tree, tree, tree,
                                                 tree *, int);
 extern int member_p                            (const_tree);
index f77ec55..05def24 100644 (file)
@@ -14191,10 +14191,17 @@ cp_parser_direct_declarator (cp_parser* parser,
                                              /*only_current_p=*/false);
                /* If that failed, the declarator is invalid.  */
                if (TREE_CODE (type) == TYPENAME_TYPE)
-                 error_at (declarator_id_start_token->location,
-                           "%<%T::%E%> is not a type",
-                           TYPE_CONTEXT (qualifying_scope),
-                           TYPE_IDENTIFIER (qualifying_scope));
+                 {
+                   if (typedef_variant_p (type))
+                     error_at (declarator_id_start_token->location,
+                               "cannot define member of dependent typedef "
+                               "%qT", type);
+                   else
+                     error_at (declarator_id_start_token->location,
+                               "%<%T::%E%> is not a type",
+                               TYPE_CONTEXT (qualifying_scope),
+                               TYPE_IDENTIFIER (qualifying_scope));
+                 }
                qualifying_scope = type;
              }
 
index 0e688bf..85d9fff 100644 (file)
@@ -17689,6 +17689,9 @@ resolve_typename_type (tree type, bool only_current_p)
      to look inside it.  */
   if (only_current_p && !currently_open_class (scope))
     return type;
+  /* If this is a typedef, we don't want to look inside (c++/11987).  */
+  if (typedef_variant_p (type))
+    return type;
   /* If SCOPE isn't the template itself, it will not have a valid
      TYPE_FIELDS list.  */
   if (same_type_p (scope, CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope)))
index 9dae184..f9e1cd7 100644 (file)
@@ -1067,6 +1067,14 @@ strip_typedefs (tree t)
   return cp_build_qualified_type (result, cp_type_quals (t));
 }
 
+/* Returns true iff TYPE is a type variant created for a typedef. */
+
+bool
+typedef_variant_p (tree type)
+{
+  return is_typedef_decl (TYPE_NAME (type));
+}
+
 \f
 /* Makes a copy of BINFO and TYPE, which is to be inherited into a
    graph dominated by T.  If BINFO is NULL, TYPE is a dependent base,
index 3194252..20f4686 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/11987
+       * g++.dg/parse/typename11.C: New.
+       * g++.dg/template/crash48.C: Adjust.
+
 2009-11-13  Uros Bizjak  <ubizjak@gmail.com>
 
        PR testsuite/42001
diff --git a/gcc/testsuite/g++.dg/parse/typename11.C b/gcc/testsuite/g++.dg/parse/typename11.C
new file mode 100644 (file)
index 0000000..a79e6d8
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/11987
+
+template <int dim> struct X {
+  struct I { I(); };
+};
+
+template <int dim> struct Y : X<dim> {
+  typedef typename X<dim>::I I;
+};
+
+// note: I is nested type in X, not Y!
+template <int dim>
+Y<dim>::I::I () {}             // { dg-error "dependent typedef" }
+// { dg-error "no type|dependent type" "" { target *-*-* } 13 }
+
+template struct Y<1>;
index deb9446..6aa3aa3 100644 (file)
@@ -7,4 +7,4 @@ template<typename T> struct A
   typedef typename T::X X;
 };
 
-template<typename T> A<T>::X::X() {} // { dg-error "no type|invalid use|not a type" }
+template<typename T> A<T>::X::X() {} // { dg-error "no type|invalid use|not a type|dependent" }