45 lines · cpp
1// RUN: %clangxx -fsanitize=returns-nonnull-attribute -w %s -O3 -o %t2// RUN: %run %t foo 2>&1 | FileCheck %s --check-prefix=NOERROR --allow-empty --implicit-check-not='runtime error'3// RUN: %run %t 2>&1 | FileCheck %s4// RUN: %clangxx -fsanitize=returns-nonnull-attribute -fno-sanitize-recover=returns-nonnull-attribute -w %s -O3 -o %t.abort5// RUN: not %run %t.abort &> /dev/null6 7__attribute__((returns_nonnull)) char *foo(char *a);8 9char *foo(char *a) {10 // CHECK: nonnull.cpp:[[@LINE+2]]:3: runtime error: null pointer returned from function declared to never return null11 // CHECK-NEXT: nonnull.cpp:[[@LINE-4]]:16: note: returns_nonnull attribute specified here12 return a;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 null18 // CHECK-NEXT: nonnull.cpp:[[@LINE-3]]:16: note: returns_nonnull attribute specified here19 return a;20 } else {21 // CHECK: nonnull.cpp:[[@LINE+2]]:5: runtime error: null pointer returned from function declared to never return null22 // CHECK-NEXT: nonnull.cpp:[[@LINE-7]]:16: note: returns_nonnull attribute specified here23 return a;24 }25}26 27int main(int argc, char **argv) {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 error39 bar(5, a);40 41 return 0;42}43 44// NOERROR-NOT: runtime error45