[LLVMdev] Different signatures or smart casting?

Kevin Hu hxy9243 at gmail.com
Fri Apr 10 19:22:29 PDT 2015


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
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150410/6a6d338a/attachment.html>


More information about the llvm-dev mailing list