diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/NaCl/PNaClABI/abi-debug-info.ll | 37 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/abi-metadata.ll | 11 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/abi-small-arguments.ll | 17 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/abi-stripped-pointers.ll | 131 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/abi-switch.ll | 31 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/abi-varargs.ll | 2 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/instructions.ll | 61 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/types-function.ll | 13 | ||||
-rw-r--r-- | test/NaCl/PNaClABI/types.ll | 56 | ||||
-rw-r--r-- | test/Transforms/NaCl/replace-ptrs-with-ints.ll | 8 |
10 files changed, 292 insertions, 75 deletions
diff --git a/test/NaCl/PNaClABI/abi-debug-info.ll b/test/NaCl/PNaClABI/abi-debug-info.ll new file mode 100644 index 0000000000..95efa0ced7 --- /dev/null +++ b/test/NaCl/PNaClABI/abi-debug-info.ll @@ -0,0 +1,37 @@ +; RUN: pnacl-abicheck -pnaclabi-allow-dev-intrinsics=0 < %s | FileCheck %s +; RUN: pnacl-abicheck -pnaclabi-allow-dev-intrinsics=0 \ +; RUN: -pnaclabi-allow-debug-metadata < %s | FileCheck %s --check-prefix=DBG +; RUN: pnacl-abicheck -pnaclabi-allow-dev-intrinsics=1 < %s | \ +; RUN: FileCheck %s --check-prefix=DBG + + +; DBG-NOT: disallowed + + +declare void @llvm.dbg.declare(metadata, metadata) +declare void @llvm.dbg.value(metadata, i64, metadata) + +; CHECK: Function llvm.dbg.declare is a disallowed LLVM intrinsic +; CHECK: Function llvm.dbg.value is a disallowed LLVM intrinsic + + +define void @debug_declare(i32 %val) { + ; We normally expect llvm.dbg.declare to be used on an alloca. + %var = alloca [4 x i8] + tail call void @llvm.dbg.declare(metadata !{[4 x i8]* %var}, metadata !{}) + tail call void @llvm.dbg.declare(metadata !{i32 %val}, metadata !{}) + ret void +} + +define void @debug_value(i32 %ptr_as_int, i32 %val) { + %ptr = inttoptr i32 %ptr_as_int to i8* + tail call void @llvm.dbg.value(metadata !{i8* %ptr}, i64 2, metadata !{}) + tail call void @llvm.dbg.value(metadata !{i32 %val}, i64 1, metadata !{}) + ret void +} + +; FileCheck gives an error if its input file is empty, so ensure that +; the output of pnacl-abicheck is non-empty by generating at least one +; error. +declare void @bad_func(ppc_fp128 %bad_arg) +; DBG: Function bad_func has disallowed type: void (ppc_fp128) diff --git a/test/NaCl/PNaClABI/abi-metadata.ll b/test/NaCl/PNaClABI/abi-metadata.ll index 4734c25973..751a3d3673 100644 --- a/test/NaCl/PNaClABI/abi-metadata.ll +++ b/test/NaCl/PNaClABI/abi-metadata.ll @@ -2,12 +2,13 @@ ; RUN: pnacl-abicheck -pnaclabi-allow-debug-metadata < %s | FileCheck %s --check-prefix=DEBUG -; If the metadata is allowed we want to check for types. -; We have a hacky way to test this. The -allow-debug-metadata whitelists debug -; metadata. That allows us to check types within debug metadata, even though -; debug metadata normally does not have illegal types. +; Metadata is not part of the PNaCl's stable ABI, so normally the ABI +; checker rejects metadata entirely. However, for debugging support, +; pre-finalized pexes may contain metadata. When checking a +; pre-finalized pexe, the ABI checker does not check the types in the +; metadata. + ; DEBUG-NOT: Named metadata node llvm.dbg.cu is disallowed -; DEBUG: Named metadata node llvm.dbg.cu refers to disallowed type: half ; CHECK: Named metadata node llvm.dbg.cu is disallowed !llvm.dbg.cu = !{!0} !0 = metadata !{ half 0.0} diff --git a/test/NaCl/PNaClABI/abi-small-arguments.ll b/test/NaCl/PNaClABI/abi-small-arguments.ll index 890b84c42a..ce698e7d47 100644 --- a/test/NaCl/PNaClABI/abi-small-arguments.ll +++ b/test/NaCl/PNaClABI/abi-small-arguments.ll @@ -21,25 +21,32 @@ define i8 @return_i8() { ; CHECK: Function return_i8 has disallowed type: -; Direct calls currently do not produce errors because the functions -; are deemed to have already been flagged. -; CHECK-NOT: disallowed define void @bad_direct_calls() { call void @arg_i1(i1 0) +; CHECK: bad function callee operand: call void @arg_i1 + call void @arg_i16(i32 0, i16 0) +; CHECK-NEXT: bad function callee operand: call void @arg_i16 + %result1 = call i1 @return_i1() +; CHECK-NEXT: bad function callee operand: {{.*}} call i1 @return_i1 + %result2 = call i8 @return_i8() +; CHECK-NEXT: bad function callee operand: {{.*}} call i8 @return_i8 + ret void } define void @bad_indirect_calls(i32 %ptr) { %func1 = inttoptr i32 %ptr to void (i8)* +; CHECK: bad result type: %func1 call void %func1(i8 0) -; CHECK: Function bad_indirect_calls has instruction with disallowed type: void (i8)* +; CHECK: bad function callee operand: {{.*}} %func1 %func2 = inttoptr i32 %ptr to i16 ()* +; CHECK: bad result type: %func2 %result3 = call i16 %func2() -; CHECK: Function bad_indirect_calls has instruction with disallowed type: i16 ()* +; CHECK: bad function callee operand: {{.*}} %func2 ret void } diff --git a/test/NaCl/PNaClABI/abi-stripped-pointers.ll b/test/NaCl/PNaClABI/abi-stripped-pointers.ll new file mode 100644 index 0000000000..c994b7d009 --- /dev/null +++ b/test/NaCl/PNaClABI/abi-stripped-pointers.ll @@ -0,0 +1,131 @@ +; RUN: pnacl-abicheck < %s | FileCheck %s + +; This test checks that the PNaCl ABI verifier enforces the normal +; form introduced by the ReplacePtrsWithInts pass. + + +@var = global [4 x i8] c"xxxx" +@ptr = global i32 ptrtoint ([4 x i8]* @var to i32) + +declare i8* @llvm.nacl.read.tp() + + +define void @pointer_arg(i8* %arg) { + ret void +} +; CHECK: Function pointer_arg has disallowed type + +define i8* @pointer_return() { + unreachable +} +; CHECK-NEXT: Function pointer_return has disallowed type + +define void @func() { + ret void +} + +define void @func_with_arg(i32 %arg) { + ret void +} + + +define void @allowed_cases(i32 %arg) { + inttoptr i32 123 to i8* + + ptrtoint [4 x i8]* @var to i32 + + %alloc = alloca [1 x i8] + ptrtoint [1 x i8]* %alloc to i32 + + ; These instructions may use a NormalizedPtr, which may be a global. + load i32* @ptr + store i32 123, i32* @ptr + cmpxchg i32* @ptr, i32 1, i32 2 seq_cst + atomicrmw add i32* @ptr, i32 3 seq_cst + + ; A NormalizedPtr may be a bitcast. + %ptr_bitcast = bitcast [4 x i8]* @var to i32* + load i32* %ptr_bitcast + + ; A NormalizedPtr may be an inttoptr. + %ptr_from_int = inttoptr i32 123 to i32* + load i32* %ptr_from_int + + ; Check direct and indirect function calls. + %func_as_int = ptrtoint void ()* @func to i32 + %func_ptr = inttoptr i32 %func_as_int to void ()* + call void %func_ptr() + call void @func() + call void @func_with_arg(i32 123) + + ; Intrinsic calls may return pointers. + %thread_ptr = call i8* @llvm.nacl.read.tp() + ptrtoint i8* %thread_ptr to i32 + + ; Bitcasts between non-pointers are not restricted + bitcast i64 0 to double + bitcast i32 0 to float + + ; ConstantInts and Arguments are allowed as operands. + add i32 %arg, 123 + + ret void +} +; CHECK-NOT: disallowed + + +define void @bad_cases() { +entry: + ptrtoint [4 x i8]* @var to i16 +; CHECK: Function bad_cases disallowed: non-i32 ptrtoint + + inttoptr i16 123 to i8* +; CHECK-NEXT: non-i32 inttoptr + + %a = alloca i32 +; CHECK-NEXT: non-i8-array alloca + + store i32 0, i32* null +; CHECK-NEXT: bad pointer + + store i32 0, i32* undef +; CHECK-NEXT: bad pointer + + %bc = bitcast i32* @ptr to i31* +; CHECK-NEXT: bad result type + store i31 0, i31* %bc +; CHECK-NEXT: bad pointer + + ; Only one level of bitcasts is allowed. + %b = bitcast i32* %a to i8* + %c = bitcast i8* %b to i16* +; CHECK-NEXT: operand not InherentPtr + + br label %block +block: + %phi1 = phi i8* [ undef, %entry ] +; CHECK-NEXT: bad operand: %phi1 + %phi2 = phi i32* [ undef, %entry ] +; CHECK-NEXT: bad operand: %phi2 + + icmp eq i32* @ptr, @ptr +; CHECK-NEXT: bad operand: {{.*}} icmp + icmp eq void ()* @func, @func +; CHECK-NEXT: bad operand: {{.*}} icmp + icmp eq i31 0, 0 +; CHECK-NEXT: bad operand: {{.*}} icmp + + call void null() +; CHECK-NEXT: bad function callee operand + + call void @func_with_arg(i32 ptrtoint (i32* @ptr to i32)) +; CHECK-NEXT: bad operand + + ; Taking the address of an intrinsic is not allowed. + ptrtoint i8* ()* @llvm.nacl.read.tp to i32 +; CHECK-NEXT: operand not InherentPtr + + ret void +} + +; CHECK-NOT: disallowed diff --git a/test/NaCl/PNaClABI/abi-switch.ll b/test/NaCl/PNaClABI/abi-switch.ll new file mode 100644 index 0000000000..a3b5e631fc --- /dev/null +++ b/test/NaCl/PNaClABI/abi-switch.ll @@ -0,0 +1,31 @@ +; RUN: pnacl-abicheck < %s | FileCheck %s + +@var = global [4 x i8] c"xxxx" + + +; CHECK-NOT: disallowed + +define void @bad_cases() { + ; ConstantExprs should be rejected here. + switch i32 ptrtoint ([4 x i8]* @var to i32), label %next [i32 0, label %next] +; CHECK: disallowed: bad switch condition +next: + + ; Bad integer type. + switch i32 0, label %next [i99 0, label %next] +; CHECK: bad switch case + + ; Bad integer type. + switch i32 0, label %next [i32 0, label %next + i99 1, label %next] +; CHECK: bad switch case + + ; Note that the reader only allows ConstantInts in the label list. + ; We don't need to check the following, because the reader rejects + ; it: + ; switch i32 0, label %next [i32 ptrtoint (i32* @ptr to i32), label %next] + + ret void +} + +; CHECK-NOT: disallowed diff --git a/test/NaCl/PNaClABI/abi-varargs.ll b/test/NaCl/PNaClABI/abi-varargs.ll index 6eda0b9b53..dac94e00e0 100644 --- a/test/NaCl/PNaClABI/abi-varargs.ll +++ b/test/NaCl/PNaClABI/abi-varargs.ll @@ -10,4 +10,4 @@ define void @call_varargs_func(i32 %ptr) { call void (i32, ...)* %ptr2(i32 123) ret void } -; CHECK: Function call_varargs_func has instruction with disallowed type: void (i32, ...)* +; CHECK: Function call_varargs_func disallowed: bad function callee operand: call void (i32, ...)* diff --git a/test/NaCl/PNaClABI/instructions.ll b/test/NaCl/PNaClABI/instructions.ll index 0076c3d07c..57d1ec856b 100644 --- a/test/NaCl/PNaClABI/instructions.ll +++ b/test/NaCl/PNaClABI/instructions.ll @@ -1,6 +1,5 @@ ; RUN: pnacl-abicheck < %s | FileCheck %s ; Test instruction opcodes allowed by PNaCl ABI -; No testing yet of operands, types, attributes, etc target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32" target triple = "le32-unknown-nacl" @@ -15,7 +14,7 @@ next: next2: unreachable ; CHECK-NOT: disallowed -; CHECK: Function terminators has disallowed instruction: indirectbr +; CHECK: Function terminators disallowed: bad instruction opcode: indirectbr indirectbr i8* undef, [label %next, label %next2] } @@ -44,37 +43,43 @@ define void @binops() { define void @vectors() { ; CHECK-NOT: disallowed -; CHECK: Function vectors has disallowed instruction: extractelement + +; CHECK: disallowed: bad instruction opcode: {{.*}} extractelement %a1 = extractelement <2 x i32> <i32 0, i32 0>, i32 0 -; CHECK: Function vectors has disallowed instruction: shufflevector + +; CHECK: disallowed: bad instruction opcode: {{.*}} shufflevector %a2 = shufflevector <2 x i32> undef, <2 x i32> undef, <2 x i32> undef -; CHECK: Function vectors has disallowed instruction: insertelement -; CHECK: Function vectors has instruction with disallowed type -; CHECK: Function vectors has instruction operand with disallowed type + +; CHECK: disallowed: bad instruction opcode: {{.*}} insertelement %a3 = insertelement <2 x i32> undef, i32 1, i32 0 + ret void } define void @aggregates() { +; CHECK-NOT: disallowed + ; Aggregate operations %a1 = extractvalue { i32, i32 } { i32 0, i32 0 }, 0 -; CHECK-NOT: disallowed -; CHECK: Function aggregates has disallowed instruction: extractvalue +; CHECK: disallowed: bad instruction opcode: {{.*}} extractvalue + %a2 = insertvalue {i32, float} undef, i32 1, 0 -; CHECK-NEXT: Function aggregates has disallowed instruction: insertvalue +; CHECK-NEXT: disallowed: bad instruction opcode: {{.*}} insertvalue + ret void } define void @memory() { ; Memory operations - %a1 = alloca i32 - %a2 = load i32* undef - store i32 undef, i32* undef + %a1 = alloca [4 x i8] + %ptr = inttoptr i32 0 to i32* + %a2 = load i32* %ptr + store i32 undef, i32* %ptr fence acq_rel - %a3 = cmpxchg i32* undef, i32 undef, i32 undef acq_rel - %a4 = atomicrmw add i32* undef, i32 1 acquire + %a3 = cmpxchg i32* %ptr, i32 undef, i32 undef acq_rel + %a4 = atomicrmw add i32* %ptr, i32 1 acquire ; CHECK-NOT: disallowed -; CHECK: Function memory has disallowed instruction: getelementptr +; CHECK: disallowed: bad instruction opcode: {{.*}} getelementptr %a5 = getelementptr { i32, i32}* undef ret void } @@ -90,9 +95,6 @@ define void @conversion() { %a7 = fptosi double undef to i64 %a8 = uitofp i64 undef to double %a9 = sitofp i64 undef to double - %a10 = ptrtoint i8* undef to i32 - %a11 = inttoptr i32 undef to i8* - %a12 = bitcast i8* undef to i32* ret void } @@ -117,40 +119,41 @@ declare void @personality_func() define void @invoke_func() { invoke void @external_func() to label %ok unwind label %onerror ; CHECK-NOT: disallowed -; CHECK: Function invoke_func has disallowed instruction: invoke +; CHECK: disallowed: bad instruction opcode: invoke ok: ret void onerror: %lp = landingpad i32 personality i8* bitcast (void ()* @personality_func to i8*) catch i32* null -; CHECK-NEXT: Function invoke_func has disallowed instruction: landingpad -; CHECK-NEXT: Function invoke_func contains disallowed ConstantExpr +; CHECK: disallowed: bad instruction opcode: {{.*}} landingpad resume i32 %lp -; CHECK-NEXT: Function invoke_func has disallowed instruction: resume +; CHECK: disallowed: bad instruction opcode: resume } -define i32 @va_arg(i8* %va_list) { +define i32 @va_arg(i32 %va_list_as_int) { + %va_list = inttoptr i32 %va_list_as_int to i8* %val = va_arg i8* %va_list, i32 ret i32 %val } ; CHECK-NOT: disallowed -; CHECK: Function va_arg has disallowed instruction: va_arg +; CHECK: disallowed: bad instruction opcode: {{.*}} va_arg @global_var = global [4 x i8] zeroinitializer -define i8* @constantexpr() { - ret i8* getelementptr ([4 x i8]* @global_var, i32 1, i32 0) +define void @constantexpr() { + ptrtoint i8* getelementptr ([4 x i8]* @global_var, i32 1, i32 0) to i32 + ret void } ; CHECK-NOT: disallowed -; CHECK: Function constantexpr contains disallowed ConstantExpr +; CHECK: disallowed: operand not InherentPtr: %1 = ptrtoint i8* getelementptr define void @inline_asm() { call void asm "foo", ""() ret void } ; CHECK-NOT: disallowed -; CHECK: Function inline_asm contains disallowed inline assembly +; CHECK: disallowed: inline assembly: call void asm "foo", ""() ; CHECK-NOT: disallowed ; If another check is added, there should be a check-not in between each check diff --git a/test/NaCl/PNaClABI/types-function.ll b/test/NaCl/PNaClABI/types-function.ll index 32004d39ad..1482c727f0 100644 --- a/test/NaCl/PNaClABI/types-function.ll +++ b/test/NaCl/PNaClABI/types-function.ll @@ -4,22 +4,27 @@ ; stashed in various places in function bodies are caught. @a2 = private global i17 zeroinitializer + +; CHECK: Function func has disallowed type: void (i15) declare void @func(i15 %arg) !llvm.foo = !{!0} !0 = metadata !{ half 0.0} define void @types() { -; CHECK: Function types has instruction with disallowed type: half +; CHECK: bad result type: {{.*}} fptrunc %h1 = fptrunc double undef to half -; CHECK: Function types has instruction operand with disallowed type: half + +; CHECK: bad operand: {{.*}} bitcast half %h2 = bitcast half 0.0 to i16 + ; see below... %h3 = fadd double 0.0, fpext (half 0.0 to double) -; CHECK: Function types has instruction operand with disallowed type: i17* +; CHECK: bad pointer: store store i32 0, i32* bitcast (i17* @a2 to i32*), align 4 -; CHECK: Function types has instruction operand with disallowed type: i15 + +; CHECK: bad function callee operand: call void @func(i15 1) call void @func(i15 1) ; CHECK: Function types has disallowed instruction metadata: !foo diff --git a/test/NaCl/PNaClABI/types.ll b/test/NaCl/PNaClABI/types.ll index 7587609d11..b1527ec111 100644 --- a/test/NaCl/PNaClABI/types.ll +++ b/test/NaCl/PNaClABI/types.ll @@ -34,66 +34,59 @@ block: ; Disallowed integer types phi i4 [ undef, %entry ] -; CHECK: Function func has instruction with disallowed type: i4 +; CHECK: Function func disallowed: bad operand: {{.*}} i4 phi i33 [ undef, %entry ] -; CHECK: instruction with disallowed type: i33 +; CHECK-NEXT: disallowed: bad operand: {{.*}} i33 phi i128 [ undef, %entry ] -; CHECK: instruction with disallowed type: i128 +; CHECK-NEXT: disallowed: bad operand: {{.*}} i128 ; Disallowed floating point types phi half [ undef, %entry ] -; CHECK: instruction with disallowed type: half +; CHECK-NEXT: disallowed: bad operand: {{.*}} half phi x86_fp80 [ undef, %entry ] -; CHECK: instruction with disallowed type: x86_fp80 +; CHECK-NEXT: disallowed: bad operand: {{.*}} x86_fp80 phi fp128 [ undef, %entry ] -; CHECK: instruction with disallowed type: fp128 +; CHECK-NEXT: disallowed: bad operand: {{.*}} fp128 phi ppc_fp128 [ undef, %entry ] -; CHECK: instruction with disallowed type: ppc_fp128 +; CHECK-NEXT: disallowed: bad operand: {{.*}} ppc_fp128 phi x86_mmx [ undef, %entry ] -; CHECK: instruction with disallowed type: x86_mmx -; CHECK: instruction operand with disallowed type: x86_mmx +; CHECK-NEXT: disallowed: bad operand: {{.*}} x86_mmx - ; Derived types + ; Derived types are disallowed too - ; TODO(mseaborn): These are currently allowed but should be disallowed. phi i32* [ undef, %entry ] +; CHECK-NEXT: disallowed: bad operand: {{.*}} i32* + phi [1 x i32] [ undef, %entry ] +; CHECK-NEXT: disallowed: bad operand: {{.*}} [1 x i32] + phi { i32, float } [ undef, %entry ] +; CHECK-NEXT: disallowed: bad operand: {{.*}} { i32, float } + phi void (i32)* [ undef, %entry ] - phi <{ i8, i32 }> [ undef, %entry ] - phi { i32, { i32, double }, float } [ undef, %entry ] -; CHECK-NOT: disallowed +; CHECK-NEXT: disallowed: bad operand: {{.*}} void (i32)* - ; Derived types containing disallowed types - phi half* [ undef, %entry ] -; CHECK: instruction with disallowed type: half* - phi [2 x i33] [ undef, %entry ] -; CHECK: instruction with disallowed type: [2 x i33] - phi { half, i32 } [ undef, %entry ] -; CHECK: instruction with disallowed type: { half, i32 } - phi { float, i33 } [ undef, %entry ] -; CHECK: instruction with disallowed type: { float, i33 } - phi { i32, { i32, half }, float } [ undef, %entry ] -; CHECK: instruction with disallowed type: { i32, { i32, half }, float } + phi <{ i8, i32 }> [ undef, %entry ] +; CHECK-NEXT: disallowed: bad operand: {{.*}} <{ i8, i32 }> ; Vector types are disallowed phi <2 x i32> [ undef, %entry ] -; CHECK: instruction with disallowed type: <2 x i32> +; CHECK-NEXT: disallowed: bad operand: {{.*}} <2 x i32> ret void } -; named types. with the current implementation, bogus named types are legal +; Named types. With the current implementation, named types are legal ; until they are actually attempted to be used. Might want to fix that. %struct.s1 = type { half, float} %struct.s2 = type { i32, i32} @@ -104,11 +97,10 @@ entry: block: phi %struct.s1 [ undef, %entry ] -; CHECK: instruction with disallowed type: %struct.s1 = type { half, float } -; CHECK: instruction operand with disallowed type: %struct.s1 = type { half, float } +; CHECK: disallowed: bad operand: {{.*}} %struct.s1 phi %struct.s2 [ undef, %entry ] -; CHECK-NOT: disallowed +; CHECK-NEXT: disallowed: bad operand: {{.*}} %struct.s2 ret void } @@ -129,8 +121,10 @@ entry: block: phi %struct.snake [ undef, %entry ] +; CHECK: disallowed: bad operand: {{.*}} %struct.snake + phi %struct.linked [ undef, %entry ] -; CHECK-NOT: disallowed +; CHECK-NEXT: disallowed: bad operand: {{.*}} %struct.linked ret void } diff --git a/test/Transforms/NaCl/replace-ptrs-with-ints.ll b/test/Transforms/NaCl/replace-ptrs-with-ints.ll index 5a8f58dbaf..823697d738 100644 --- a/test/Transforms/NaCl/replace-ptrs-with-ints.ll +++ b/test/Transforms/NaCl/replace-ptrs-with-ints.ll @@ -202,6 +202,14 @@ define i16* @constant_pointer_null_load() { ; CHECK-NEXT: %.asptr = inttoptr i32 0 to i32* ; CHECK-NEXT: %val = load i32* %.asptr +define i16* @constant_pointer_undef_load() { + %val = load i16** undef + ret i16* %val +} +; CHECK: define i32 @constant_pointer_undef_load() { +; CHECK-NEXT: %.asptr = inttoptr i32 undef to i32* +; CHECK-NEXT: %val = load i32* %.asptr + define i8 @load(i8* %ptr) { %x = load i8* %ptr |