1 // N.B. The clang driver defaults to -fsanitize-merge but clang_cc1 effectively 2 // defaults to -fno-sanitize-merge. 3 // RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s 4 // RUN: %clang_cc1 -fsanitize=array-bounds -O -emit-llvm -triple x86_64-apple-darwin10 %s -o - | not FileCheck %s 5 // 6 // RUN: %clang_cc1 -fsanitize=local-bounds -fsanitize-trap=local-bounds -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s 7 // 8 // RUN: %clang_cc1 -fsanitize=local-bounds -fsanitize-trap=local-bounds -O3 -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s --check-prefixes=NOOPTLOCAL 9 // RUN: %clang_cc1 -fsanitize=local-bounds -fsanitize-trap=local-bounds -fno-sanitize-merge -O3 -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s --check-prefixes=NOOPTLOCAL 10 // RUN: %clang_cc1 -fsanitize=local-bounds -fsanitize-trap=local-bounds -fsanitize-merge=local-bounds -O3 -emit-llvm -triple x86_64-apple-darwin10 %s -o - | not FileCheck %s --check-prefixes=NOOPTLOCAL 11 // 12 // RUN: %clang_cc1 -fsanitize=array-bounds -fsanitize-trap=array-bounds -O3 -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s --check-prefixes=NOOPTARRAY 13 // RUN: %clang_cc1 -fsanitize=array-bounds -fsanitize-trap=array-bounds -fno-sanitize-merge -O3 -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s --check-prefixes=NOOPTARRAY 14 // RUN: %clang_cc1 -fsanitize=array-bounds -fsanitize-trap=array-bounds -fsanitize-merge=array-bounds -O3 -emit-llvm -triple x86_64-apple-darwin10 %s -o - | not FileCheck %s --check-prefixes=NOOPTARRAY 15 // 16 // REQUIRES: x86-registered-target 17 18 // CHECK-LABEL: @f1 19 double f1(int b, int i) { 20 double a[b]; 21 // CHECK: call {{.*}} @llvm.{{(ubsan)?trap}} 22 return a[i]; 23 } 24 25 // CHECK-LABEL: @f2 26 void f2(void) { 27 // everything is constant; no trap possible 28 // CHECK-NOT: call {{.*}} @llvm.{{(ubsan)?trap}} 29 int a[2]; 30 a[1] = 42; 31 32 #ifndef NO_DYNAMIC 33 extern void *malloc(__typeof__(sizeof(0))); 34 short *b = malloc(64); 35 b[5] = *a + a[1] + 2; 36 #endif 37 } 38 39 // CHECK-LABEL: @f3 40 void f3(void) { 41 int a[1]; 42 // CHECK: call {{.*}} @llvm.{{(ubsan)?trap}} 43 a[2] = 1; 44 } 45 46 // CHECK-LABEL: @f4 47 __attribute__((no_sanitize("bounds"))) 48 int f4(int i) { 49 int b[64]; 50 // CHECK-NOT: call void @llvm.trap() 51 // CHECK-NOT: trap: 52 // CHECK-NOT: cont: 53 return b[i]; 54 } 55 56 // Union flexible-array members are a C99 extension. All array members with a 57 // constant size should be considered FAMs. 58 59 union U { int a[0]; int b[1]; int c[2]; }; 60 61 // CHECK-LABEL: @f5 62 int f5(union U *u, int i) { 63 // a is treated as a flexible array member. 64 // CHECK-NOT: @llvm.ubsantrap 65 return u->a[i]; 66 } 67 68 // CHECK-LABEL: @f6 69 int f6(union U *u, int i) { 70 // b is treated as a flexible array member. 71 // CHECK-NOT: call {{.*}} @llvm.{{(ubsan)?trap}} 72 return u->b[i]; 73 } 74 75 // CHECK-LABEL: @f7 76 int f7(union U *u, int i) { 77 // c is treated as a flexible array member. 78 // CHECK-NOT: @llvm.ubsantrap 79 return u->c[i]; 80 } 81 82 char B[10]; 83 char B2[10]; 84 // CHECK-LABEL: @f8 85 // Check the label to prevent spuriously matching ubsantraps from other 86 // functions. 87 // NOOPTLOCAL-LABEL: @f8 88 // NOOPTARRAY-LABEL: @f8 89 void f8(int i, int k) { 90 // NOOPTLOCAL: call void @llvm.ubsantrap(i8 3) #[[ATTR1:[0-9]+]] 91 // NOOPTARRAY: call void @llvm.ubsantrap(i8 18) #[[ATTR2:[0-9]+]] 92 B[i] = '\0'; 93 94 // NOOPTLOCAL: call void @llvm.ubsantrap(i8 5) #[[ATTR1:[0-9]+]] 95 // NOOPTARRAY: call void @llvm.ubsantrap(i8 18) #[[ATTR2:[0-9]+]] 96 B2[k] = '\0'; 97 } 98 99 // See commit 9a954c6 that caused a SEGFAULT in this code. 100 struct S { 101 __builtin_va_list ap; 102 } *s; 103 // CHECK-LABEL: @f9 104 struct S *f9(int i) { 105 return &s[i]; 106 } 107 // NOOPTLOCAL: attributes #[[ATTR1]] = { nomerge noreturn nounwind } 108 // NOOPTARRAY: attributes #[[ATTR2]] = { nomerge noreturn nounwind } 109