Bug 16663 - Poor parse error recovery with mispelled type in function declaration
Summary: Poor parse error recovery with mispelled type in function declaration
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.0
: P2 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic, error-recovery
: 41054 (view as bug list)
Depends on: 102774 102775
Blocks:
  Show dependency treegraph
 
Reported: 2004-07-21 23:07 UTC by Ivan Godard
Modified: 2021-10-15 12:14 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-08-04 19:21:19


Attachments
testcase (87 bytes, text/plain)
2008-08-04 19:22 UTC, Manuel López-Ibáñez
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ivan Godard 2004-07-21 23:07:08 UTC
void Foo(misspelled a, char b, bool c, float f);

gets you

foo.cc:1: error: variable or field `Foo' declared void
foo.cc:1: error: `misspelled' was not declared in this scope
foo.cc:1: error: expected primary-expression before "char"
foo.cc:1: error: expected primary-expression before "bool"
foo.cc:1: error: expected primary-expression before "float"
foo.cc:1: error: initializer expression list treated as compound expression
Comment 1 Wolfgang Bangerth 2004-07-22 00:18:33 UTC
That's a duplicate of another bug, maybe even one of mine. I gotta run now, though, 
so maybe someone else wants to dig for it. 
W. 
Comment 2 Andrew Pinski 2004-07-22 00:31:09 UTC
It is related to bug 16151.
Comment 3 Andrew Pinski 2004-07-22 00:36:41 UTC
Confirmed.

Another related bug is PR 15786.
Comment 4 Manuel López-Ibáñez 2008-08-04 19:21:19 UTC
In GCC 4.4 we have:

pr16663.C:2: error: variable or field ‘Foo’ declared void
pr16663.C:2: error: ‘misspelled’ was not declared in this scope
pr16663.C:2: error: expected primary-expression before ‘char’
pr16663.C:2: error: expected primary-expression before ‘bool’
pr16663.C:2: error: expected primary-expression before ‘float’

This is not easy to fix since that statement can be a function declaration but also a variable declaration and initialization. We try to parse tentatively the first case, fail, then we parse the second case and see that 'void' is not allowed and that 'misspelled' is not declared.

If we have 

int Bar(misspelled a, char b, bool c, float f);

then we get the full list of error messages:

pr16663.C:4: error: ‘misspelled’ was not declared in this scope
pr16663.C:4: error: expected primary-expression before ‘char’
pr16663.C:4: error: expected primary-expression before ‘bool’
pr16663.C:4: error: expected primary-expression before ‘float’
pr16663.C:4: error: initializer expression list treated as compound expression

Comment 5 Manuel López-Ibáñez 2008-08-04 19:22:26 UTC
Created attachment 16015 [details]
testcase

Testcase
Comment 6 Manuel López-Ibáñez 2009-08-25 13:53:33 UTC
*** Bug 41054 has been marked as a duplicate of this bug. ***
Comment 7 Rui Maciel 2011-09-11 19:29:02 UTC
(In reply to comment #4)
> In GCC 4.4 we have:
> 
> pr16663.C:2: error: variable or field ‘Foo’ declared void
> pr16663.C:2: error: ‘misspelled’ was not declared in this scope
> pr16663.C:2: error: expected primary-expression before ‘char’
> pr16663.C:2: error: expected primary-expression before ‘bool’
> pr16663.C:2: error: expected primary-expression before ‘float’
> 
> This is not easy to fix since that statement can be a function declaration but
> also a variable declaration and initialization. We try to parse tentatively the
> first case, fail, then we parse the second case and see that 'void' is not
> allowed and that 'misspelled' is not declared.

If 'void' is not allowed and 'misspelled' is not declared, then wouldn't it be better to recognize that case as an undeclared 'misspelled' instead of an impossible (or, at least, highly improbable) declaration of a variable of type void?  As things stand, GCC outputs a cryptic error message that is based on the expectation that a variable being declared with type void is both correct and the expected behaviour, and this isn't helpful.
Comment 8 Manuel López-Ibáñez 2011-09-11 20:28:50 UTC
(In reply to comment #7)
> 
> If 'void' is not allowed and 'misspelled' is not declared, then wouldn't it be
> better to recognize that case as an undeclared 'misspelled' instead of an
> impossible (or, at least, highly improbable) declaration of a variable of type

It could be possible to parse everything tentatively, and once everything failed, try to guess why. But this is not a 10 minutes, one-liner fix, that is what I mean by "not trivial".

> void?  As things stand, GCC outputs a cryptic error message that is based on
> the expectation that a variable being declared with type void is both correct
> and the expected behaviour, and this isn't helpful.

We know it is not helpful, that is why this is marked as NEW and g++ devs would be happy if someone submitted a patch fixing it. But so far, nobody has been bothered by this issue enough to submit such patch.

BTW, clang avoids the errors-cascade but also gives the wrong "void" error:

/tmp/webcompile/_26781_1.cc:1:6: error: variable has incomplete type 'void'
void Foo(misspelled a, char b, bool c, float f);
     ^
/tmp/webcompile/_26781_1.cc:1:10: error: use of undeclared identifier 'misspelled'
void Foo(misspelled a, char b, bool c, float f);
         ^
Comment 9 Jonathan Wakely 2021-10-15 11:55:46 UTC
We no longer print the final "initializer expression list treated as compound expression" error.

If we make the example a little more realistic so the thing being mispelled is actually in scope, then GCC does better these days:

struct mispelled { };

void Foo(misspelled a, char b, bool c, float f);

For this we get:


foo.C:2:6: error: variable or field 'Foo' declared void
    2 | void Foo(misspelled a, char b, bool c, float f);
      |      ^~~
foo.C:2:10: error: 'misspelled' was not declared in this scope; did you mean 'mispelled'?
    2 | void Foo(misspelled a, char b, bool c, float f);
      |          ^~~~~~~~~~
      |          mispelled
foo.C:2:24: error: expected primary-expression before 'char'
    2 | void Foo(misspelled a, char b, bool c, float f);
      |                        ^~~~
foo.C:2:32: error: expected primary-expression before 'bool'
    2 | void Foo(misspelled a, char b, bool c, float f);
      |                                ^~~~
foo.C:2:40: error: expected primary-expression before 'float'
    2 | void Foo(misspelled a, char b, bool c, float f);
      |                                        ^~~~~


The subsequent errors are still unhelpful, but the "did you mean" is correct, and helpful.