[cfe-commits] r102464 - in /cfe/trunk: lib/AST/ASTContext.cpp test/Sema/attr-regparm.c
Abramo Bagnara
abramo.bagnara at gmail.com
Wed Apr 28 14:35:47 PDT 2010
Il 28/04/2010 22:51, Eli Friedman ha scritto:
> On Wed, Apr 28, 2010 at 9:45 AM, Abramo Bagnara
> <abramo.bagnara at gmail.com> wrote:
>> Il 28/04/2010 18:15, Daniel Dunbar ha scritto:
>>> Hi Eli,
>>>
>>> I am about to revert this, it breaks a lot of project builds. I don't
>>> have a test case handy, but they all seem to involve noreturn. This is
>>> the ClamAV failure, for example:
>>> --
>>> clamdtop.c:435:24: error: conflicting types for 'exit_program'
>>> static void __noreturn exit_program(enum exit_reason reason, const
>>> char *func, unsigned line)
>>> ^
>>> clamdtop.c:113:13: note: previous declaration is here
>>> static void exit_program(enum exit_reason reason, const char *func,
>>> unsigned line);
>>> ^
>>
>> In added testcase:
>>
>> __attribute((regparm(1))) int g(void);
>> __attribute((regparm(2))) int g(void);
>>
>> we have conflicting attributes, while in
>>
>> enum exit_reason;
>>
>> #define __noreturn __attribute__((noreturn))
>> static void exit_program(enum exit_reason reason, const char *func,
>> unsigned line);
>> static void __noreturn exit_program(enum exit_reason reason, const
>> char *func, unsigned line)
>>
>> we should merge the attributes of the two function declarations.
>>
>> That apart, the patch concerning type incompatibility is correct.
>
> No, I think the issue is that the gcc model is seriously messed up.
> Take the following testcase:
>
> void a();
> void b() __attribute((noreturn));
> typedef void (*f1)();
> typedef void (*f2)() __attribute__ ((noreturn));
>
> int c() {
> return __builtin_types_compatible_p(typeof(a),typeof(b));
> }
>
> int p() {
> return __builtin_types_compatible_p(f1, f2);
> }
>
> You would think c() and p() would return the same thing, but they don't.
I was aware of that: in gcc typeof is broken with respect to functions
with attributes related to the type.
But please try:
void (*f1)(void) __attribute__((noreturn));
void (*f2)(void);
void g() {
int x[__builtin_types_compatible_p(typeof(f1), typeof(f2))*2-1];
}
The point is that function with such attributes and function with
conflicting attributes (or without them) cannot be mixed (and for good
reasons, I fear).
Two testcases:
1) from your patch:
__attribute((regparm(1))) int g(void);
__attribute((regparm(2))) int g(void);
2) a missing important warning:
void (*fun)() __attribute__((noreturn));
void f();
void g() {
fun = f;
}
If the choice to have attributes like regparm and noreturn attached to
types instead of declarations had been sensible, IMHO this means that
these attributes should make a difference when types are compared.
I'm missing something?
--
Abramo Bagnara
Opera Unica Phone: +39.0546.656023
Via Borghesi, 16
48014 Castel Bolognese (RA) - Italy
More information about the cfe-commits
mailing list