[cfe-dev] Cast to type with side effects

Douglas Gregor dgregor at apple.com
Wed Sep 22 08:55:35 PDT 2010


On Sep 22, 2010, at 8:13 AM, Abramo Bagnara wrote:

> 
> int g();
> 
> int main() {
>  //  enum { x = (g(), 0) };
>  enum { x = (int)(int(*)[g()])0 };
>  return 0;
> }
> 
> Constant expression evaluator seems to (wrongly IMHO) believe that types
> cannot have side effects.
> 
> Do you confirm we have a bug here?

I don't think this was meant to be well-formed C99, although it seems like there is a gap in the C99 standard here. In particular, C99 6.7.5.2p2 says:

  An ordinary identifier (as defined in 6.2.3) that has a variably modified type shall have either block scope and no linkage or function prototype scope.

Now, we're in a type-name (C99 6.7.6), so there is no identifier... however, the general view of type-names is that they are declarators without the identifier, which implies that C99 6.7.5p2 applies in this case. C99 6.7.7p3 strengthens our case somewhat, even though it is about typedefs, because it says:

	Any array size expressions associated with variable length array declarators are evaluated each time the declaration of the typedef name is reached in the order of execution.

There is no way to reach an enumerator constant in the order of execution, so it doesn't make sense to have a VLA there.

Oh, and EDG rejects this code in C99 mode.

Long story short: yes, there is a bug here, which is that Clang accepts this ill-formed program. It should reject the use of a variably-modified type in a cast.

	- Doug




More information about the cfe-dev mailing list