[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