void foo(void) { double Q *= 5.0; } causes gcc 3.4 to print (same for mainline) te.cpp: In function `void foo()': te.cpp:3: error: expected primary-expression before "double" te.cpp:3: error: expected `;' before "double" while 3.3.4 printed the clearly superior te.cpp: In function `void foo()': te.cpp:3: error: parse error before `*=' token EDG is even better te.cpp(3): error: expected a ";" double Q *= 5.0; ^
Hm, yes. In fact, the second line is not helpful at all, since if I insert a semicolon _before_ the 'double', I of course get the same error as before ;-) This problem here seems so obvious that I would rate it as low priority, though. As a general remark: I believe that many of these dreaded "expected primary-expression before XXX" messages are so unhelpful because they wrongly state the context XXX. In this case, we are actually quite happy with what we see until we get to the *= operator. We certainly don't expect anything else before "double", everything is fine up to that point. I have no clue where this comes from, but it seems we should instead print the token where things start go wrong, not the first token of the expression. I think that this probably holds for a good number of the cases where we print this error message. W.
Not so easy, though. The parser tries several different constructs that can happen at statement level (function declaration, variable declaration, etc.). They are all equally possible, and they all fail at different tokens. So the error "expected primary expression before XXX", it actually means "starting from XXX, I could not find a valid primary expression". In this case, I think we should consider the variable declaration to be OK even without ';' so that we emit a missing semicolon error, and then skip all the token till the end of the line.
In this case, yes. In general: if we can't find a valid sequence of tokens starting somewhere, why don't we say "starting at XXX", rather than "before XXX"? W.
The right thing to do here is to notice that after "double" -- not followed by a parenthesis -- there are no non-declaration alternatives. Then, we should commit to the tentative parse, and that would get us a better error message. In other words, the improvement is to avoid backtracking in this case.
Postponed until GCC 3.4.3.
Working on a fix.
Subject: Bug 16002 CVSROOT: /cvs/gcc Module name: gcc Changes by: mmitchel@gcc.gnu.org 2004-09-17 07:01:11 Modified files: gcc/testsuite : ChangeLog gcc/cp : ChangeLog lex.c parser.c Added files: gcc/testsuite/g++.dg/parse: error18.C gcc/testsuite/g++.dg/warn: Wunused-8.C Log message: PR c++/16002 * parser.c (cp_parser_simple_declaration): Commit to tentative parses after seeing a decl-specifier. (cp_parser_simple_declaration): Eliminate spurious message. (cp_parser_init_declarator): Adjust error message. PR c++/16029 * lex.c (unqualified_name_lookup_error): Mark the dummy declaration as used. PR c++/16002 * g++.dg/template/error18.C: New test. PR c++/16029 * g++.dg/warn/Wunused-8.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4303&r2=1.4304 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4360&r2=1.4361 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/lex.c.diff?cvsroot=gcc&r1=1.344&r2=1.345 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/parser.c.diff?cvsroot=gcc&r1=1.248&r2=1.249 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/error18.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/warn/Wunused-8.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
Fixed in 4.0, but will not be marked as fixed until backported to 3.4.
It appears the test case for this bug (error18.C), but *not* the fix, was committed to the 3.4 branch, causing a test suite regression there. Was this intentional?
It was an accident that error18.C was committed on the branch. I've now removed it.
Postponed until GCC 3.4.4.
Subject: Bug 16002 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: giovannibajo@gcc.gnu.org 2005-07-28 10:22:23 Modified files: gcc/testsuite : ChangeLog gcc/cp : ChangeLog call.c parser.c pt.c gcc/testsuite/g++.dg/parse: crash11.C crash13.C Added files: gcc/testsuite/g++.dg/ext: packed8.C gcc/testsuite/g++.dg/parse: error18.C gcc/testsuite/g++.dg/template: crash25.C local5.C typedef2.C Log message: Backport: 2004-09-16 Mark Mitchell <mark@codesourcery.com> PR c++/16002 * parser.c (cp_parser_simple_declaration): Commit to tentative parses after seeing a decl-specifier. (cp_parser_simple_declaration): Eliminate spurious message. (cp_parser_init_declarator): Adjust error message. 2005-06-17 Geoffrey Keating <geoffk@apple.com> PR c++/17413 * pt.c (type_unification_real): Apply template type deduction even to procedure parameters that are not dependent on a template parameter. 2004-11-02 Mark Mitchell <mark@codesourcery.com> PR c++/18124 * parser.c (cp_parser_type_parameter): Robustify. PR c++/18155 * parser.c (cp_parser_single_declaration): Disallow template typedefs. (cp_parser_typedef_p): New function. 2004-12-21 Mark Mitchell <mark@codesourcery.com> PR c++/18378 * call.c (convert_like_real): Do not permit the use of a copy constructor to copy a packed field. Backport: 2004-09-16 Mark Mitchell <mark@codesourcery.com> PR c++/16002 * g++.dg/parse/error18.C: New test. * g++.dg/parse/crash11.C: Adjust error markers. 2005-06-17 Geoffrey Keating <geoffk@apple.com> PR c++/17413 * g++.dg/template/local5.C: New. 2004-11-02 Mark Mitchell <mark@codesourcery.com> PR c++/18124 * g++.dg/template/crash25.C: New test. PR c++/18155 * g++.dg/template/typedef2.C: New test. * g++.dg/parse/crash13.C: Adjust error markers. 2004-12-21 Mark Mitchell <mark@codesourcery.com> PR c++/18378 * g++.dg/ext/packed8.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.411&r2=1.3389.2.412 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3892.2.228&r2=1.3892.2.229 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/call.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.452.2.26&r2=1.452.2.27 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/parser.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.157.2.57&r2=1.157.2.58 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.816.2.56&r2=1.816.2.57 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed8.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.42.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/error18.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.1.12.3&r2=1.1.12.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/crash11.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.2&r2=1.2.24.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/crash13.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.1&r2=1.1.14.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/crash25.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.38.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/local5.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.14.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/typedef2.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.38.1
Fixed also for GCC 3.4.5.