Skip to content

Commit d1c3780

Browse files
committedJun 23, 2017
[ubsan] Improve diagnostics for return value checks (compiler-rt)
Differential Revision: https://reviews.llvm.org/D34298 llvm-svn: 306164
1 parent c34d343 commit d1c3780

File tree

5 files changed

+57
-24
lines changed

5 files changed

+57
-24
lines changed
 

‎compiler-rt/lib/ubsan/ubsan_handlers.cc

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,12 @@ void __ubsan::__ubsan_handle_function_type_mismatch_abort(
473473
Die();
474474
}
475475

476-
static void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts,
477-
bool IsAttr) {
478-
SourceLocation Loc = Data->Loc.acquire();
476+
static void handleNonNullReturn(NonNullReturnData *Data, SourceLocation *LocPtr,
477+
ReportOptions Opts, bool IsAttr) {
478+
if (!LocPtr)
479+
UNREACHABLE("source location pointer is null!");
480+
481+
SourceLocation Loc = LocPtr->acquire();
479482
ErrorType ET = ErrorType::InvalidNullReturn;
480483

481484
if (ignoreReport(Loc, Opts, ET))
@@ -491,25 +494,29 @@ static void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts,
491494
: "_Nonnull return type annotation");
492495
}
493496

494-
void __ubsan::__ubsan_handle_nonnull_return(NonNullReturnData *Data) {
497+
void __ubsan::__ubsan_handle_nonnull_return_v1(NonNullReturnData *Data,
498+
SourceLocation *LocPtr) {
495499
GET_REPORT_OPTIONS(false);
496-
handleNonNullReturn(Data, Opts, true);
500+
handleNonNullReturn(Data, LocPtr, Opts, true);
497501
}
498502

499-
void __ubsan::__ubsan_handle_nonnull_return_abort(NonNullReturnData *Data) {
503+
void __ubsan::__ubsan_handle_nonnull_return_v1_abort(NonNullReturnData *Data,
504+
SourceLocation *LocPtr) {
500505
GET_REPORT_OPTIONS(true);
501-
handleNonNullReturn(Data, Opts, true);
506+
handleNonNullReturn(Data, LocPtr, Opts, true);
502507
Die();
503508
}
504509

505-
void __ubsan::__ubsan_handle_nullability_return(NonNullReturnData *Data) {
510+
void __ubsan::__ubsan_handle_nullability_return_v1(NonNullReturnData *Data,
511+
SourceLocation *LocPtr) {
506512
GET_REPORT_OPTIONS(false);
507-
handleNonNullReturn(Data, Opts, false);
513+
handleNonNullReturn(Data, LocPtr, Opts, false);
508514
}
509515

510-
void __ubsan::__ubsan_handle_nullability_return_abort(NonNullReturnData *Data) {
516+
void __ubsan::__ubsan_handle_nullability_return_v1_abort(
517+
NonNullReturnData *Data, SourceLocation *LocPtr) {
511518
GET_REPORT_OPTIONS(true);
512-
handleNonNullReturn(Data, Opts, false);
519+
handleNonNullReturn(Data, LocPtr, Opts, false);
513520
Die();
514521
}
515522

‎compiler-rt/lib/ubsan/ubsan_handlers.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,13 @@ RECOVERABLE(function_type_mismatch,
132132
ValueHandle Val)
133133

134134
struct NonNullReturnData {
135-
SourceLocation Loc;
136135
SourceLocation AttrLoc;
137136
};
138137

139138
/// \brief Handle returning null from function with the returns_nonnull
140139
/// attribute, or a return type annotated with _Nonnull.
141-
RECOVERABLE(nonnull_return, NonNullReturnData *Data)
142-
RECOVERABLE(nullability_return, NonNullReturnData *Data)
140+
RECOVERABLE(nonnull_return_v1, NonNullReturnData *Data, SourceLocation *Loc)
141+
RECOVERABLE(nullability_return_v1, NonNullReturnData *Data, SourceLocation *Loc)
143142

144143
struct NonNullArgData {
145144
SourceLocation Loc;

‎compiler-rt/lib/ubsan/ubsan_interface.inc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ INTERFACE_FUNCTION(__ubsan_handle_negate_overflow)
2828
INTERFACE_FUNCTION(__ubsan_handle_negate_overflow_abort)
2929
INTERFACE_FUNCTION(__ubsan_handle_nonnull_arg)
3030
INTERFACE_FUNCTION(__ubsan_handle_nonnull_arg_abort)
31-
INTERFACE_FUNCTION(__ubsan_handle_nonnull_return)
32-
INTERFACE_FUNCTION(__ubsan_handle_nonnull_return_abort)
31+
INTERFACE_FUNCTION(__ubsan_handle_nonnull_return_v1)
32+
INTERFACE_FUNCTION(__ubsan_handle_nonnull_return_v1_abort)
3333
INTERFACE_FUNCTION(__ubsan_handle_nullability_arg)
3434
INTERFACE_FUNCTION(__ubsan_handle_nullability_arg_abort)
35-
INTERFACE_FUNCTION(__ubsan_handle_nullability_return)
36-
INTERFACE_FUNCTION(__ubsan_handle_nullability_return_abort)
35+
INTERFACE_FUNCTION(__ubsan_handle_nullability_return_v1)
36+
INTERFACE_FUNCTION(__ubsan_handle_nullability_return_v1_abort)
3737
INTERFACE_FUNCTION(__ubsan_handle_out_of_bounds)
3838
INTERFACE_FUNCTION(__ubsan_handle_out_of_bounds_abort)
3939
INTERFACE_FUNCTION(__ubsan_handle_pointer_overflow)
Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,42 @@
1-
// RUN: %clangxx -fsanitize=returns-nonnull-attribute %s -O3 -o %t
2-
// RUN: %run %t foo
1+
// RUN: %clangxx -fsanitize=returns-nonnull-attribute -w %s -O3 -o %t
2+
// RUN: %run %t foo 2>&1 | count 0
33
// RUN: %run %t 2>&1 | FileCheck %s
4+
// RUN: %clangxx -fsanitize=returns-nonnull-attribute -fno-sanitize-recover=returns-nonnull-attribute -w %s -O3 -o %t.abort
5+
// RUN: not %run %t.abort &> /dev/null
46

57
__attribute__((returns_nonnull)) char *foo(char *a);
68

79
char *foo(char *a) {
10+
// CHECK: nonnull.cpp:[[@LINE+2]]:3: runtime error: null pointer returned from function declared to never return null
11+
// CHECK-NEXT: nonnull.cpp:[[@LINE-4]]:16: note: returns_nonnull attribute specified here
812
return a;
9-
// CHECK: nonnull.cpp:[[@LINE+2]]:1: runtime error: null pointer returned from function declared to never return null
10-
// CHECK-NEXT: nonnull.cpp:[[@LINE-5]]:16: note: returns_nonnull attribute specified here
13+
}
14+
15+
__attribute__((returns_nonnull)) char *bar(int x, char *a) {
16+
if (x > 10) {
17+
// CHECK: nonnull.cpp:[[@LINE+2]]:5: runtime error: null pointer returned from function declared to never return null
18+
// CHECK-NEXT: nonnull.cpp:[[@LINE-3]]:16: note: returns_nonnull attribute specified here
19+
return a;
20+
} else {
21+
// CHECK: nonnull.cpp:[[@LINE+2]]:5: runtime error: null pointer returned from function declared to never return null
22+
// CHECK-NEXT: nonnull.cpp:[[@LINE-7]]:16: note: returns_nonnull attribute specified here
23+
return a;
24+
}
1125
}
1226

1327
int main(int argc, char **argv) {
14-
return foo(argv[1]) == 0;
28+
char *a = argv[1];
29+
30+
foo(a);
31+
32+
bar(20, a);
33+
34+
// We expect to see a runtime error the first time we cover the "else"...
35+
bar(5, a);
36+
37+
// ... but not a second time.
38+
// CHECK-NOT: runtime error
39+
bar(5, a);
40+
41+
return 0;
1542
}

‎compiler-rt/test/ubsan/TestCases/Misc/nullability.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// RUN: %run %t foo 2>&1 | count 0
33
// RUN: %run %t 2>&1 | FileCheck %s
44

5-
// CHECK: nullability.c:[[@LINE+2]]:51: runtime error: null pointer returned from function declared to never return null
5+
// CHECK: nullability.c:[[@LINE+2]]:41: runtime error: null pointer returned from function declared to never return null
66
// CHECK-NEXT: nullability.c:[[@LINE+1]]:6: note: _Nonnull return type annotation specified here
77
int *_Nonnull nonnull_retval1(int *p) { return p; }
88

0 commit comments

Comments
 (0)
Please sign in to comment.