[LLVMdev] Why a function pointer field in a LLVM IR struct is replaced by {}*?

Eli Friedman eli.friedman at gmail.com
Tue Sep 10 20:16:12 PDT 2013


On Tue, Sep 10, 2013 at 7:13 PM, Ben Niu <niuben003 at gmail.com> wrote:

> Dear LLVM developers,
>
> My name is Ben Niu and I am a Ph.D. student at Lehigh University. I
> compiled the MUSL C library using Clang 3.3, and dumped the generated LLVM
> IR files. I found that the MUSL-defined FILE struct (aliasing __FILE_s)
>
> struct __FILE_s {
>     unsigned flags;
>     unsigned char *rpos, *rend;
>     int (*close)(FILE *);
>     unsigned char *wend, *wpos;
>     unsigned char *mustbezero_1;
>     unsigned char *wbase;
>     size_t (*read)(FILE *, unsigned char *, size_t);
>     size_t (*write)(FILE *, const unsigned char *, size_t);
>     off_t (*seek)(FILE *, off_t, int);
>     unsigned char *buf;
>     size_t buf_size;
>     FILE *prev, *next;
>     int fd;
>     int pipe_pid;
>     long lockcount;
>     short dummy3;
>     signed char mode;
>     signed char lbf;
>     int lock;
>     int waiters;
>     void *cookie;
>     off_t off;
>     char *getln_buf;
>     void *mustbezero_2;
>     unsigned char *shend;
>     off_t shlim, shcnt;};
>
> was represented by
>
> %struct.__FILE_s = type { i32, i8*, i8*,
> i32 (%struct.__FILE_s*)*, i8*, i8*, i8*, i8*,
> i64 (%struct.__FILE_s*, i8*, i64)*,
> i64 (%struct.__FILE_s*, i8*, i64)*,
> i64 (%struct.__FILE_s*, i64, i32)*,
> i8*, i64, %struct.__FILE_s*, %struct.__FILE_s*,
> i32, i32, i64, i16, i8, i8, i32, i32, i8*,
> i64, i8*, i8*, i8*, i64, i64 }
>
>  in some IR files, but was represented by
>
> %struct.__FILE_s = type { i32, i8*, i8*,
> i32 (%struct.__FILE_s*)*, i8*, i8*, i8*, i8*,
> i64 (%struct.__FILE_s*, i8*, i64)*, {}*,
> i64 (%struct.__FILE_s*, i64, i32)*,
> i8*, i64, %struct.__FILE_s*, %struct.__FILE_s*,
> i32, i32, i64, i16, i8, i8, i32, i32, i8*,
> i64, i8*, i8*, i8*, i64, i64 }
>
>  in other source files. All these source files include the complete FILE
> struct definition. The only difference between these two IR structs is that
> a function pointer type field in the first form is replaced by {}* in the
> second form. Could anyone tell me why this happens and how to disable the
> {}* replacement?
>
>
> See CodeGenTypes::isFuncTypeArgumentConvertible in
clang/lib/CodeGen/CodeGenTypes.cpp; this behavior exists to protect the
type conversion code from infinite recursion. Our behavior could probably
be improved here; patches welcome (but be warned the code is rather
complicated).

Off the top of my head, I can't say why this is triggering in some files,
but not others.

-Eli
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130910/5d171065/attachment.html>


More information about the llvm-dev mailing list