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

Charles Davis cdavis at mymail.mines.edu
Tue Feb 23 17:34:09 PST 2010


John McCall wrote:
> On Feb 23, 2010, at 3:40 PM, Charles Davis wrote:
>> 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:
> 
> I did read the bug commentary before I posted.  My question is whether this behavior is intentional or extensional :).  That is, is this an *aspect* of the rule that gcc uses, or merely a *consequence*?
> 
> In particular, it is quite possible that gcc checks if the innermost declarator is a function (or pointer to function?) and, if so, applying CCs in the declaration-specifiers to that function rather than the type in the type-specifiers.  That's distinguishable from "don't apply CCs to the return type" in several ways:
> 
> typedef void ftype(int);
> ftype __attribute__((fastcall)) **fpp; // is this accepted?
> ftype __attribute__((fastcall)) *fpa[10];  // or this?
For both tof these, GCC tried to apply it to the pointer (or the array,
in the second case).
> ftype __attribute__((fastcall)) (**fpfpp)(int); // and which function does the attribute affect here?
Neither. For one thing, GCC didn't like that this function returns a
function. This probably confused GCC, and so it ended up applying it to
the pointer itself (which, of course, fails).

Adding an asterisk causes GCC to accept it, but placement of the
asterisk was important. If it came before the calling convention
attribute, GCC attached it to the return type (which I determined by
looking at the generated code for a function of the type to which fpfpp
points).

If the asterisk came after, GCC once again fails to apply the attribute,
but that's because it's trying to apply the attribute to the pointer to
a function pointer. It understands functions and function pointers, but
not pointers to function pointers.

It's interesting how GCC gets this backwards--at least, in my opinion. I
would think that it would be the other way around, that if the calling
convention comes before the asterisk, it belongs to the return type, and
if it comes after, it belongs to the function. My verdict: this is
definitely extensional behavior.

How do you come up with this stuff?
> 
> Also, what happens in a declaration group?  Does it make the decision separately for each declaration, or is the decision made for the first declaration carried over to subsequent declarations?
For a function typedef (not a function *pointer* typedef), it depends on
where the asterisk is. If the calling convention comes before the
asterisk, the attribute applies to the whole group. If it comes after,
it only applies to the first one.

For function pointer typedefs, it always applies the attribute to the
whole group.
> 
> I accept that the rule I implemented earlier is incorrect;  I just want to know what the correct rule is before we start hacking in more things that make individual projects work.
Good point. Hope this helps.

Chip



More information about the cfe-commits mailing list