llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.69k stars 11.87k forks source link

Confusing error message for "goto" jump over variably modified type #62219

Open tstanisl opened 1 year ago

tstanisl commented 1 year ago

The following C code:

int foo() {
   int n = 42;
   typedef char T[n];
   goto label;
   T *a;
label:
   return sizeof a;
}

fails to compile with an error:

<source>:4:4: error: cannot jump from this goto statement to its label
   goto label;
   ^
<source>:5:7: note: jump bypasses initialization of variable length array
   T *a;

The second note is invalid. There is no initialization there. There is even no declaration of VLA. The note should be:

note: jump over declaration of an identifier with variably modified type

The other question is why such declarations are disallowed because the type of a is fully established. Nothing needs to be evaluated there.

shafik commented 1 year ago

clang and gcc are consistent on this error: https://godbolt.org/z/4Mqqx64dE

Although clang's diagnostic could be worded better.

We are not allowed to jump from outside the scope of identifier have a variable modified type.

CC @AaronBallman in case he has more comments

efriedma-quic commented 1 year ago

Standard says "A goto statement shall not jump from outside the scope of an identifier having a variably modified type to inside the scope of that identifier." You could argue the standard is overly strict here, but that is what it says.

AaronBallman commented 1 year ago

I agree that Clang and GCC are correct.

C2x 6.8.6.1p1, in part: "A goto statement shall not jump from outside the scope of an identifier having a variably modified type to inside the scope of that identifier."

C2x 6.2.1p4, in part: " If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the end of the associated block."

C2x 6.2.1p6: "Two identifiers have the same scope if and only if their scopes terminate at the same point."

C2x 6.2.1p7, in part: "Any other identifier has scope that begins just after the completion of its declarator."

So a and label have the same scope termination point, but the goto jumps over the entrypoint for the scope of a.

Closing as not a bug.

tstanisl commented 1 year ago

@AaronBallman The issue was raised to improve the error message which is wrong or very confusing at best. Please reopen the ticket.

I agree that the standard is overstrict in this case but it says what it says.

AaronBallman commented 1 year ago

@AaronBallman The issue was raised to improve the error message which is wrong or very confusing at best. Please reopen the ticket.

Okay, sorry for jumping the gun!