From 8c85bca5a5db8e84891d1cc849efb0773bddf71c Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Fri, 5 Jan 2018 07:57:12 +0000 Subject: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17 As discussed in the mail thread "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.) To remove exception specifications from types, the existing internal ASTContext::getFunctionTypeWithExceptionSpec was made public, and some places otherwise unrelated to this change have been adapted to call it, too. This is the cfe part of a patch covering both cfe and compiler-rt. Differential Revision: https://reviews.llvm.org/D40720 llvm-svn: 321859 --- clang/lib/CodeGen/CodeGenFunction.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp') diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 664b510..6fb21b1 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -924,8 +924,13 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) { if (const FunctionDecl *FD = dyn_cast_or_null(D)) { if (llvm::Constant *PrologueSig = getPrologueSignature(CGM, FD)) { + // Remove any (C++17) exception specifications, to allow calling e.g. a + // noexcept function through a non-noexcept pointer. + auto ProtoTy = + getContext().getFunctionTypeWithExceptionSpec(FD->getType(), + EST_None); llvm::Constant *FTRTTIConst = - CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true); + CGM.GetAddrOfRTTIDescriptor(ProtoTy, /*ForEH=*/true); llvm::Constant *FTRTTIConstEncoded = EncodeAddrForUseInPrologue(Fn, FTRTTIConst); llvm::Constant *PrologueStructElems[] = {PrologueSig, -- cgit v1.1