[cfe-dev] Running code on module load

Chris Lattner clattner at apple.com
Mon Mar 3 14:02:57 PST 2008

On Mar 3, 2008, at 9:17 AM, David Chisnall wrote:

> On further inspection, there appears to be a bug in llvm-gcc when
> performing this operation.
> The @llvm.global_ctors variable is defined as an array of i32,
> function pairs (the i32 seems to always be 65536 - does anyone know
> what this is?).

That number is an initializer priority, which can be set with  
attr(init_priority) on some targets.  No LLVM targets do anything with  
it, so you can just set it to 65536.

> However, the functions can have arbitrary types.  The
> following code will break llvm-gcc:
> int __attribute__((constructor)) foo(void) {
>   return 0;
> }
> void __attribute__((constructor)) bar(void) {}
> Worse, it doesn't give a nice warning, but an internal LLVM error
> because the first method defines the type of the array and the second
> being added (with a different type) breaks everything.

Whoops, I fixed this:

The LLVM IR generated for this test is now:

> Before I implement this in clang, I'd like to know if anyone knows the
> correct behaviour.  Presumably the ctor functions should only be of
> type void()*, since C doesn't provide any mechanism for handling
> returns or passing in arguments to functions called in this way.


> Should we be silently casting ctor functions to this, or throwing an
> error if they are of another form (could cause runtime errors if they
> actually try to use their parameters)?

Silently casting it is the right thing to do, and emitting a warning  
would also be great.  I wouldn't emit an error though.

> Is there an accompanying linker bug?  What happens if you define the
> @llvm.global_ctors as two different types in two different modules and
> then try linking them?

The front-end is required to make an array of type ["n" x { i32, void  
()* }], so the bug is in the front-end.


More information about the cfe-dev mailing list