[cfe-commits] [PATCH] Don't apply function attributes to the return type

Charles Davis cdavis at mymail.mines.edu
Tue Feb 23 15:40:00 PST 2010


John McCall wrote:
> Is this actually what gcc does?  The documentation I've seen suggested that gcc tries to apply a function type attribute in the decl spec to the return type if it's a function pointer, and otherwise tries to apply it to the function itself.  But maybe I'm misinterpreting it, or maybe that documentation is incorrect:
>   http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Attribute-Syntax.html#Attribute-Syntax
> 
> At any rate, please do more investigation.  If this is the right thing to do, we'll do it, but until we have a clear idea what on earth gcc is doing here, I'd rather hold off.
I did some experimentation with GCC 4.2. The results are on the page for
PR6408. For your convenience, I reiterate them here:

- If the return type is a function pointer typedef, GCC does not even
attempt to apply the attribute to the return type. So, for example, this:

typedef void (*p)();
p __attribute__((stdcall)) f(void);

declares a function with the stdcall convention that returns a function
pointer instead of a function that returns a pointer to a function with
the stdcall convention.

These two are equivalent:
__attribute__((stdcall)) p f(void);
p __attribute__((stdcall)) f(void);

In both cases, the stdcall attribute belongs to 'f' instead of 'p'.

To understand why this is important, consider this example:
typedef void (__attribute__((stdcall)) *p)();
p __attribute__((cdecl)) f(const char *x);

GCC correctly interprets this to mean "The function 'f' is a 'cdecl'
function... that returns a pointer to a 'stdcall' function." Clang
without this patch, on the other hand, thinks that both the 'stdcall'
and the 'cdecl' belong to the return type. Since the return type already
has 'stdcall', Clang complains. The patch fixes this.

- If the return type is a raw function pointer, the attribute belongs to
the function itself if it's outside the parentheses and to the return
type if it's inside the parentheses. So in this:

void __attribute__((cdecl)) (__attribute__((stdcall)) *f(const char *x));

the function itself has the cdecl convention and the return type is a
pointer to a function with the stdcall convention. Clang currently has
this case backwards, even with this patch, in that the function has the
stdcall convention and the return type has the cdecl convention.

Chip



More information about the cfe-commits mailing list