Bug 16002

Summary: [3.4 regression] Strange error message with new parser
Product: gcc Reporter: Richard Biener <rguenth>
Component: c++Assignee: Mark Mitchell <mark>
Status: RESOLVED FIXED    
Severity: minor CC: gcc-bugs
Priority: P2 Keywords: diagnostic
Version: 3.4.0   
Target Milestone: 3.4.5   
Host: Target:
Build: Known to work: 4.0.0
Known to fail: 3.4.0 Last reconfirmed: 2005-05-14 21:03:01

Description Richard Biener 2004-06-15 15:31:15 UTC
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;
  	         ^
Comment 1 Wolfgang Bangerth 2004-06-15 15:56:00 UTC
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. 
Comment 2 Giovanni Bajo 2004-06-16 10:16:16 UTC
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.
Comment 3 Wolfgang Bangerth 2004-06-16 13:53:13 UTC
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. 
Comment 4 Mark Mitchell 2004-07-17 07:39:01 UTC
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.
Comment 5 Mark Mitchell 2004-08-29 18:51:56 UTC
Postponed until GCC 3.4.3.
Comment 6 Mark Mitchell 2004-09-17 02:39:21 UTC
Working on a fix.
Comment 7 GCC Commits 2004-09-17 07:01:17 UTC
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

Comment 8 Mark Mitchell 2004-09-17 07:10:41 UTC
Fixed in 4.0, but will not be marked as fixed until backported to 3.4.
Comment 9 Ulrich Weigand 2004-10-05 16:30:21 UTC
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?
Comment 10 Mark Mitchell 2004-10-16 00:08:12 UTC
It was an accident that error18.C was committed on the branch.  I've now removed it.
Comment 11 Mark Mitchell 2004-11-01 00:45:16 UTC
Postponed until GCC 3.4.4.
Comment 12 GCC Commits 2005-07-28 10:23:16 UTC
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

Comment 13 Giovanni Bajo 2005-07-28 10:24:14 UTC
Fixed also for GCC 3.4.5.