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.

llvm-svn: 203705
This commit is contained in:
Rafael Espindola 2014-03-12 20:15:49 +00:00
parent 9b27960b14
commit d866898775
17 changed files with 166 additions and 63 deletions

View 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

View 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())

View 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,

View 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]

View 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]

View File

@ -6,4 +6,6 @@
declare extern_weak i32 @pthread_cancel(i32)
define weak i32 @pthread_cancel(i32) {
ret i32 0
}

View 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:

View File

@ -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

View 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

View File

@ -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
}

View 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
}

View File

@ -1,6 +1,6 @@
; RUN: opt < %s -globalopt
@g = external global i32
@g = global i32 0
@a = alias bitcast (i32* @g to i8*)

View 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:

View 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:

View 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:

View 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

12
test/Verifier/alias.ll Normal file
View File

@ -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