mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-03 10:54:42 +00:00
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:
parent
9b27960b14
commit
d866898775
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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,
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
||||
|
@ -6,4 +6,6 @@
|
||||
|
||||
|
||||
|
||||
declare extern_weak i32 @pthread_cancel(i32)
|
||||
define weak i32 @pthread_cancel(i32) {
|
||||
ret i32 0
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: opt < %s -globalopt
|
||||
|
||||
@g = external global i32
|
||||
@g = global i32 0
|
||||
|
||||
@a = alias bitcast (i32* @g to i8*)
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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
12
test/Verifier/alias.ll
Normal 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
|
Loading…
x
Reference in New Issue
Block a user