From 38048cdb1c016e1429004ddf4adfa40a8d853cbf Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 12 Mar 2014 20:15:49 +0000 Subject: [PATCH] Reject alias to undefined symbols in the verifier. 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 --- docs/LangRef.rst | 5 + lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 6 +- lib/IR/Verifier.cpp | 1 + test/Analysis/BasicAA/2007-11-05-SizeCrash.ll | 2 +- .../BasicAA/2007-12-08-OutOfBoundsCrash.ll | 2 +- test/Assembler/2007-09-10-AliasFwdRef.ll | 4 +- test/CodeGen/X86/2008-03-14-SpillerCrash.ll | 2 +- test/CodeGen/X86/alias-error.ll | 5 - test/Feature/aliases.ll | 6 +- test/Linker/2011-08-22-ResolveAlias2.ll | 108 +++++++++++++----- test/Transforms/GVN/2009-03-10-PREOnVoid.ll | 56 ++++++--- .../GlobalOpt/2009-02-15-BitcastAlias.ll | 2 +- test/Transforms/GlobalOpt/alias-resolve.ll | 6 +- .../InstCombine/2007-09-10-AliasConstFold.ll | 4 +- .../InstCombine/2007-09-17-AliasConstFold2.ll | 4 +- test/Transforms/MetaRenamer/metarenamer.ll | 4 +- test/Verifier/alias.ll | 12 ++ 17 files changed, 166 insertions(+), 63 deletions(-) delete mode 100644 test/CodeGen/X86/alias-error.ll create mode 100644 test/Verifier/alias.ll diff --git a/docs/LangRef.rst b/docs/LangRef.rst index cf1243a04b1..0a46e8375e2 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -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 diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index ebca8e544ba..66ce4e1075d 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -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()) diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index fcdbac2f9f6..2fc77cc2d72 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -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, diff --git a/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll b/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll index 563d3326367..32d9930f427 100644 --- a/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll +++ b/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll @@ -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] diff --git a/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll b/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll index 52d0af1b81c..cd997ea5251 100644 --- a/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll +++ b/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll @@ -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] diff --git a/test/Assembler/2007-09-10-AliasFwdRef.ll b/test/Assembler/2007-09-10-AliasFwdRef.ll index b21491ba5a9..2ebfc2719e9 100644 --- a/test/Assembler/2007-09-10-AliasFwdRef.ll +++ b/test/Assembler/2007-09-10-AliasFwdRef.ll @@ -6,4 +6,6 @@ -declare extern_weak i32 @pthread_cancel(i32) +define weak i32 @pthread_cancel(i32) { + ret i32 0 +} diff --git a/test/CodeGen/X86/2008-03-14-SpillerCrash.ll b/test/CodeGen/X86/2008-03-14-SpillerCrash.ll index 18b3714f851..6b374a7f6f0 100644 --- a/test/CodeGen/X86/2008-03-14-SpillerCrash.ll +++ b/test/CodeGen/X86/2008-03-14-SpillerCrash.ll @@ -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 ; [#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 index 8f01dcff2bf..00000000000 --- a/test/CodeGen/X86/alias-error.ll +++ /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 diff --git a/test/Feature/aliases.ll b/test/Feature/aliases.ll index 139381215ee..7ffa5f26013 100644 --- a/test/Feature/aliases.ll +++ b/test/Feature/aliases.ll @@ -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 diff --git a/test/Linker/2011-08-22-ResolveAlias2.ll b/test/Linker/2011-08-22-ResolveAlias2.ll index 25490405973..eee60d49d02 100644 --- a/test/Linker/2011-08-22-ResolveAlias2.ll +++ b/test/Linker/2011-08-22-ResolveAlias2.ll @@ -37,56 +37,110 @@ @_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 +} diff --git a/test/Transforms/GVN/2009-03-10-PREOnVoid.ll b/test/Transforms/GVN/2009-03-10-PREOnVoid.ll index 89d6a5f982b..fd31fce59a8 100644 --- a/test/Transforms/GVN/2009-03-10-PREOnVoid.ll +++ b/test/Transforms/GVN/2009-03-10-PREOnVoid.ll @@ -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 +} diff --git a/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll b/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll index a1b69efe1a7..d6a565ad10a 100644 --- a/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll +++ b/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -globalopt -@g = external global i32 +@g = global i32 0 @a = alias bitcast (i32* @g to i8*) diff --git a/test/Transforms/GlobalOpt/alias-resolve.ll b/test/Transforms/GlobalOpt/alias-resolve.ll index 5e229b94268..64e3d88af8a 100644 --- a/test/Transforms/GlobalOpt/alias-resolve.ll +++ b/test/Transforms/GlobalOpt/alias-resolve.ll @@ -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: diff --git a/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll b/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll index c27fe0ab6a6..7f9bd9e40dc 100644 --- a/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll +++ b/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll @@ -3,7 +3,9 @@ @__gthrw_pthread_cancel = alias weak i32 (i32)* @pthread_cancel ; [#uses=1] @__gthread_active_ptr.5335 = internal constant i8* bitcast (i32 (i32)* @__gthrw_pthread_cancel to 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: diff --git a/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll b/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll index 23ee12ba754..c7cef752dcc 100644 --- a/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll +++ b/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll @@ -3,7 +3,9 @@ @A = alias weak void ()* @B ; [#uses=1] -declare extern_weak void @B() +define weak void @B() { + ret void +} define i32 @active() { entry: diff --git a/test/Transforms/MetaRenamer/metarenamer.ll b/test/Transforms/MetaRenamer/metarenamer.ll index 4020e104508..6297af62ff0 100644 --- a/test/Transforms/MetaRenamer/metarenamer.ll +++ b/test/Transforms/MetaRenamer/metarenamer.ll @@ -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 index 00000000000..e3636bc7017 --- /dev/null +++ b/test/Verifier/alias.ll @@ -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