[compiler-rt] r321860 - o -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

Stephan Bergmann via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 4 23:57:25 PST 2018


Author: sberg
Date: Thu Jan  4 23:57:24 2018
New Revision: 321860

URL: http://llvm.org/viewvc/llvm-project?rev=321860&view=rev
Log:
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

Modified:
    compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/Function/function.cpp

Modified: compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/Function/function.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/Function/function.cpp?rev=321860&r1=321859&r2=321860&view=diff
==============================================================================
--- compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/Function/function.cpp (original)
+++ compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/Function/function.cpp Thu Jan  4 23:57:24 2018
@@ -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




More information about the llvm-commits mailing list