Reject alias to undefined symbols in the verifier.
authorRafael Espindola <rafael.espindola@gmail.com>
Wed, 12 Mar 2014 20:15:49 +0000 (20:15 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Wed, 12 Mar 2014 20:15:49 +0000 (20:15 +0000)
On ELF and COFF an alias is just another name for a position in the file.
There is no way to refer to a position in another file, so an alias to
undefined is meaningless.

MachO currently doesn't support aliases. The spec has a N_INDR, which when
implemented will have a different set of restrictions. Adding support for
it shouldn't be harder than any other IR extension.

For now, having the IR represent what is actually possible with current
tools makes it easier to fix the design of GlobalAlias.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203705 91177308-0d34-0410-b5e6-96231b3b80d8

17 files changed:
docs/LangRef.rst
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/IR/Verifier.cpp
test/Analysis/BasicAA/2007-11-05-SizeCrash.ll
test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll
test/Assembler/2007-09-10-AliasFwdRef.ll
test/CodeGen/X86/2008-03-14-SpillerCrash.ll
test/CodeGen/X86/alias-error.ll [deleted file]
test/Feature/aliases.ll
test/Linker/2011-08-22-ResolveAlias2.ll
test/Transforms/GVN/2009-03-10-PREOnVoid.ll
test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll
test/Transforms/GlobalOpt/alias-resolve.ll
test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll
test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll
test/Transforms/MetaRenamer/metarenamer.ll
test/Verifier/alias.ll [new file with mode: 0644]

index cf1243a04b10d89987992b59eab1e68b9328c681..0a46e8375e2c87165afe95b866eecdc9a62fb40c 100644 (file)
@@ -687,6 +687,11 @@ The linkage must be one of ``private``, ``linker_private``,
 might not correctly handle dropping a weak symbol that is aliased by a non-weak
 alias.
 
+Alias that are not ``unnamed_addr`` are guaranteed to have the same address as
+the aliasee.
+
+The aliasee must be a definition.
+
 .. _namedmetadatastructure:
 
 Named Metadata
index ebca8e544baa5801ed6dcebb6a095be93face273..66ce4e1075d72763288391c28eb644ad37a72d63 100644 (file)
@@ -928,11 +928,7 @@ bool AsmPrinter::doFinalization(Module &M) {
       MCSymbol *Name = getSymbol(I);
 
       const GlobalValue *GV = I->getAliasedGlobal();
-      if (GV->isDeclaration()) {
-        report_fatal_error(Name->getName() +
-                           ": Target doesn't support aliases to declarations");
-      }
-
+      assert(!GV->isDeclaration());
       MCSymbol *Target = getSymbol(GV);
 
       if (I->hasExternalLinkage() || !MAI->getWeakRefDirective())
index fcdbac2f9f6f0a81e93afc2b538cbd559eb40e94..2fc77cc2d7271344fe65dbd2e22868459833b7d2 100644 (file)
@@ -501,6 +501,7 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) {
               &GA);
     }
   }
