Bug 50169 (C++DR2141) - [DR 2141] "new struct X {{}};" incorrectly treated as an invalid struct-definition
Summary: [DR 2141] "new struct X {{}};" incorrectly treated as an invalid struct-defin...
Status: NEW
Alias: C++DR2141
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: c++-core-issues
  Show dependency treegraph
 
Reported: 2011-08-23 20:37 UTC by Johannes Schaub
Modified: 2021-12-14 04:57 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-08-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Johannes Schaub 2011-08-23 20:37:38 UTC
The following looks like valid code:

 struct A { int a; }; 
 int main() { 
   new struct A {{ }}; 
 }

The type-specifier-seq "struct A" is followed by a braced-init-list "{{}}". But GCC says:

main1.cpp: In function 'int main()':
main1.cpp:3:16: error: types may not be defined in a new-type-id
main1.cpp:3:17: error: expected unqualified-id before '{' token

As far as I can see, I would only define a new type if I would say:

    new struct A { };

But the two-braces disambiguates it.
Comment 1 Ville Voutilainen 2011-08-23 21:22:39 UTC
Trying

struct A { int a; }; 
 int main() { 
   new (struct A) {{ }}; 
 }

gives

internal compiler error: in cxx_eval_bare_aggregate, at cp/semantics.c:6601

This works fine:

struct A { int a; };
 int main() {
   new (struct A) { };
 }
Comment 2 Eric Gallager 2017-08-18 12:46:22 UTC
(In reply to Johannes Schaub from comment #0)
> The following looks like valid code:
> 
>  struct A { int a; }; 
>  int main() { 
>    new struct A {{ }}; 
>  }
> 
> The type-specifier-seq "struct A" is followed by a braced-init-list "{{}}".
> But GCC says:
> 
> main1.cpp: In function 'int main()':
> main1.cpp:3:16: error: types may not be defined in a new-type-id
> main1.cpp:3:17: error: expected unqualified-id before '{' token
> 
> As far as I can see, I would only define a new type if I would say:
> 
>     new struct A { };
> 
> But the two-braces disambiguates it.

Confirmed that g++ rejects it, but clang++ rejects it too:

$ /usr/local/bin/g++ -c -Wall -Wextra -pedantic 50169.cc
50169.cc: In function ‘int main()’:
50169.cc:3:15: error: types may not be defined in a new-type-id
  new struct A {{ }};
               ^
50169.cc:3:16: error: expected unqualified-id before ‘{’ token
  new struct A {{ }};
                ^
$ /sw/opt/llvm-3.1/bin/clang++ -c -Wall -Wextra -pedantic 50169.cc
50169.cc:3:16: error: expected member name or ';' after declaration specifiers
        new struct A {{ }}; 
                      ^
50169.cc:3:13: error: 'A' can not be defined in a type specifier
        new struct A {{ }}; 
                   ^
2 errors generated.
$

...so I'm not sure if it's an incorrect treatment or not...

(In reply to Ville Voutilainen from comment #1)
> Trying
> 
> struct A { int a; }; 
>  int main() { 
>    new (struct A) {{ }}; 
>  }
> 
> gives
> 
> internal compiler error: in cxx_eval_bare_aggregate, at cp/semantics.c:6601
> 

I can't reproduce this ICE with gcc8...

I guess I'll leave this in UNCONFIRMED for now.
Comment 3 Jonathan Wakely 2017-08-18 13:18:45 UTC
EDG rejects it too:

"gr.cc", line 3: error: expected a declaration
     new struct A {{ }}; 
                   ^

"gr.cc", line 3: error: type definition is not allowed
     new struct A {{ }}; 
         ^

2 errors detected in the compilation of "gr.cc".


VC++ accepts it though.

I suggest taking it to WG21 as a core issue.
Comment 4 Ville Voutilainen 2017-08-18 14:55:02 UTC
I have sent this to Core for consideration.
Comment 5 Ville Voutilainen 2017-08-18 17:27:05 UTC
This is DR 2141:
http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#2141

The original code is supposed to be valid, so confirming this as an actual bug.
Comment 6 Nathan Ridge 2017-10-18 16:03:47 UTC
Here is another test case that MSVC accepts but GCC rejects:

struct A {};
struct A* b = (1 == 1) ? new struct A : new struct A;
Comment 7 Eric Gallager 2018-10-18 04:42:22 UTC
(In reply to Nathan Ridge from comment #6)
> Here is another test case that MSVC accepts but GCC rejects:
> 
> struct A {};
> struct A* b = (1 == 1) ? new struct A : new struct A;

Is this really the same thing though?
Comment 8 Nathan Ridge 2018-10-21 20:06:35 UTC
(In reply to Eric Gallager from comment #7)
> (In reply to Nathan Ridge from comment #6)
> > Here is another test case that MSVC accepts but GCC rejects:
> > 
> > struct A {};
> > struct A* b = (1 == 1) ? new struct A : new struct A;
> 
> Is this really the same thing though?

I believe it's code that was made valid by DR2141, yes. I elaborate on my reasoning in the corresponding clang bug:

https://bugs.llvm.org/show_bug.cgi?id=34993