aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2009-11-08 03:47:36 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2009-11-08 03:47:36 +0000
commit393af3a28e1ad8299ae72f130e2d1fe581cada1d (patch)
treedd1b28a0105b37143349e8a0082a6894d5afb12c
parentfb2f8a88feedf97893673a6909376d97f42aca52 (diff)
PR c++/18451
PR c++/40738 * cp-tree.h (cp_decl_specifier_seq): Add any_type_specifiers_p. * parser.c (cp_parser_single_declaration): Call cp_parser_parse_and_diagnose_invalid_type_name here, too. (cp_parser_parameter_declaration): And here. (cp_parser_parse_and_diagnose_invalid_type_name): Be less picky about declarator form. Don't skip to the end of the block if we're in a declarator. (cp_parser_decl_specifier_seq): Set any_type_specifiers_p. (cp_parser_simple_declaration): Check it. (cp_parser_member_declaration): Likewise. (cp_parser_diagnose_invalid_type_name): Tweak error message. (cp_parser_expression_statement): Likewise. * decl2.c (grokfield): Mention decltype instead of typeof. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@154006 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog18
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/parser.c38
-rw-r--r--gcc/testsuite/ChangeLog25
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/typedef-init.C8
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class1.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class10.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class5.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class7.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/strong-using-2.C2
-rw-r--r--gcc/testsuite/g++.dg/other/typedef1.C4
-rw-r--r--gcc/testsuite/g++.dg/parse/access10.C6
-rw-r--r--gcc/testsuite/g++.dg/parse/constructor1.C6
-rw-r--r--gcc/testsuite/g++.dg/parse/crash38.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/error3.C4
-rw-r--r--gcc/testsuite/g++.dg/parse/error36.C22
-rw-r--r--gcc/testsuite/g++.dg/parse/typespec1.C2
-rw-r--r--gcc/testsuite/g++.dg/template/typedef5.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/typename3.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/typename4.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/typename6.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb94.C2
27 files changed, 123 insertions, 52 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b63977b968e..7dc15875cfe 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,21 @@
+2009-11-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/18451
+ PR c++/40738
+ * cp-tree.h (cp_decl_specifier_seq): Add any_type_specifiers_p.
+ * parser.c (cp_parser_single_declaration): Call
+ cp_parser_parse_and_diagnose_invalid_type_name here, too.
+ (cp_parser_parameter_declaration): And here.
+ (cp_parser_parse_and_diagnose_invalid_type_name): Be
+ less picky about declarator form. Don't skip to
+ the end of the block if we're in a declarator.
+ (cp_parser_decl_specifier_seq): Set any_type_specifiers_p.
+ (cp_parser_simple_declaration): Check it.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_diagnose_invalid_type_name): Tweak error message.
+ (cp_parser_expression_statement): Likewise.
+ * decl2.c (grokfield): Mention decltype instead of typeof.
+
2009-11-06 Jason Merrill <jason@redhat.com>
PR c++/15946
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c4b088beb56..68be9345471 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4267,6 +4267,8 @@ typedef struct cp_decl_specifier_seq {
BOOL_BITFIELD conflicting_specifiers_p : 1;
/* True iff at least one decl-specifier was found. */
BOOL_BITFIELD any_specifiers_p : 1;
+ /* True iff at least one type-specifier was found. */
+ BOOL_BITFIELD any_type_specifiers_p : 1;
/* True iff "int" was explicitly provided. */
BOOL_BITFIELD explicit_int_p : 1;
/* True iff "char" was explicitly provided. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 53f66ad73fc..ba987f7888c 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -789,7 +789,7 @@ grokfield (const cp_declarator *declarator,
if (TREE_CODE (value) == TYPE_DECL && init)
{
- error ("typedef %qD is initialized (use __typeof__ instead)", value);
+ error ("typedef %qD is initialized (use decltype instead)", value);
init = NULL_TREE;
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 47f5f13f1d3..7bafb67bc1c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2402,8 +2402,8 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser,
id, parser->scope);
else if (TYPE_P (parser->scope)
&& dependent_scope_p (parser->scope))
- error_at (location, "need %<typename%> before %<%T::%E%> to name "
- "a type in dependent scope %qT",
+ error_at (location, "need %<typename%> before %<%T::%E%> because "
+ "%qT is a dependent scope",
parser->scope, id, parser->scope);
else if (TYPE_P (parser->scope))
error_at (location, "%qE in class %qT does not name a type",
@@ -2437,9 +2437,9 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
/*template_p=*/NULL,
/*declarator_p=*/true,
/*optional_p=*/false);
- /* After the id-expression, there should be a plain identifier,
- otherwise this is not a simple variable declaration. */
- if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ /* If the next token is a (, this is a function with no explicit return
+ type, i.e. constructor, destructor or conversion op. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
|| TREE_CODE (id) == TYPE_DECL)
{
cp_parser_abort_tentative_parse (parser);
@@ -2451,9 +2451,11 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
/* Emit a diagnostic for the invalid type. */
cp_parser_diagnose_invalid_type_name (parser, parser->scope,
id, token->location);
- /* Skip to the end of the declaration; there's no point in
- trying to process it. */
- cp_parser_skip_to_end_of_block_or_statement (parser);
+ /* If we aren't in the middle of a declarator (i.e. in a
+ parameter-declaration-clause), skip to the end of the declaration;
+ there's no point in trying to process it. */
+ if (!parser->in_declarator_p)
+ cp_parser_skip_to_end_of_block_or_statement (parser);
return true;
}
@@ -7773,8 +7775,8 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
&& !cp_parser_uncommitted_to_tentative_parse_p (parser)
&& TREE_CODE (statement) == SCOPE_REF)
- error_at (token->location, "need %<typename%> before %qE to name "
- "a type in dependent scope %qT",
+ error_at (token->location, "need %<typename%> before %qE because "
+ "%qT is a dependent scope",
statement, TREE_OPERAND (statement, 0));
/* Consume the final `;'. */
@@ -8846,7 +8848,7 @@ cp_parser_simple_declaration (cp_parser* parser,
T t;
where "T" should name a type -- but does not. */
- if (!decl_specifiers.type
+ if (!decl_specifiers.any_type_specifiers_p
&& cp_parser_parse_and_diagnose_invalid_type_name (parser))
{
/* If parsing tentatively, we should commit; we really are
@@ -9211,6 +9213,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
{
constructor_possible_p = false;
found_decl_spec = true;
+ if (!is_cv_qualifier)
+ decl_specs->any_type_specifiers_p = true;
}
}
@@ -14973,6 +14977,11 @@ cp_parser_parameter_declaration (cp_parser *parser,
CP_PARSER_FLAGS_NONE,
&decl_specifiers,
&declares_class_or_enum);
+
+ /* Complain about missing 'typename' or other invalid type names. */
+ if (!decl_specifiers.any_type_specifiers_p)
+ cp_parser_parse_and_diagnose_invalid_type_name (parser);
+
/* If an error occurred, there's no reason to attempt to parse the
rest of the declaration. */
if (cp_parser_error_occurred (parser))
@@ -16523,7 +16532,7 @@ cp_parser_member_declaration (cp_parser* parser)
prefix_attributes = decl_specifiers.attributes;
decl_specifiers.attributes = NULL_TREE;
/* Check for an invalid type-name. */
- if (!decl_specifiers.type
+ if (!decl_specifiers.any_type_specifiers_p
&& cp_parser_parse_and_diagnose_invalid_type_name (parser))
return;
/* If there is no declarator, then the decl-specifier-seq should
@@ -18775,6 +18784,11 @@ cp_parser_single_declaration (cp_parser* parser,
cp_parser_perform_template_parameter_access_checks (checks);
}
}
+
+ /* Complain about missing 'typename' or other invalid type names. */
+ if (!decl_specifiers.any_type_specifiers_p)
+ cp_parser_parse_and_diagnose_invalid_type_name (parser);
+
/* If it's not a template class, try for a template function. If
the next token is a `;', then this declaration does not declare
anything. But, if there were errors in the decl-specifiers, then
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index df7e86d043a..d4dc136cbff 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,30 @@
2009-11-07 Jason Merrill <jason@redhat.com>
+ PR c++/18451
+ PR c++/40738
+ * g++.dg/parse/error36.C: Add parameter and template cases.
+ * g++.dg/cpp0x/variadic-ex1.C: Update expected errors.
+ * g++.dg/ext/typedef-init.C: Likewise.
+ * g++.dg/lookup/hidden-class1.C: Likewise.
+ * g++.dg/lookup/hidden-class10.C: Likewise.
+ * g++.dg/lookup/hidden-class5.C: Likewise.
+ * g++.dg/lookup/hidden-class7.C: Likewise.
+ * g++.dg/lookup/hidden-temp-class1.C: Likewise.
+ * g++.dg/lookup/hidden-temp-class4.C: Likewise.
+ * g++.dg/lookup/hidden-temp-class7.C: Likewise.
+ * g++.dg/lookup/strong-using-2.C: Likewise.
+ * g++.dg/other/typedef1.C: Likewise.
+ * g++.dg/parse/access10.C: Likewise.
+ * g++.dg/parse/constructor1.C: Likewise.
+ * g++.dg/parse/crash38.C: Likewise.
+ * g++.dg/parse/error3.C: Likewise.
+ * g++.dg/parse/typespec1.C: Likewise.
+ * g++.dg/template/typedef5.C: Likewise.
+ * g++.old-deja/g++.pt/typename3.C: Likewise.
+ * g++.old-deja/g++.pt/typename4.C: Likewise.
+ * g++.old-deja/g++.pt/typename6.C: Likewise.
+ * g++.old-deja/g++.robertl/eb94.C: Likewise.
+
* g++.dg/abi/regparm1.C: Fix execute test.
2009-11-07 Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C
index d5ebf0def3c..485fffa476c 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex1.C
@@ -1,4 +1,4 @@
// { dg-options "-std=gnu++0x" }
template<typename ... Elements> class Tuple;
Tuple<>* t; // OK: Elements is empty
-Tuple* u; // { dg-error "expected" }
+Tuple* u; // { dg-error "template-name" }
diff --git a/gcc/testsuite/g++.dg/ext/typedef-init.C b/gcc/testsuite/g++.dg/ext/typedef-init.C
index 95a96d55162..153303d217b 100644
--- a/gcc/testsuite/g++.dg/ext/typedef-init.C
+++ b/gcc/testsuite/g++.dg/ext/typedef-init.C
@@ -11,8 +11,7 @@
/* Case A: just the bare name = initializer. */
-typedef A = 0; /* { dg-error "initialized" "A" } */
- /* { dg-warning "no type" "A warns" { target *-*-* } 14 } */
+typedef A = 0; /* { dg-error "does not name a type" "A" } */
A a; /* { dg-error "does not name a type" "A error cascade" } */
/* Case B: with a type also. */
@@ -24,9 +23,8 @@ B b; /* { dg-error "does not name a type" "B error cascade" } */
field declarations go by a different code path in C++ (ick). */
struct S {
- typedef C = 0; /* { dg-error "initialized" "C" } */
- /* { dg-warning "no type" "C warns" { target *-*-* } 27 } */
- C c; /* { dg-bogus "" "C error cascade" } */
+ typedef C = 0; /* { dg-error "does not name a type" "C" } */
+ C c; /* { dg-error "" "C error cascade" } */
typedef int D = 0; /* { dg-error "initialized" "D" } */
D d; /* { dg-bogus "" "D error cascade" } */
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class1.C b/gcc/testsuite/g++.dg/lookup/hidden-class1.C
index fc71e96fb7f..b3be4e8e941 100644
--- a/gcc/testsuite/g++.dg/lookup/hidden-class1.C
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class1.C
@@ -4,5 +4,5 @@
class A {
friend class B;
- B *b; // { dg-error "no type|expected" }
+ B *b; // { dg-error "type|expected" }
};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class10.C b/gcc/testsuite/g++.dg/lookup/hidden-class10.C
index f68196ff8a1..c9b5ca9f663 100644
--- a/gcc/testsuite/g++.dg/lookup/hidden-class10.C
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class10.C
@@ -7,5 +7,5 @@
class A {
friend class abort;
- abort *b; // { dg-error "no type|expected" }
+ abort *b; // { dg-error "type|expected" }
};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class5.C b/gcc/testsuite/g++.dg/lookup/hidden-class5.C
index 1cf06bcc395..c2413546bd7 100644
--- a/gcc/testsuite/g++.dg/lookup/hidden-class5.C
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class5.C
@@ -6,4 +6,4 @@ class A {
friend class B;
};
-B* b; // { dg-error "expected" }
+B* b; // { dg-error "type|expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class7.C b/gcc/testsuite/g++.dg/lookup/hidden-class7.C
index f681cd649f1..a46ae711d20 100644
--- a/gcc/testsuite/g++.dg/lookup/hidden-class7.C
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class7.C
@@ -10,4 +10,4 @@ class C {
friend class B;
};
-B *b; // { dg-error "expected" }
+B *b; // { dg-error "type|expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C
index c92b7f66a1a..8cdb235e8fc 100644
--- a/gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class1.C
@@ -4,5 +4,5 @@
class A {
template <class T> friend class B;
- B<int> *b; // { dg-error "no type|expected" }
+ B<int> *b; // { dg-error "type|expected" }
};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C
index 02dc9c3e50f..3d085e2249a 100644
--- a/gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class4.C
@@ -6,4 +6,4 @@ class A {
template <class T> friend class B;
};
-B<int> *b; // { dg-error "expected" }
+B<int> *b; // { dg-error "type|expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C b/gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C
index 22804d782a0..19dd9524895 100644
--- a/gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C
+++ b/gcc/testsuite/g++.dg/lookup/hidden-temp-class7.C
@@ -10,4 +10,4 @@ class C {
template <class T> friend class B;
};
-B<int> *b; // { dg-error "expected" }
+B<int> *b; // { dg-error "type|expected" }
diff --git a/gcc/testsuite/g++.dg/lookup/strong-using-2.C b/gcc/testsuite/g++.dg/lookup/strong-using-2.C
index 5c4b425fa8a..314aa52388a 100644
--- a/gcc/testsuite/g++.dg/lookup/strong-using-2.C
+++ b/gcc/testsuite/g++.dg/lookup/strong-using-2.C
@@ -20,4 +20,4 @@ namespace baz {
foo::T *t1;
bar::T *t2;
-baz::T *t3; // { dg-error "(ambiguous|expected|extra)" "" }
+baz::T *t3; // { dg-error "(ambiguous|does not name a type)" "" }
diff --git a/gcc/testsuite/g++.dg/other/typedef1.C b/gcc/testsuite/g++.dg/other/typedef1.C
index 55d62bb7cb2..ef1684d7aef 100644
--- a/gcc/testsuite/g++.dg/other/typedef1.C
+++ b/gcc/testsuite/g++.dg/other/typedef1.C
@@ -2,6 +2,6 @@
// { dg-do compile }
void f1(typedef) {} // { dg-error "no type|typedef declaration" }
-void f2(typedef x) {} // { dg-error "no type|typedef declaration" }
-void f3(typedef x[]) {} // { dg-error "no type|typedef declaration" }
+void f2(typedef x) {} // { dg-error "type|typedef declaration" }
+void f3(typedef x[]) {} // { dg-error "type|typedef declaration" }
void f4(typedef int x) {} // { dg-error "typedef declaration" }
diff --git a/gcc/testsuite/g++.dg/parse/access10.C b/gcc/testsuite/g++.dg/parse/access10.C
index ebfeea9f451..62adc1b16f9 100644
--- a/gcc/testsuite/g++.dg/parse/access10.C
+++ b/gcc/testsuite/g++.dg/parse/access10.C
@@ -7,7 +7,5 @@ template<int> struct A
::A~(); // { dg-bogus "using-declaration" }
};
-// Instead of the bogus error we get 3 separate errors.
-// { dg-error "no type" "" { target *-*-* } 7 }
-// { dg-error "::" "" { target *-*-* } 7 }
-// { dg-error "~" "" { target *-*-* } 7 }
+// Instead of the bogus error we get a different error.
+// { dg-error "template-name" "" { target *-*-* } 7 }
diff --git a/gcc/testsuite/g++.dg/parse/constructor1.C b/gcc/testsuite/g++.dg/parse/constructor1.C
index 1796531487c..1bb9ee0a105 100644
--- a/gcc/testsuite/g++.dg/parse/constructor1.C
+++ b/gcc/testsuite/g++.dg/parse/constructor1.C
@@ -1,8 +1,8 @@
// { dg-do compile }
// { dg-options "-fshow-column" }
-ACE_Process_Descriptor::ACE_Process_Descriptor () : // { dg-error "declared" "declared" }
- // { dg-error "no type" "no type" { target *-*-* } 4 }
- process_ (0) // { dg-error "3: only constructors take base initializers" }
+ACE_Process_Descriptor::ACE_Process_Descriptor () :
+ // { dg-error "does not name a type" "no type" { target *-*-* } 4 }
+ process_ (0)
{
}
diff --git a/gcc/testsuite/g++.dg/parse/crash38.C b/gcc/testsuite/g++.dg/parse/crash38.C
index c050b93cc42..724f9b80a12 100644
--- a/gcc/testsuite/g++.dg/parse/crash38.C
+++ b/gcc/testsuite/g++.dg/parse/crash38.C
@@ -3,7 +3,7 @@
/* This would not ICE. */
namespace M { } /* { dg-error "previous declaration" } */
struct M; /* { dg-error "redeclared as different kind of symbol" } */
-M *p; /* { dg-error "expected constructor" } */
+M *p; /* { dg-error "does not name a type" } */
/* This would ICE when processing 'p'. */
namespace N { } /* { dg-error "previous declaration" } */
diff --git a/gcc/testsuite/g++.dg/parse/error3.C b/gcc/testsuite/g++.dg/parse/error3.C
index 55ae024d412..7e8cf8de000 100644
--- a/gcc/testsuite/g++.dg/parse/error3.C
+++ b/gcc/testsuite/g++.dg/parse/error3.C
@@ -5,5 +5,5 @@ static void InstantiateConstraint(const float&, unsigned,
void(*AddFunction)(const TYPE&,bool&,
char*, char*,
unsigned*));
-// { dg-error "64:expected ',' or '...' before '&' token" "" { target *-*-* } { 5 } }
-// { dg-error "60:ISO C\\+\\+ forbids declaration of 'TYPE' with no type" "" { target *-*-* } { 5 } }
+// { dg-error "64: ISO C\\+\\+ forbids declaration of 'parameter' with no type" "" { target *-*-* } { 5 } }
+// { dg-error "60: 'TYPE' does not name a type" "" { target *-*-* } { 5 } }
diff --git a/gcc/testsuite/g++.dg/parse/error36.C b/gcc/testsuite/g++.dg/parse/error36.C
index 92101e9c99f..0d7f8cfc4c3 100644
--- a/gcc/testsuite/g++.dg/parse/error36.C
+++ b/gcc/testsuite/g++.dg/parse/error36.C
@@ -1,17 +1,33 @@
+// PR c++/15946
// Test for helpful error message about missing typename.
-template <class T> struct A { typedef T foo; typedef T bar; };
+template <class T> struct A
+{
+ struct B { };
+ static B b;
+};
+
template <class T>
void f(T t)
{
typedef A<T>::foo type; // { dg-error "typename" }
A<T>::bar b; // { dg-error "typename" }
-} // { dg-error "expected ';'" "" { target *-*-* } 8 }
+} // { dg-error "expected ';'" "" { target *-*-* } 14 }
+// PR c++/36353
template <class T> struct B
{
void f()
{
A<T>::baz z; // { dg-error "typename" }
- } // { dg-error "expected ';'" "" { target *-*-* } 15 }
+ } // { dg-error "expected ';'" "" { target *-*-* } 22 }
};
+
+// PR c++/40738
+template <class T>
+void g(const A<T>::type &t); // { dg-error "typename" }
+// { dg-error "no type" "" { target *-*-* } 28 }
+
+// PR c++/18451
+template <class T> A<T>::B A<T>::b; // { dg-error "typename" }
+// { dg-error "expected" "" { target *-*-* } 32 }
diff --git a/gcc/testsuite/g++.dg/parse/typespec1.C b/gcc/testsuite/g++.dg/parse/typespec1.C
index a371f8b9836..44ee116f636 100644
--- a/gcc/testsuite/g++.dg/parse/typespec1.C
+++ b/gcc/testsuite/g++.dg/parse/typespec1.C
@@ -1,4 +1,4 @@
// PR c++/26571
struct A {};
-unsigned A a; // { dg-error "multiple" }
+unsigned A a; // { dg-error "expected initializer" }
diff --git a/gcc/testsuite/g++.dg/template/typedef5.C b/gcc/testsuite/g++.dg/template/typedef5.C
index abd9ebb57cf..04b8eac3bcc 100644
--- a/gcc/testsuite/g++.dg/template/typedef5.C
+++ b/gcc/testsuite/g++.dg/template/typedef5.C
@@ -2,6 +2,6 @@
// { dg-do compile }
template<typedef,int> struct A1; // { dg-error "no type|typedef declaration|default argument" }
-template<typedef x,int> struct A2; // { dg-error "no type|typedef declaration|default argument" }
-template<typedef x[],int> struct A3; // { dg-error "no type|typedef declaration|default argument" }
+template<typedef x,int> struct A2; // { dg-error "type|typedef declaration|default argument" }
+template<typedef x[],int> struct A3; // { dg-error "no type|typedef declaration|expected" }
template<typedef int x, int> struct A4; // { dg-error "typedef declaration|default argument" }
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename3.C b/gcc/testsuite/g++.old-deja/g++.pt/typename3.C
index 9b412756b42..0708f1f2495 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/typename3.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/typename3.C
@@ -17,5 +17,5 @@ struct B : public A<U>
template <class U>
-B<U>::A_Type B<U>::Func() { // { dg-error "expected" } implicit typename
-}
+B<U>::A_Type B<U>::Func() { // { dg-error "typename" } implicit typename
+} // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename4.C b/gcc/testsuite/g++.old-deja/g++.pt/typename4.C
index 286795cb643..7238470e4ce 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/typename4.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/typename4.C
@@ -22,5 +22,5 @@ struct C : public B<U>
template <class U>
-C<U>::A_Type C<U>::Func() { // { dg-error "expected" } implicit typename
-}
+C<U>::A_Type C<U>::Func() { // { dg-error "typename" } implicit typename
+} // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/typename6.C b/gcc/testsuite/g++.old-deja/g++.pt/typename6.C
index 27944795ae2..0a5f0184bd4 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/typename6.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/typename6.C
@@ -15,6 +15,6 @@ struct B : public A<U>
};
template <class U>
-A<U>::A_Type B<U>::Func() // { dg-error "expected" } function
+A<U>::A_Type B<U>::Func() // { dg-error "typename" } function
{
-}
+} // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb94.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb94.C
index b3d2da1cbeb..535023606a7 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb94.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb94.C
@@ -10,7 +10,7 @@ static int variable;
class myClass : public baseClass
{
private:
-static int variable; // this is intentionally duplicated
+static int variable; // { dg-error "private" }
};
myClass::variable = 0; //{ dg-error "" } no type