+  Assert1(!GV->isDeclaration(), "Alias must point to a definition", &GA);
 
   const GlobalValue* Resolved = GA.resolveAliasedGlobal(/*stopOnWeak*/ false);
   Assert1(Resolved,
index 563d3326367b4d47bff54c9882d8452d0171ca22..32d9930f42708adf0dbac186fa3a6aa089e789de 100644 (file)
@@ -7,7 +7,7 @@ target triple = "x86_64-unknown-linux-gnu"
         %struct.pci_device_id = type { i32, i32, i32, i32, i32, i32, i64 }
         %struct.usb_bus = type { %struct.device* }
         %struct.usb_hcd = type { %struct.usb_bus, i64, [0 x i64] }
-@uhci_pci_ids = external constant [1 x %struct.pci_device_id]           ; <[1 x %struct.pci_device_id]*> [#uses=1]
+@uhci_pci_ids = constant [1 x %struct.pci_device_id] zeroinitializer
 
 @__mod_pci_device_table = alias [1 x %struct.pci_device_id]* @uhci_pci_ids     
         ; <[1 x %struct.pci_device_id]*> [#uses=0]
index 52d0af1b81ce5718d10ead83f91b1692baab271b..cd997ea525133ea1d2ec5ee901dc418ac2b67986 100644 (file)
@@ -7,7 +7,7 @@ target triple = "x86_64-unknown-linux-gnu"
        %struct.pci_device_id = type { i32, i32, i32, i32, i32, i32, i64 }
        %struct.usb_bus = type { %struct.device* }
        %struct.usb_hcd = type { %struct.usb_bus, [0 x i64] }
-@pci_ids = external constant [1 x %struct.pci_device_id]               ; <[1 x %struct.pci_device_id]*> [#uses=1]
+@pci_ids = constant [1 x %struct.pci_device_id] zeroinitializer
 
 @__mod_pci_device_table = alias [1 x %struct.pci_device_id]* @pci_ids          ; <[1 x %struct.pci_device_id]*> [#uses=0]
 
index b21491ba5a90356795288a16a42a7a0776d038df..2ebfc2719e9561673a9d94ab5111e12ddf63b014 100644 (file)
@@ -6,4 +6,6 @@
 
 
 
-declare extern_weak i32 @pthread_cancel(i32)
+define weak i32 @pthread_cancel(i32) {
+  ret i32 0
+}
index 18b3714f851f89632583741de097dfaebe53b6e9..6b374a7f6f083bc9183200c3e51de01b5b36c14f 100644 (file)
@@ -6,7 +6,7 @@
        %struct.locale_data = type { i8*, i8*, i32, i32, { void (%struct.locale_data*)*, %struct.anon }, i32, i32, i32, [0 x %struct.locale_data_value] }
        %struct.locale_data_value = type { i32* }
 
-@wcstoll_l = alias i64 (i32*, i32**, i32, %struct.__locale_struct*)* @__wcstoll_l              ; <i64 (i32*, i32**, i32, %struct.__locale_struct*)*> [#uses=0]
+@wcstoll_l = alias i64 (i32*, i32**, i32, %struct.__locale_struct*)* @__wcstoll_l
 
 define i64 @____wcstoll_l_internal(i32* %nptr, i32** %endptr, i32 %base, i32 %group, %struct.__locale_struct* %loc) nounwind  {
 entry:
diff --git a/test/CodeGen/X86/alias-error.ll b/test/CodeGen/X86/alias-error.ll
deleted file mode 100644 (file)
index 8f01dcf..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-; RUN: not llc -mtriple=i686-pc-linux-gnu %s -o /dev/null 2>&1 | FileCheck %s
-
-@a = external global i32
-@b = alias i32* @a
-; CHECK: b: Target doesn't support aliases to declarations
index 139381215ee80835e145ea31daa5af2db6dab4da..7ffa5f2601361a21057c5dd434918852ccd71c39 100644 (file)
@@ -4,14 +4,16 @@
 
 @llvm.used = appending global [1 x i8*] [i8* bitcast (i32* @foo1 to i8*)], section "llvm.metadata"
 
-@bar = external global i32
+@bar = global i32 0
 @foo1 = alias i32* @bar
 @foo2 = alias i32* @bar
 @foo3 = alias i32* @foo2
 
 %FunTy = type i32()
 
-declare i32 @foo_f()
+define i32 @foo_f() {
+  ret i32 0
+}
 @bar_f = alias weak %FunTy* @foo_f
 @bar_ff = alias i32()* @bar_f
 
index 2549040597338444ddd9ca81b22e1be637ffd8ef..eee60d49d02605b6876d2d6a9826e307456bf151 100644 (file)
 @_ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti = alias weak i32 (%union.pthread_mutexattr_t*, i32)* @pthread_mutexattr_settype
 @_ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutexattr_t*)* @pthread_mutexattr_destroy
 
-declare void @_ZN13HexxagonBoardC2ERKS_(%struct.HexxagonBoard*, %struct.HexxagonBoard*) uwtable align 2
+define void @_ZN13HexxagonBoardC2ERKS_(%struct.HexxagonBoard*, %struct.HexxagonBoard*) uwtable align 2 {
+  ret void
+}
 
-declare extern_weak i32 @pthread_once(i32*, void ()*)
+define weak i32 @pthread_once(i32*, void ()*) {
+  ret i32 0
+}
 
-declare extern_weak i8* @pthread_getspecific(i32)
+define weak i8* @pthread_getspecific(i32) {
+  ret i8* null
+}
 
-declare extern_weak i32 @pthread_setspecific(i32, i8*)
+define weak i32 @pthread_setspecific(i32, i8*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*)
+define weak i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_join(i64, i8**)
+define weak i32 @pthread_join(i64, i8**) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_equal(i64, i64)
+define weak i32 @pthread_equal(i64, i64) {
+  ret i32 0
+}
 
-declare extern_weak i64 @pthread_self()
+define weak i64 @pthread_self() {
+  ret i64 0
+}
 
-declare extern_weak i32 @pthread_detach(i64)
+define weak i32 @pthread_detach(i64) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_cancel(i64)
+define weak i32 @pthread_cancel(i64) {
+  ret i32 0
+}
 
-declare extern_weak i32 @sched_yield()
+define weak i32 @sched_yield() {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_mutex_lock(%union.pthread_mutex_t*)
+define weak i32 @pthread_mutex_lock(%union.pthread_mutex_t*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_mutex_trylock(%union.pthread_mutex_t*)
+define weak i32 @pthread_mutex_trylock(%union.pthread_mutex_t*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_mutex_timedlock(%union.pthread_mutex_t*, %struct.timespec*)
+define weak i32 @pthread_mutex_timedlock(%union.pthread_mutex_t*, %struct.timespec*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_mutex_unlock(%union.pthread_mutex_t*)
+define weak i32 @pthread_mutex_unlock(%union.pthread_mutex_t*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_mutex_init(%union.pthread_mutex_t*, %union.pthread_mutexattr_t*)
+define weak i32 @pthread_mutex_init(%union.pthread_mutex_t*, %union.pthread_mutexattr_t*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_mutex_destroy(%union.pthread_mutex_t*)
+define weak i32 @pthread_mutex_destroy(%union.pthread_mutex_t*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_cond_broadcast(%union.pthread_cond_t*)
+define weak i32 @pthread_cond_broadcast(%union.pthread_cond_t*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_cond_signal(%union.pthread_cond_t*)
+define weak i32 @pthread_cond_signal(%union.pthread_cond_t*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_cond_wait(%union.pthread_cond_t*, %union.pthread_mutex_t*)
+define weak i32 @pthread_cond_wait(%union.pthread_cond_t*, %union.pthread_mutex_t*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_cond_timedwait(%union.pthread_cond_t*, %union.pthread_mutex_t*, %struct.timespec*)
+define weak i32 @pthread_cond_timedwait(%union.pthread_cond_t*, %union.pthread_mutex_t*, %struct.timespec*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_cond_destroy(%union.pthread_cond_t*)
+define weak i32 @pthread_cond_destroy(%union.pthread_cond_t*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_key_create(i32*, void (i8*)*)
+define weak i32 @pthread_key_create(i32*, void (i8*)*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_key_delete(i32)
+define weak i32 @pthread_key_delete(i32) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_mutexattr_init(%union.pthread_mutexattr_t*)
+define weak i32 @pthread_mutexattr_init(%union.pthread_mutexattr_t*) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_mutexattr_settype(%union.pthread_mutexattr_t*, i32)
+define weak i32 @pthread_mutexattr_settype(%union.pthread_mutexattr_t*, i32) {
+  ret i32 0
+}
 
-declare extern_weak i32 @pthread_mutexattr_destroy(%union.pthread_mutexattr_t*)
+define weak i32 @pthread_mutexattr_destroy(%union.pthread_mutexattr_t*) {
+  ret i32 0
+}
index 89d6a5f982b8882d6cc57d68d1de8c11af0f43f8..fd31fce59a842d080fdabc67abbc6cada4a9c606 100644 (file)
@@ -53,30 +53,58 @@ bb11:               ; preds = %bb7, %bb5
        unreachable
 }
 
-declare i32 @pthread_once(i32*, void ()*)
+define i32 @pthread_once(i32*, void ()*) {
+       ret i32 0
+}
 
-declare i8* @pthread_getspecific(i32)
+define i8* @pthread_getspecific(i32) {
+       ret i8* null
+}
 
-declare i32 @pthread_setspecific(i32, i8*)
+define i32 @pthread_setspecific(i32, i8*) {
+        ret i32 0
+}
 
-declare i32 @pthread_create(i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)
+define i32 @pthread_create(i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*) {
+       ret i32 0
+}
 
-declare i32 @pthread_cancel(i32)
+define i32 @pthread_cancel(i32) {
+      ret i32 0
+}
 
-declare i32 @pthread_mutex_lock(%struct.pthread_mutex_t*)
+define i32 @pthread_mutex_lock(%struct.pthread_mutex_t*) {
+       ret i32 0
+}
 
-declare i32 @pthread_mutex_trylock(%struct.pthread_mutex_t*)
+define i32 @pthread_mutex_trylock(%struct.pthread_mutex_t*) {
+       ret i32 0
+}
 
-declare i32 @pthread_mutex_unlock(%struct.pthread_mutex_t*)
+define i32 @pthread_mutex_unlock(%struct.pthread_mutex_t*) {
+       ret i32 0
+}
 
-declare i32 @pthread_mutex_init(%struct.pthread_mutex_t*, %struct.__sched_param*)
+define i32 @pthread_mutex_init(%struct.pthread_mutex_t*, %struct.__sched_param*) {
+        ret i32 0
+}
 
-declare i32 @pthread_key_create(i32*, void (i8*)*)
+define i32 @pthread_key_create(i32*, void (i8*)*) {
+       ret i32 0
+}
 
-declare i32 @pthread_key_delete(i32)
+define i32 @pthread_key_delete(i32) {
+        ret i32 0
+}
 
-declare i32 @pthread_mutexattr_init(%struct.__sched_param*)
+define i32 @pthread_mutexattr_init(%struct.__sched_param*) {
+        ret i32 0
+}
 
-declare i32 @pthread_mutexattr_settype(%struct.__sched_param*, i32)
+define i32 @pthread_mutexattr_settype(%struct.__sched_param*, i32) {
+        ret i32 0
+}
 
-declare i32 @pthread_mutexattr_destroy(%struct.__sched_param*)
+define i32 @pthread_mutexattr_destroy(%struct.__sched_param*) {
+       ret i32 0
+}
index a1b69efe1a76f1e5cf8778644871a59b6f6a4ea7..d6a565ad10a8fdbdec513aa8f96bfaa46e66d78c 100644 (file)
@@ -1,6 +1,6 @@
 ; RUN: opt < %s -globalopt
 
-@g = external global i32
+@g = global i32 0
 
 @a = alias bitcast (i32* @g to i8*)
 
index 5e229b94268078a75494c2fc934f0bb2aa20f662..64e3d88af8aa721d1d9f18bab91d8fb85fe4a06d 100644 (file)
@@ -9,8 +9,10 @@
 @bar1  = alias void ()* @bar2
 ; CHECK: @bar1 = alias void ()* @bar2
 
-declare void @bar2()
-; CHECK: declare void @bar2()
+define void @bar2() {
+  ret void
+}
+; CHECK: define void @bar2()
 
 define void @baz() {
 entry:
index c27fe0ab6a6dbb9a412de306a36cc8eeb856d3cc..7f9bd9e40dcb119629ffa0f0ff6bb405aa4c6eea 100644 (file)
@@ -3,7 +3,9 @@
 
 @__gthrw_pthread_cancel = alias weak i32 (i32)* @pthread_cancel                ; <i32 (i32)*> [#uses=1]
 @__gthread_active_ptr.5335 = internal constant i8* bitcast (i32 (i32)* @__gthrw_pthread_cancel to i8*)         ; <i8**> [#uses=1]
-declare extern_weak i32 @pthread_cancel(i32)
+define weak i32 @pthread_cancel(i32) {
+       ret i32 0
+}
 
 define i1 @__gthread_active_p() {
 entry:
index 23ee12ba754f4bfc140f970a053b024cec9d42bf..c7cef752dcc9e6bc48dd26177358bfae99af89b7 100644 (file)
@@ -3,7 +3,9 @@
 
 @A = alias weak void ()* @B            ; <void ()*> [#uses=1]
 
-declare extern_weak void @B()
+define weak void @B() {
+       ret void
+}
 
 define i32 @active() {
 entry:
index 4020e10450813d0e87d947c783bd3b5467e15cdc..6297af62ff0cb9b865850b95c7b03242a0fd433a 100644 (file)
@@ -14,7 +14,9 @@ target triple = "x86_64-pc-linux-gnu"
 
 @func_7_xxx = alias weak i32 (...)* @aliased_func_7_xxx
 
-declare i32 @aliased_func_7_xxx(...)
+define i32 @aliased_func_7_xxx(...) {
+  ret i32 0
+}
 
 define i32 @func_3_xxx() nounwind uwtable ssp {
   ret i32 3
diff --git a/test/Verifier/alias.ll b/test/Verifier/alias.ll
new file mode 100644 (file)
index 0000000..e3636bc
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN:  not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+
+declare void @f()
+@fa = alias void ()* @f
+; CHECK: Alias must point to a definition
+; CHECK-NEXT: @fa
+
+@g = external global i32
+@ga = alias i32* @g
+; CHECK: Alias must point to a definition
+; CHECK-NEXT: @ga