Revert r320977 "No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17"
At least <http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-android/ builds/6013/steps/annotate/logs/stdio> complains about __ubsan::__ubsan_handle_function_type_mismatch_abort (compiler-rt lib/ubsan/ubsan_handlers.cc) returning now despite being declared 'noreturn', so looks like a different approach is needed for the function_type_mismatch check to be called also in cases that may ultimately succeed. llvm-svn: 320981
This commit is contained in:
parent
8ee540c01a
commit
2635ea6601
|
|
@ -18,9 +18,6 @@
|
|||
|
||||
#include "sanitizer_common/sanitizer_common.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <typeinfo>
|
||||
|
||||
using namespace __sanitizer;
|
||||
using namespace __ubsan;
|
||||
|
||||
|
|
@ -464,50 +461,14 @@ void __ubsan::__ubsan_handle_invalid_builtin_abort(InvalidBuiltinData *Data) {
|
|||
Die();
|
||||
}
|
||||
|
||||
// Check that TI2 represents the same function type as TI1, except that TI2 has
|
||||
// "noexcept" and TI1 does not.
|
||||
static bool checkForAddedNoexcept(const std::type_info *TI1,
|
||||
const std::type_info *TI2) {
|
||||
const char *Mangled1 = TI1->name();
|
||||
const char *Mangled2 = TI2->name();
|
||||
|
||||
// Skip <CV-qualifiers>.
|
||||
if (*Mangled1 == 'V') {
|
||||
if (*Mangled2 != 'V')
|
||||
return false;
|
||||
++Mangled1;
|
||||
++Mangled2;
|
||||
}
|
||||
if (*Mangled1 == 'K') {
|
||||
if (*Mangled2 != 'K')
|
||||
return false;
|
||||
++Mangled1;
|
||||
++Mangled2;
|
||||
}
|
||||
|
||||
// Check for "Do" <exception-spec>.
|
||||
if (*Mangled2++ != 'D' || *Mangled2++ != 'o')
|
||||
return false;
|
||||
|
||||
// Check remainder is identical.
|
||||
return std::strcmp(Mangled1, Mangled2) == 0;
|
||||
}
|
||||
|
||||
static bool handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
|
||||
ValueHandle Function, ValueHandle RTTI,
|
||||
static void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
|
||||
ValueHandle Function,
|
||||
ReportOptions Opts) {
|
||||
if (Data->NonNoexceptRTTI &&
|
||||
checkForAddedNoexcept(
|
||||
reinterpret_cast<std::type_info *>(Data->NonNoexceptRTTI),
|
||||
reinterpret_cast<std::type_info *>(RTTI))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SourceLocation CallLoc = Data->Loc.acquire();
|
||||
ErrorType ET = ErrorType::FunctionTypeMismatch;
|
||||
|
||||
if (ignoreReport(CallLoc, Opts, ET))
|
||||
return true;
|
||||
return;
|
||||
|
||||
ScopedReport R(Opts, CallLoc, ET);
|
||||
|
||||
|
|
@ -520,21 +481,20 @@ static bool handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
|
|||
"call to function %0 through pointer to incorrect function type %1")
|
||||
<< FName << Data->Type;
|
||||
Diag(FLoc, DL_Note, "%0 defined here") << FName;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
__ubsan::__ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data,
|
||||
ValueHandle Function, ValueHandle RTTI) {
|
||||
ValueHandle Function) {
|
||||
GET_REPORT_OPTIONS(false);
|
||||
handleFunctionTypeMismatch(Data, Function, RTTI, Opts);
|
||||
handleFunctionTypeMismatch(Data, Function, Opts);
|
||||
}
|
||||
|
||||
void __ubsan::__ubsan_handle_function_type_mismatch_abort(
|
||||
FunctionTypeMismatchData *Data, ValueHandle Function, ValueHandle RTTI) {
|
||||
FunctionTypeMismatchData *Data, ValueHandle Function) {
|
||||
GET_REPORT_OPTIONS(true);
|
||||
if (handleFunctionTypeMismatch(Data, Function, RTTI, Opts))
|
||||
Die();
|
||||
handleFunctionTypeMismatch(Data, Function, Opts);
|
||||
Die();
|
||||
}
|
||||
|
||||
static void handleNonNullReturn(NonNullReturnData *Data, SourceLocation *LocPtr,
|
||||
|
|
|
|||
|
|
@ -140,12 +140,11 @@ RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data)
|
|||
struct FunctionTypeMismatchData {
|
||||
SourceLocation Loc;
|
||||
const TypeDescriptor &Type;
|
||||
ValueHandle NonNoexceptRTTI;
|
||||
};
|
||||
|
||||
RECOVERABLE(function_type_mismatch,
|
||||
FunctionTypeMismatchData *Data,
|
||||
ValueHandle Val, ValueHandle RTTI)
|
||||
ValueHandle Val)
|
||||
|
||||
struct NonNullReturnData {
|
||||
SourceLocation AttrLoc;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t
|
||||
// RUN: %clangxx -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,47 +23,9 @@ 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);
|
||||
// CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f1(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 = 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
|
||||
|
|
|
|||
Loading…
Reference in New Issue