LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 19955 - The address of a dllimported global variable cannot be used in a constant initializer
Summary: The address of a dllimported global variable cannot be used in a constant ini...
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Core LLVM classes (show other bugs)
Version: trunk
Hardware: PC Windows NT
: P normal
Assignee: David Majnemer
URL:
Keywords:
: 20076 (view as bug list)
Depends on:
Blocks:
 
Reported: 2014-06-05 12:32 PDT by Reid Kleckner
Modified: 2014-06-25 23:25 PDT (History)
8 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Reid Kleckner 2014-06-05 12:32:54 PDT
Consider:

extern "C" int __declspec(dllimport) x;
extern "C" int *y = &x;

Clang creates this LLVM IR:

@x = external dllimport global i32
@y = global i32* @x, align 4

This is lowered to:

        .data
        .globl  _y
        .align  4
_y:
        .long   _x

Which is incorrect, because x is dllimported, and its address isn't a link time constant.  It must be loaded from __imp_x.  Clang should emit something like the following IR instead:

@y = global i32* null, align 4
@x = external dllimport global i32
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @init, i8* null }]
define internal void @init() {
entry:
  store i32* @x, i32** @y, align 4
  ret void
}

This is consistent with what MSVC does, and it would be important to match them if x was selectany or a static data member of a class template.

However, this is really a bug in LLVM, because LLVM will optimize that IR back to Clang's original output:

$ opt t.ll -O2 -S -o -
@y = global i32* @x, align 4
@x = external dllimport global i32
@llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer

If y were a function, this would actually link correctly, because import libraries provide thunks for functions.  The only downside is that the address of a thunk isn't really the address of the function, but few programs rely on function identity.  There's no way to create a forwarding thunk for data, so we get a link failure with this test case.
Comment 1 Reid Kleckner 2014-06-18 13:03:17 PDT
*** Bug 20076 has been marked as a duplicate of this bug. ***
Comment 2 David Majnemer 2014-06-23 14:14:08 PDT
Fixes are available.
LLVM-related: http://reviews.llvm.org/D4249
Clang-related: http://reviews.llvm.org/D4250
Comment 3 David Majnemer 2014-06-24 01:55:07 PDT
Fixed in r211571, r211570, r211568.
Comment 4 Ehsan Akhgari [:ehsan] 2014-06-25 23:25:43 PDT
Thanks, I verified this on our side!