Hi,
this is another bug essentially already fixed. However, in the audit
trail Giovanni Bajo noticed that for the local declarations case we also
emit those annoying:
16128.C:16:7: error: expected ‘;’ before ‘a’
and likewise for 'b'. By checking the return value of
cp_parser_expression at the beginning of cp_parser_expression_statement
we can avoid those and many more in existing testcases (see patch).
Tested x86_64-linux.
Thanks,
Paolo.
////////////////////////
/cp
2013-06-18 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/16128
* parser.c (cp_parser_expression_statement): Check whether
cp_parser_expression returns error_mark_node.
/testsuite
2013-06-18 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/16128
* g++.dg/template/error52.C: New.
* g++.dg/lookup/friend15.C: Update.
* g++.dg/parse/error11.C: Likewise.
* g++.dg/parse/error14.C: Likewise.
* g++.dg/parse/parser-pr28152-2.C: Likewise.
* g++.dg/parse/template25.C: Likewise.
* g++.old-deja/g++.jason/cond.C: Likewise.
* g++.old-deja/g++.mike/for2.C: Likewise.
* g++.old-deja/g++.robertl/eb125.C: Likewise.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 200134)
+++ cp/parser.c (working copy)
@@ -9264,7 +9264,15 @@ cp_parser_expression_statement (cp_parser* parser,
/* If the next token is a ';', then there is no expression
statement. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
- statement = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ {
+ statement = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ if (statement == error_mark_node
+ && !cp_parser_uncommitted_to_tentative_parse_p (parser))
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+ }
/* Give a helpful message for "A<T>::type t;" and the like. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
Index: testsuite/g++.dg/lookup/friend15.C
===================================================================
--- testsuite/g++.dg/lookup/friend15.C (revision 200141)
+++ testsuite/g++.dg/lookup/friend15.C (working copy)
@@ -8,5 +8,4 @@ void foo()
friend class B;
};
B::B() {} // { dg-error "has not been declared" }
-// { dg-error "expected" "expected" { target *-*-* } 10 }
}
Index: testsuite/g++.dg/parse/error11.C
===================================================================
--- testsuite/g++.dg/parse/error11.C (revision 200131)
+++ testsuite/g++.dg/parse/error11.C (working copy)
@@ -53,18 +53,16 @@ void func(void)
// { dg-error "6:missing template arguments before" "template" { target *-*-*
} { 51 } }
// { dg-error "9:expected primary-expression before ':' token" "primary" {
target *-*-* } 51 }
// { dg-error "9:expected '\]' before ':' token" "backslash" { target *-*-* }
51 }
-// { dg-error "9:expected ';' before ':' token" "semicolon" { target *-*-* }
51 }
// { dg-error "6:missing template arguments before" "template" { target *-*-*
} 52 }
// { dg-error "7:expected primary-expression before ':' token" "primary" {
target *-*-* } 52 }
// { dg-error "7:expected '\]' before ':' token" "backslash" { target *-*-* }
52 }
-// { dg-error "7:expected ';' before ':' token" "semicolon" { target *-*-* }
52 }
//
int Foo[2];
Foo[::value] = 0;
}
template struct Foo<::B>; // { dg-error "20:'<::' cannot begin" "begin" {
target c++98 } }
-// { dg-message "20:is an alternate" "alt" { target c++98 } 66 }
+// { dg-message "20:is an alternate" "alt" { target c++98 } 64 }
// On the first error message, an additional note about the use of
// -fpermissive should be present
Index: testsuite/g++.dg/parse/error14.C
===================================================================
--- testsuite/g++.dg/parse/error14.C (revision 200131)
+++ testsuite/g++.dg/parse/error14.C (working copy)
@@ -22,5 +22,3 @@ struct X
}; // { dg-error "2:expected '.' at end of input" "at end of input" }
// { dg-error "1:expected primary-expression before '.' token" "primary" {
target *-*-* } 22 }
// { dg-error "1:expected unqualified-id" "unqualified-id" { target *-*-* }
22 }
- // { dg-error "1:expected ';' before '.' token" "function" { target *-*-* }
22 }
-
Index: testsuite/g++.dg/parse/parser-pr28152-2.C
===================================================================
--- testsuite/g++.dg/parse/parser-pr28152-2.C (revision 200131)
+++ testsuite/g++.dg/parse/parser-pr28152-2.C (working copy)
@@ -7,7 +7,5 @@ main (void)
__complex__ float z;
z = __complex__ (1.90000007326203904e+19, 0.0); // { dg-error "expected
primary-expression before '__complex__'" "primary-expression" }
- // { dg-error "expected .;. before .__complex__." "semicolon" { target *-*-*
} 9 }
z = __complex__ (1.0e+0, 0.0) / z; // { dg-error "expected
primary-expression before '__complex__'" "primaty-expression" }
- // { dg-error "expected .;. before '__complex__'" "semicolon" { target *-*-*
} 11 }
- // { dg-error "at end of input" "end" { target *-*-* } 11 }
+ // { dg-error "at end of input" "end" { target *-*-* } 10 }
Index: testsuite/g++.dg/parse/parser-pr28152.C
===================================================================
--- testsuite/g++.dg/parse/parser-pr28152.C (revision 200131)
+++ testsuite/g++.dg/parse/parser-pr28152.C (working copy)
@@ -7,7 +7,5 @@ main (void)
_Complex float z;
z = _Complex (1.90000007326203904e+19, 0.0); // { dg-error "expected
primary-expression before '_Complex'" "primary-expression" }
- // { dg-error "expected .;. before ._Complex." "semicolon" { target *-*-* }
9 }
z = _Complex (1.0e+0, 0.0) / z; // { dg-error "expected
primary-expression before '_Complex'" "primary-expression" }
- // { dg-error "expected .;. before '_Complex'" "semicolon" { target *-*-* }
11 }
- // { dg-error "at end of input" "end" { target *-*-* } 11 }
+ // { dg-error "at end of input" "end" { target *-*-* } 10 }
Index: testsuite/g++.dg/parse/template25.C
===================================================================
--- testsuite/g++.dg/parse/template25.C (revision 200131)
+++ testsuite/g++.dg/parse/template25.C (working copy)
@@ -10,5 +10,4 @@ void f(void)
void g(void)
{
template f<int>(); /* { dg-error "expected primary-expression"
"primary-expression" } */
- /* { dg-error "expected ';'" "semicolon" { target *-*-* } 12 } */
}
Index: testsuite/g++.dg/template/error52.C
===================================================================
--- testsuite/g++.dg/template/error52.C (revision 0)
+++ testsuite/g++.dg/template/error52.C (working copy)
@@ -0,0 +1,19 @@
+// PR c++/16128
+
+template<typename T>
+struct A {
+ };
+
+namespace H {
+ template<typename T>
+ struct B {};
+ }
+
+A a; // { dg-error "template" }
+H::B b; // { dg-error "template" }
+
+int main() {
+ A a; // { dg-error "template" }
+ H::B b; // { dg-error "template" }
+ return 0;
+ }
Index: testsuite/g++.old-deja/g++.jason/cond.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/cond.C (revision 200131)
+++ testsuite/g++.old-deja/g++.jason/cond.C (working copy)
@@ -37,10 +37,9 @@ int main()
;
A bar; // { dg-error "not declared" "decl" }
- // { dg-error "expected" "exp" { target *-*-* } 39 }
if (enum A { one, two, three } foo = one) // { dg-error "defined" "def" }
- // { dg-error "not declared" "expected" { target *-*-* } 42 }
+ // { dg-error "not declared" "expected" { target *-*-* } 41 }
;
struct B { operator int () { return 2; } };
@@ -49,7 +48,7 @@ int main()
;
if (int f () = 1) // { dg-warning "extern" "extern" }
- // { dg-error "is initialized like a variable" "var" { target *-*-* } 51 }
+ // { dg-error "is initialized like a variable" "var" { target *-*-* } 50 }
;
if (int a[2] = {1, 2}) // { dg-error "extended init" "" { target c++98
} }
Index: testsuite/g++.old-deja/g++.mike/for2.C
===================================================================
--- testsuite/g++.old-deja/g++.mike/for2.C (revision 200131)
+++ testsuite/g++.old-deja/g++.mike/for2.C (working copy)
@@ -4,19 +4,17 @@ void foo() {
for (class C {};;)
;
C c; // { dg-error "declared" "decl" }
- // { dg-error "expected" "exp" { target *-*-* } 6 }
}
void bar() {
for (enum E {num};;)
;
E e; // { dg-error "declared" "decl" }
- // { dg-error "expected" "exp" { target *-*-* } 13 }
}
void bee () {
int i = 0;
for (int fun() = 0; i != 2; ++i) { // { dg-warning "extern" "extern" }
- // { dg-error "initialized" "init" { target *-*-* } 19 }
+ // { dg-error "initialized" "init" { target *-*-* } 17 }
}
}
Index: testsuite/g++.old-deja/g++.robertl/eb125.C
===================================================================
--- testsuite/g++.old-deja/g++.robertl/eb125.C (revision 200131)
+++ testsuite/g++.old-deja/g++.robertl/eb125.C (working copy)
@@ -16,7 +16,7 @@ class test_square
template <class BOX> void test(BOX *the_box)
{x // { dg-error "not declared in this scope" }
- the_box->print(); // { dg-error "before" }
+ the_box->print();
}
template void test<> (test_box *);