[cfe-dev] Problem with struct arguments passed by value

Chris Lattner clattner at apple.com
Wed Apr 9 13:55:33 PDT 2008


On Apr 9, 2008, at 1:35 PM, Eli Friedman wrote:

> On Wed, Apr 9, 2008 at 1:06 PM, Shantonu Sen <ssen at apple.com> wrote:
>> I have the following program that I'm trying to compile with clang on
>> Mac OS X on Intel, which clang fails to codegen correctly.
>>
>> $ cat a.c
>>
>> typedef struct {
>>     long location;
>>     long length;
>> } CFRange;
>>
>> char CFArrayContainsValue(void *theArray, CFRange range, const void
>> *value);
>
> llvm-gcc:
> declare i8 @CFArrayContainsValue(i8*, i32, i32, i8*) signext
>
> clang:
> declare i8 @CFArrayContainsValue(i8*, %struct.anon*, i8*)
>
> What the heck is llvm-gcc doing here?!

Heh, it is lowering the structure to make it match the ABI.  This is  
gross, but correct.

Clang hasn't done much of anything to try to match the ABI.  At the  
very least though, structs passed by value should be marked with the  
byval attribute.  The code should work better if compiled to:

> declare i8 @CFArrayContainsValue(i8*, %struct.anon* byval, i8*)  
> signext

Also, note that '-arch x86_64' doesn't currently switch the target  
information fully: I think it will still think that pointers are 32- 
bit etc:

 From include/clang/Basic/TargetInfo.h:

   /// getPointerWidth - Return the width of pointers on this target,  
for the
   /// specified address space. FIXME: implement correctly.
   uint64_t getPointerWidth(unsigned AddrSpace) const { return 32; }
   uint64_t getPointerAlign(unsigned AddrSpace) const { return 32; }

-Chris



More information about the cfe-dev mailing list