diff --git a/clang/test/CodeGen/bounds-checking.c b/clang/test/CodeGen/bounds-checking.c --- a/clang/test/CodeGen/bounds-checking.c +++ b/clang/test/CodeGen/bounds-checking.c @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -fsanitize=local-bounds -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s -// RUN: %clang_cc1 -fsanitize=local-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s -// RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s --check-prefixes=CHECK,NONLOCAL -// RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s --check-prefixes=CHECK,NONLOCAL +// RUN: %clang_cc1 -w -fsanitize=local-bounds -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s +// RUN: %clang_cc1 -w -fsanitize=local-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s +// RUN: %clang_cc1 -w -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s --check-prefixes=CHECK,NONLOCAL +// RUN: %clang_cc1 -w -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s --check-prefixes=CHECK,NONLOCAL // // REQUIRES: x86-registered-target @@ -49,3 +49,54 @@ return u->c[i]; // CHECK: } } + +struct S0 { + int t; + int a[0]; +}; + +// CHECK-LABEL: define {{.*}} @S0 +int S0(struct S0 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return s->a[i]; + // CHECK: } +} + +struct S1 { + int t; + int a[1]; +}; + +// CHECK-LABEL: define {{.*}} @S1 +int S1(struct S1 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return s->a[i]; + // CHECK: } +} + +struct S2 { + int t; + int a[2]; +}; + +// CHECK-LABEL: define {{.*}} @S2 +int S2(struct S2 *s, int i) { + // a and b are treated as flexible array members. + // NONLOCAL: call {{.*}} @llvm.trap + return s->a[i]; +} + +struct SFlex { + int t; + int a[]; +}; + +// CHECK-LABEL: define {{.*}} @SFlex +int SFlex(struct SFlex *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return s->a[i]; + // CHECK: } +} diff --git a/clang/test/CodeGen/bounds-checking.cpp b/clang/test/CodeGen/bounds-checking.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/bounds-checking.cpp @@ -0,0 +1,100 @@ +// RUN: %clang_cc1 -w -x c++ -fsanitize=local-bounds -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s +// RUN: %clang_cc1 -w -x c++ -fsanitize=local-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s +// RUN: %clang_cc1 -w -x c++ -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -fexperimental-new-pass-manager -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s --check-prefixes=CHECK,NONLOCAL +// +// REQUIRES: x86-registered-target + +// CHECK-LABEL: @_Z1f +double f(int b, int i) { + double a[b]; + // CHECK: call {{.*}} @llvm.trap + return a[i]; +} + +// CHECK-LABEL: @_Z2f2 +void f2() { + // everything is constant; no trap possible + // CHECK-NOT: call {{.*}} @llvm.trap + int a[2]; + a[1] = 42; +} + +// CHECK-LABEL: @_Z2f3 +void f3() { + int a[1]; + // CHECK: call {{.*}} @llvm.trap + a[2] = 1; +} + +union U { + int a[0]; + int b[1]; + int c[2]; +}; + +// CHECK-LABEL: define {{.*}} @_Z2f4 +int f4(union U *u, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return u->a[i] + u->b[i]; + // CHECK: } +} + +// CHECK-LABEL: define {{.*}} @_Z2f5 +int f5(union U *u, int i) { + // c is not a flexible array member. + // NONLOCAL: call {{.*}} @llvm.trap + return u->c[i]; + // CHECK: } +} + +struct S0 { + int t; + int a[0]; +}; + +// CHECK-LABEL: define {{.*}} @_Z2S0 +int S0(struct S0 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return s->a[i]; + // CHECK: } +} + +struct S1 { + int t; + int a[1]; +}; + +// CHECK-LABEL: define {{.*}} @_Z2S1 +int S1(struct S1 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return s->a[i]; + // CHECK: } +} + +struct S2 { + int t; + int a[2]; +}; + +// CHECK-LABEL: define {{.*}} @_Z2S2 +int S2(struct S2 *s, int i) { + // a and b are treated as flexible array members. + // NONLOCAL: call {{.*}} @llvm.trap + return s->a[i]; +} + +struct SFlex { + int t; + int a[]; +}; + +// CHECK-LABEL: define {{.*}} @_Z5SFlex +int SFlex(struct SFlex *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return s->a[i]; + // CHECK: } +}