[cfe-dev] Likely nasty bug with enum constants type

Douglas Gregor dgregor at apple.com
Wed Feb 3 11:23:55 PST 2010

On Feb 3, 2010, at 11:21 AM, Abramo Bagnara wrote:

> Il 01/02/2010 19:54, Douglas Gregor ha scritto:
>> On Feb 1, 2010, at 7:53 AM, Abramo Bagnara wrote:
>>> Il 01/02/2010 15:55, Eli Friedman ha scritto:
>>>> On Mon, Feb 1, 2010 at 3:17 AM, Abramo Bagnara <abramo.bagnara at gmail.com> wrote:
>>>>> $ cat bug.c
>>>>> enum {
>>>>> a = 1U,
>>>>> b = a-2
>>>>> };
>>>>> int x[b];
>>>>> $ gcc -S -std=c99 -pedantic -W -Wall bug.c
>>>>> bug.c:7: error: size of array ‘x’ is negative
>>>>> $ ~/llvm/Debug/bin/clang -S -std=c99 -pedantic -W -Wall bug.c
>>>>> $
>>>>> This typescript show that while gcc (as mandated by c99 standard)
>>>>> correctly gives int as the type of the enum constant, clang gives it
>>>>> unsigned type.
>>>>> Do you confirm the bug?
>>>> Yes; see http://llvm.org/bugs/show_bug.cgi?id=4515 .
>>> We have found this bug investigating about a failed assertion on clang
>>> that perhaps it's a different bug, I don't know.
>>> The fact is that after the type adapting phases of the enum constants to
>>> the finally decided underlying enum type, the DeclRefExpr referring an
>>> enum constant found inside another enum constant initializer expressions
>>> retains the original type (that is incongruent with newly assigned
>>> EnumConstantDecl type).
>> From the AST perspective, that's not necessarily a problem. In fact,
>> C++ is quite specific that the types of enumerators before and after the
>> closing "}" are different; we don't get that right either:
>> 	http://llvm.org/bugs/show_bug.cgi?id=5854
>> C is less clear, but the intent appears to be that the type of all
>> enumerator values is int. However, GCC extends C to permit enumerator
>> values which do not have type int when the value is not representable in
>> an int. So, we'll still end up with enumerator values that don't match
>> the enum type.
> I have to say that the thing is for me a surprise: are you saying that
> according to clang design, in the AST the registered type of a
> DeclRefExpr node may be different from type of referred Decl (at least
> in this case)?

In this case, yes. The C++ language explicitly specifies that the type of enum constants changes after the '}', and it's perfectly valid to have DeclRefExprs to an enum constant both before and after the type changed. We're accurately modeling the language, here.

> There are also other known cases where we can have such kind of type
> incongruences?

None that I know of.

> I was under the impression that types in AST should always be correct
> for things to work (and this is the reason why I was not surprised to
> see such assertion in constant expression evaluator).

The AST *is* correct; it's just modeling a very weird language. The constant expression evaluator needs to tread lightly here.

	- Doug

More information about the cfe-dev mailing list