[LLVMdev] Different signatures or smart casting?

Ksenia Dolgorukova der.spiegel.sieht.mich at gmail.com
Sat Apr 11 02:50:59 PDT 2015


Yes, this is a feature, I think. Furthermore, I looked for it in
Linker source code and run linker with gdb but I cann't find the
moment of signature changing. It's like a magic. When Verifier pass
works on linked code it finds nothing! If signatures were not changed
Verifier must throw an error of parameter mismatching.

2015-04-11 5:22 GMT+03:00 Kevin Hu <hxy9243 at gmail.com>:
>
> Dear Ksenia,
>
>>
>> Message: 3
>> Date: Fri, 10 Apr 2015 16:03:18 +0300
>> From: Ksenia Dolgorukova <der.spiegel.sieht.mich at gmail.com>
>> To: llvmdev at cs.uiuc.edu
>> Subject: [LLVMdev] Different signatures or smart casting?
>> Message-ID:
>>
>> <CALtCODFHh-Y9dreELuiiHt2BXRcmtBSr6LXAzvExhEGoSqPrtw at mail.gmail.com>
>> Content-Type: text/plain; charset=UTF-8
>>
>>
>> Hello!
>> I linked two bitcode files like described below using LTO and find
>> they are linked fine instead of making an error.
>> ----------
>> 1.bc
>> ----------
>> ...
>> define i32 @main(i32 %argc, i8** %argv) #0 {
>> entry:
>> ...
>> %call = call i32 @_Z1aj(i64 2)
>> ...
>> }
>> declare i32 @_Z1aj(i64) #1
>> ...
>>
>> ----------
>> 2.bc
>> ----------
>> ...
>> define i32 @_Z1aj(i32 %b) #0 {
>> entry:
>> ...
>> }
>> ...
>>
>> ----------
>>
>> In the first file function "_Z1aj" is declared as having i64 argument,
>> whereas in the second file the function "_Z1aj" is described as having
>> i32 argument!
>>
>> Are function signatures different?
>> How does LLVM cast them?
>> Could it be a bug?
>
>
>
> After playing around a little bit, I found this might actually be a feature
> of the C language. And please correct me if I'm wrong. For example, the
> following actually gets compiled with clang as well as gcc:
>
> // main.c
> #include <stdio.h>
> void foo(char c);
> int main()
> {
>     foo(100);
>     return 0;
> }
>
> // foo.c
> #include <stdio.h>
> void foo(int c)
> {
>     printf("The param is %d\n", c);
> }
>
>
> $ gcc hello.c foo.c
>
> Although the declaration and definition for foo has different parameter
> types, the foo.c and main.c compiled successfully. I think this might be the
> 'feature' of the linker, since C object files exposes function names only.
> This won't compiler if you're using clang++ or g++.
>
> The corresponding IR is following:
>
> ;; main.ll
>
> declare void @foo(i8 signext) #1
>
> ;; foo.ll
>
> define void @foo(i32 %c) #0 {
>   ...
> }
>
>
> Not only so, the following C code also compiles with gcc-4.9 and clang-3.5:
>
> // main.c
>
> void foo(char c);
>
> // foo.c
> void foo(int c, int d, int e)
> {
>     printf("The param is %d, %d, %d\n", c, d, e);
> }
>
> The running result is:
>
> The param is 100, 911150376, 911150392
>
> The last two numbers, I believe, represents memory on the stack, cause
> that's where the C functions are reading parameters from.
>
> Correct me if you found somewhere I was wrong.
>
>
> Regards,
> Kevin
>
>
>>
>> --
>> Best regards, Ksenia
>>
>>
>



-- 
Best regards, Ksenia



More information about the llvm-dev mailing list