* 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
+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
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);
/*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;
}
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)))
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,
+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
--- /dev/null
+// 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>;
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" }