diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2018-01-05 07:57:24 +0000 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2018-01-05 07:57:24 +0000 |
commit | 51c8596650e147f0708f68887fd9f6247591920c (patch) | |
tree | 62434d4cbbba1c1f267f7c02bef710ea7024f2d7 /test/ubsan/TestCases | |
parent | 7eefa06560c53aee3da527c2c6d66e09e9f34323 (diff) |
o -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17
As discussed in the mail thread <https://groups.google.com/a/isocpp.org/forum/
#!topic/std-discussion/T64_dW3WKUk> "Calling noexcept function throug non-
noexcept pointer is undefined behavior?", such a call should not be UB.
However, Clang currently warns about it.
This change removes exception specifications from the function types recorded
for -fsanitize=function, both in the functions themselves and at the call sites.
That means that calling a non-noexcept function through a noexcept pointer will
also not be flagged as UB. In the review of this change, that was deemed
acceptable, at least for now. (See the "TODO" in compiler-rt
test/ubsan/TestCases/TypeCheck/Function/function.cpp.)
This is the compiler-rt part of a patch covering both cfe and compiler-rt.
Differential Revision: https://reviews.llvm.org/D40720
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@321860 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/ubsan/TestCases')
-rw-r--r-- | test/ubsan/TestCases/TypeCheck/Function/function.cpp | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/test/ubsan/TestCases/TypeCheck/Function/function.cpp b/test/ubsan/TestCases/TypeCheck/Function/function.cpp index 25b2bdc32..63d24a129 100644 --- a/test/ubsan/TestCases/TypeCheck/Function/function.cpp +++ b/test/ubsan/TestCases/TypeCheck/Function/function.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx -fsanitize=function %s -O3 -g -o %t +// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t // RUN: %run %t 2>&1 | FileCheck %s // Verify that we can disable symbolization if needed: // RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM @@ -23,9 +23,49 @@ void make_invalid_call() { reinterpret_cast<void (*)(int)>(reinterpret_cast<uintptr_t>(f))(42); } +void f1(int) {} +void f2(unsigned int) {} +void f3(int) noexcept {} +void f4(unsigned int) noexcept {} + +void check_noexcept_calls() { + void (*p1)(int); + p1 = &f1; + p1(0); + p1 = reinterpret_cast<void (*)(int)>(&f2); + // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int)' + // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)' + p1(0); + p1 = &f3; + p1(0); + p1 = reinterpret_cast<void (*)(int)>(&f4); + // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int)' + // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)' + p1(0); + + void (*p2)(int) noexcept; + p2 = reinterpret_cast<void (*)(int) noexcept>(&f1); + // TODO: Unclear whether calling a non-noexcept function through a pointer to + // nexcept function should cause an error. + // CHECK-NOT: function.cpp:[[@LINE+2]]:3: runtime error: call to function f1(int) through pointer to incorrect function type 'void (*)(int) noexcept' + // NOSYM-NOT: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept' + p2(0); + p2 = reinterpret_cast<void (*)(int) noexcept>(&f2); + // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept' + // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept' + p2(0); + p2 = &f3; + p2(0); + p2 = reinterpret_cast<void (*)(int) noexcept>(&f4); + // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept' + // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept' + p2(0); +} + int main(void) { make_valid_call(); make_invalid_call(); + check_noexcept_calls(); // Check that no more errors will be printed. // CHECK-NOT: runtime error: call to function // NOSYM-NOT: runtime error: call to function |