Bug 34269 - [4.3 regression] Incomplete __decltype/__typeof expressions accepted
Summary: [4.3 regression] Incomplete __decltype/__typeof expressions accepted
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.3.0
: P2 normal
Target Milestone: 4.4.0
Assignee: Jakub Jelinek
URL:
Keywords: accepts-invalid, monitored
Depends on:
Blocks:
 
Reported: 2007-11-28 21:06 UTC by Volker Reichelt
Modified: 2009-06-04 11:34 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.3.3 4.4.0
Known to fail: 3.4.0 4.0.4 4.1.0 4.2.0 4.3.0
Last reconfirmed: 2008-11-12 19:22:27


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Volker Reichelt 2007-11-28 21:06:01 UTC
The following invalid code snippets are wrongly accepted on mainline:

=============================
void foo() { __decltype; }
=============================

=============================
void foo() { __decltype(; }
=============================
Comment 1 Jakub Jelinek 2007-11-28 22:27:53 UTC
And the same with __typeof__ instead of __decltype.  Since 3.4.
Why is this considered an regression?
Comment 2 Andrew Pinski 2007-12-08 20:47:13 UTC
(In reply to comment #1)
> And the same with __typeof__ instead of __decltype.  Since 3.4.
> Why is this considered an regression?

Well 3.3 rejected the incomplete __typeof__ so this is a regression for that.

Confirmed.
Comment 3 Joseph S. Myers 2008-07-04 22:21:01 UTC
Closing 4.1 branch.
Comment 4 Jakub Jelinek 2008-11-11 15:42:04 UTC
The joys (well, lack thereof) of tentative parsing.  No errors are reported
because cp_parser_decl_specifier_seq (and its caller cp_parser_simple_declaration) is called during tentative parsing.  cp_parser_decl_specifier_seq returns error_mark_node type, but any_specifiers_p is set, so cp_parser_simple_declaration calls:
8172  /* If we have seen at least one decl-specifier, and the next token
8173     is not a parenthesis, then we must be looking at a declaration.
8174     (After "int (" we might be looking at a functional cast.)  */
8175  if (decl_specifiers.any_specifiers_p
8176      && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)
8177      && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
8178    cp_parser_commit_to_tentative_parse (parser);
Type being error_mark_node generally means that routines assume that error
has been reported already, so nothing is diagnosed afterwards.

Mark, how should this be fixed up?  If cp_parser_decltype (and cp_parser_simple_type_specifier) knew one of the callers is going to call cp_parser_commit_to_tentative_parse, it could cp_parser_commit_to_tentative_parse
first and let all the errors be reported right away.  But I doubt it can.
Another possibility would be add support for queing error messages during tentative parsing and at cp_parser_commit_to_tentative_parse emit them.
Comment 5 Jason Merrill 2008-11-11 17:45:36 UTC
Subject: Re:  [4.2/4.3/4.4 regression] Incomplete __decltype/__typeof
 expressions accepted

jakub at gcc dot gnu dot org wrote:
> Another possibility would be add support for queing error messages during
> tentative parsing and at cp_parser_commit_to_tentative_parse emit them.

This seems right to me.  It's even what the comment at the top of the 
file says we do:

      Then, while we attempt to parse the construct, the parser queues 
up
      error messages, rather than issuing them immediately, and saves 
the
      tokens it consumes.  If the construct is parsed successfully, the 

      parser "commits", i.e., it issues any queued error messages and 

      the tokens that were being preserved are permanently discarded.

The simulate_error business only works for parse errors that indicate 
that this line of parsing won't work; it doesn't work for code that 
parses fine, but violates semantic rules and therefore needs an error.

Jason
Comment 6 Mark Mitchell 2008-11-11 20:09:35 UTC
Subject: Re:  [4.2/4.3/4.4 regression] Incomplete __decltype/__typeof
 expressions accepted

jason at redhat dot com wrote:

> This seems right to me.  It's even what the comment at the top of the 
> file says we do:
> 
>       Then, while we attempt to parse the construct, the parser queues 
> up
>       error messages, rather than issuing them immediately, and saves 
> the
>       tokens it consumes.  If the construct is parsed successfully, the 
> 
>       parser "commits", i.e., it issues any queued error messages and 
> 
>       the tokens that were being preserved are permanently discarded.
> 
> The simulate_error business only works for parse errors that indicate 
> that this line of parsing won't work; it doesn't work for code that 
> parses fine, but violates semantic rules and therefore needs an error.

I forgot that comment was still there.  I think it's a lie, reflecting
an earlier implementation state.  I found queuing up the messages to be
really difficult.

For a syntactically broken construct, we can just issue the error and
commit to the tentative parse at that point.  I believe we do that in
some other places.  It doesn't matter what top-level construct
(declaration or expression-statement) we might be looking at; something
like "__decltype( ;" is always invalid.  Once you see "decltype (" , if
the parsing of the operand to decltype fails, we can commit to the
current tentative parse, issue the error, and move on.

However, I think the core bug here may be that the code you mention in
cp_parser_simple_declaration doesn't check to see if the parse has
already failed.  Committing to the tentative parse is reasonable in that
situation if the parsing has succeeded thus far -- but if we've actually
hit a *parse* error, rather than a *semantic* error, we could safely
give up.

That will result in trying to parse the decltype again (now as an
expression statement), and we'll get an error that time.

Comment 7 Jakub Jelinek 2008-11-12 17:35:14 UTC
Subject: Bug 34269

Author: jakub
Date: Wed Nov 12 17:33:48 2008
New Revision: 141793

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141793
Log:
	PR c++/34269
	* parser.c (cp_parser_simple_declaration): Don't commit
	to tentative parse if parse errors were seen.

	* g++.dg/cpp0x/decltype13.C: New test.
	* g++.dg/cpp0x/decltype-33837.C: Adjust dg-error pattern.
	* g++.dg/cpp0x/pr33839.C: Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/decltype13.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/parser.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/cpp0x/decltype-33837.C
    trunk/gcc/testsuite/g++.dg/cpp0x/pr33839.C

Comment 8 Joseph S. Myers 2009-03-31 20:14:24 UTC
Closing 4.2 branch.
Comment 9 Richard Biener 2009-06-04 11:34:16 UTC
Not worth fixing on the 4.3 branch.  Fixed for 4.4.0.