On Wed, 6 Nov 2024, Marek Polacek wrote:

> On Wed, Nov 06, 2024 at 09:42:02AM -0500, Marek Polacek wrote:
> > On reflection, I'm not so sure about these anymore:
> > 
> > On Mon, Nov 04, 2024 at 06:26:47PM -0500, Marek Polacek wrote:
> > > +  switch (extern int i = 0);  /* { dg-error "in condition|both .extern. 
> > > and initializer" } */
> > 
> > I think this is definitely valid.
> 
> Ugh, *INvalid*.
>  
> > > +  switch (register int i = 0); /* { dg-error "in condition" } */
> > > +  switch (static int i = 0); /* { dg-error "in condition" } */
> > > +  switch (thread_local int i = 0); /* { dg-error "in 
> > > condition|function-scope" } */
> > 
> > All three may be valid, actually.
> > 
> > > +  switch (typedef int i); /* { dg-error "in condition|initializer" } */
> > > +  switch (typedef int i = 0); /* { dg-error "in condition|initialized" } 
> > > */
> > 
> > Both remain invalid.
> > 
> > Joseph, let me know if you agree, and I'll adjust the patch.  Thanks.

There are no restrictions on storage class specifiers for 
simple-declarations separate from those applying to declarations in 
general.  When such a declaration would be invalid inside a function, it 
remains invalid as a simple-declaration; otherwise, it appears such 
statements are valid.  The wording is certainly questionable for such 
cases, since it talks about "the controlling expression is the value of 
the single declared object after initialization", but initialization in 
the static storage duration case occurs once at translation time whereas 
one would expect the if/switch to determine the controlling expression 
value once each execution.

I don't see any -std=c2y -pedantic-errors tests in the patch.  Such tests 
should be present for both valid and invalid code.

The logic for dealing with a simple declaration appears to use the 
declaration directly to extract its initialized value, without any 
convert_lvalue_to_rvalue, though there's one subsequently for switch 
statements.  But for if statements, I don't see anything that would ensure 
convert_lvalue_to_rvalue gets used.  In particular, although it's not 
specified whether the initialized value is re-read from the object, if the 
object is atomic it seems wrong to do a non-atomic read from it to get the 
value for the condition.

Another case to test: a simple declaration with array type.  Maybe "the 
value of the single declared object after initialization" means there is 
no conversion from array to pointer, in which case it would be invalid in 
both if and switch.

-- 
Joseph S. Myers
josmy...@redhat.com

Reply via email to