2018-03-22 Alexandre Oliva <aoliva@redhat.com>
+ PR c++/84789
+ * pt.c (resolve_typename_type): Drop assert that stopped
+ simplification to template-independent types. Add assert to
+ verify the initial scope is template dependent.
+ * parser.c (cp_parser_parse_and_diagnose_invalid_type_name):
+ Reparse the id expression as a type-name, not a declarator.
+
PR c++/84729
* init.c (build_vec_init): Error at parenthesized array init.
/*template_keyword_p=*/false,
/*check_dependency_p=*/true,
/*template_p=*/NULL,
- /*declarator_p=*/true,
+ /*declarator_p=*/false,
/*optional_p=*/false);
/* If the next token is a (, this is a function with no explicit return
type, i.e. constructor, destructor or conversion op. */
gcc_assert (TREE_CODE (type) == TYPENAME_TYPE);
scope = TYPE_CONTEXT (type);
+ /* We shouldn't have built a TYPENAME_TYPE with a non-dependent scope. */
+ gcc_checking_assert (uses_template_parms (scope));
+
/* Usually the non-qualified identifier of a TYPENAME_TYPE is
TYPE_IDENTIFIER (type). But when 'type' is a typedef variant of
a TYPENAME_TYPE node, then TYPE_NAME (type) is set to the TYPE_DECL representing
/* scope is either the template itself or a compatible instantiation
like X<T>, so look up the name in the original template. */
scope = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope);
- /* We shouldn't have built a TYPENAME_TYPE with a non-dependent scope. */
- gcc_checking_assert (uses_template_parms (scope));
/* If scope has no fields, it can't be a current instantiation. Check this
before currently_open_class to avoid infinite recursion (71515). */
if (!TYPE_FIELDS (scope))
2018-03-22 Alexandre Oliva <aoliva@redhat.com>
+ PR c++/84789
+ * g++.dg/template/pr84789.C: New.
+ * g++.dg/template/pr84789-2.C: New.
+ * g++.dg/template/pr84789-3.C: New.
+ * g++.dg/parse/dtor11.C: Accept alternate error message.
+
PR c++/84729
* g++.dg/pr84729.C: New.
* g++.old-deja/g++.ext/arrnew2.C: Require error.
struct B
{
- A::~B B(); // { dg-error "as member of" }
+ A::~B B(); // { dg-error "as member of|as a type" }
};
--- /dev/null
+// { dg-do compile }
+
+struct K {
+ struct L {
+ static double j;
+ };
+};
+
+template <typename T>
+struct M {
+ struct N {
+ static int i;
+ };
+};
+
+template <typename T>
+struct O {
+ typedef M<T> P;
+ typedef K Q;
+};
+
+template <typename T>
+int O<T>::P::N::i = 42; // This is obfuscated, but apparently ok.
+
+template <typename T>
+double O<T>::Q::L::j = 42.0; // { dg-error "non-template" }
--- /dev/null
+// { dg-do compile }
+
+struct A
+{
+ static int i;
+};
+struct B
+{
+ typedef ::A A;
+};
+int B::A::i = 0;
+
+struct K
+{
+ struct L
+ {
+ template <typename T>
+ static void f(T);
+ };
+};
+
+template <typename T>
+struct O
+{
+ typedef K Q;
+};
+
+template <typename T>
+void O<T>::Q::L::f(T)
+{
+}
--- /dev/null
+// { dg-do compile }
+
+struct A
+{
+ typedef int I;
+};
+
+template<typename> struct B : A {};
+
+template<typename T> struct C : B<T>
+{
+ B<T>::A::I::I i; // { dg-error "typename" }
+};