Author: vedantk Date: Wed Apr 26 16:55:17 2017 New Revision: 301482 URL: http://llvm.org/viewvc/llvm-project?rev=301482&view=rev Log: [ubsan] nullability-assign: Check assignments into C++ structs
Fix the nullability-assign check so that it can handle assignments into C++ structs. Previously, such assignments were not instrumented. Testing: check-clang, check-ubsan, enabling the existing test in ObjC++ mode, and building some Apple frameworks with -fsanitize=nullability. Added: cfe/trunk/test/CodeGenCXX/ubsan-nullability-assign.cpp Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/test/CodeGenObjC/ubsan-nullability.m Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=301482&r1=301481&r2=301482&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Apr 26 16:55:17 2017 @@ -4065,6 +4065,8 @@ LValue CodeGenFunction::EmitBinaryOperat RValue RV = EmitAnyExpr(E->getRHS()); LValue LV = EmitCheckedLValue(E->getLHS(), TCK_Store); + if (RV.isScalar()) + EmitNullabilityCheck(LV, RV.getScalarVal(), E->getExprLoc()); EmitStoreThroughLValue(RV, LV); return LV; } Added: cfe/trunk/test/CodeGenCXX/ubsan-nullability-assign.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-nullability-assign.cpp?rev=301482&view=auto ============================================================================== --- cfe/trunk/test/CodeGenCXX/ubsan-nullability-assign.cpp (added) +++ cfe/trunk/test/CodeGenCXX/ubsan-nullability-assign.cpp Wed Apr 26 16:55:17 2017 @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=nullability-assign | FileCheck %s + +struct S1 { + int *_Nonnull p; +}; + +struct S2 { + S1 s1; +}; + +union U1 { + S1 s1; + S2 s2; +}; + +// CHECK-LABEL: define void @{{.*}}f1 +void f1(int *p) { + U1 u; + + // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize + // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_type_mismatch{{.*}} !nosanitize + // CHECK: store + u.s1.p = p; + + // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize + // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_type_mismatch{{.*}} !nosanitize + // CHECK: store + u.s2.s1.p = p; + + // CHECK-NOT: __ubsan_handle_type_mismatch + // CHECK-NOT: store + // CHECK: ret void +} Modified: cfe/trunk/test/CodeGenObjC/ubsan-nullability.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/ubsan-nullability.m?rev=301482&r1=301481&r2=301482&view=diff ============================================================================== --- cfe/trunk/test/CodeGenObjC/ubsan-nullability.m (original) +++ cfe/trunk/test/CodeGenObjC/ubsan-nullability.m Wed Apr 26 16:55:17 2017 @@ -1,19 +1,22 @@ // REQUIRES: asserts // RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s +// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s // CHECK: [[NONNULL_RV_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 109, i32 1 {{.*}} i32 100, i32 6 // CHECK: [[NONNULL_ARG_LOC:@.*]] = private unnamed_addr global {{.*}} i32 204, i32 15 {{.*}} i32 190, i32 23 // CHECK: [[NONNULL_ASSIGN1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 305, i32 9 // CHECK: [[NONNULL_ASSIGN2_LOC:@.*]] = private unnamed_addr global {{.*}} i32 405, i32 10 -// CHECK: [[NONNULL_ASSIGN3_LOC:@.*]] = private unnamed_addr global {{.*}} i32 505, i32 10 +// CHECK: [[NONNULL_ASSIGN3_LOC:@.*]] = private unnamed_addr global {{.*}} i32 506, i32 10 // CHECK: [[NONNULL_INIT1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 604, i32 25 // CHECK: [[NONNULL_INIT2_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 26 // CHECK: [[NONNULL_INIT2_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 29 // CHECK: [[NONNULL_RV_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 817, i32 1 {{.*}} i32 800, i32 6 #define NULL ((void *)0) +#define INULL ((int *)NULL) +#define INNULL ((int *_Nonnull)NULL) -// CHECK-LABEL: define i32* @nonnull_retval1 +// CHECK-LABEL: define i32* @{{.*}}nonnull_retval1 #line 100 int *_Nonnull nonnull_retval1(int *p) { // CHECK: br i1 true, label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize @@ -29,7 +32,7 @@ int *_Nonnull nonnull_retval1(int *p) { #line 190 void nonnull_arg(int *_Nonnull p) {} -// CHECK-LABEL: define void @call_func_with_nonnull_arg +// CHECK-LABEL: define void @{{.*}}call_func_with_nonnull_arg #line 200 void call_func_with_nonnull_arg(int *_Nonnull p) { // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize @@ -38,7 +41,7 @@ void call_func_with_nonnull_arg(int *_No nonnull_arg(p); } -// CHECK-LABEL: define void @nonnull_assign1 +// CHECK-LABEL: define void @{{.*}}nonnull_assign1 #line 300 void nonnull_assign1(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize @@ -48,7 +51,7 @@ void nonnull_assign1(int *p) { local = p; } -// CHECK-LABEL: define void @nonnull_assign2 +// CHECK-LABEL: define void @{{.*}}nonnull_assign2 #line 400 void nonnull_assign2(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize @@ -62,17 +65,18 @@ struct S1 { int *_Nonnull mptr; }; -// CHECK-LABEL: define void @nonnull_assign3 +// CHECK-LABEL: define void @{{.*}}nonnull_assign3 #line 500 void nonnull_assign3(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]] + // CHECK-NOT: call void @__ubsan_handle_type_mismatch struct S1 s; s.mptr = p; } -// CHECK-LABEL: define void @nonnull_init1 +// CHECK-LABEL: define void @{{.*}}nonnull_init1 #line 600 void nonnull_init1(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize @@ -81,7 +85,7 @@ void nonnull_init1(int *p) { int *_Nonnull local = p; } -// CHECK-LABEL: define void @nonnull_init2 +// CHECK-LABEL: define void @{{.*}}nonnull_init2 #line 700 void nonnull_init2(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize @@ -93,7 +97,7 @@ void nonnull_init2(int *p) { int *_Nonnull arr[] = {p, p}; } -// CHECK-LABEL: define i32* @nonnull_retval2 +// CHECK-LABEL: define i32* @{{.*}}nonnull_retval2 #line 800 int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this. int *_Nonnull arg2, //< Test this. @@ -150,7 +154,7 @@ int *_Nonnull nonnull_retval2(int *_Nonn } @end -// CHECK-LABEL: define void @call_A +// CHECK-LABEL: define void @{{.*}}call_A void call_A(A *a, int *p) { // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize @@ -168,15 +172,15 @@ void call_A(A *a, int *p) { void dont_crash(int *_Nonnull p, ...) {} int main() { - nonnull_retval1(NULL); - nonnull_retval2(NULL, NULL, NULL, NULL, 0, 0, 0, 0); - call_func_with_nonnull_arg(NULL); - nonnull_assign1(NULL); - nonnull_assign2(NULL); - nonnull_assign3(NULL); - nonnull_init1(NULL); - nonnull_init2(NULL); - call_A(NULL, NULL); - dont_crash(NULL, NULL); + nonnull_retval1(INULL); + nonnull_retval2(INNULL, INNULL, INULL, (int *_Nullable)NULL, 0, 0, 0, 0); + call_func_with_nonnull_arg(INNULL); + nonnull_assign1(INULL); + nonnull_assign2(INULL); + nonnull_assign3(INULL); + nonnull_init1(INULL); + nonnull_init2(INULL); + call_A((A *)NULL, INULL); + dont_crash(INNULL, NULL); return 0; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits