This revision was automatically updated to reflect the committed changes.
Closed by commit rC321859: No -fsanitize=function warning when calling noexcept
function through non… (authored by sberg, committed by ).
Changed prior to commit:
https://reviews.llvm.org/D40720?vs=128289&id=128710#toc
Repository:
rC Clang
https://reviews.llvm.org/D40720
Files:
include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/ItaniumCXXABI.cpp
lib/Sema/SemaOverload.cpp
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1162,6 +1162,13 @@
/// \brief Change the result type of a function type once it is deduced.
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
+ /// Get a function type and produce the equivalent function type with the
+ /// specified exception specification. Type sugar that can be present on a
+ /// declaration of a function with an exception specification is permitted
+ /// and preserved. Other type sugar (for instance, typedefs) is not.
+ QualType getFunctionTypeWithExceptionSpec(
+ QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI);
+
/// \brief Determine whether two function types are the same, ignoring
/// exception specifications in cases where they're part of the type.
bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U);
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -2582,44 +2582,42 @@
/// specified exception specification. Type sugar that can be present on a
/// declaration of a function with an exception specification is permitted
/// and preserved. Other type sugar (for instance, typedefs) is not.
-static QualType getFunctionTypeWithExceptionSpec(
- ASTContext &Context, QualType Orig,
- const FunctionProtoType::ExceptionSpecInfo &ESI) {
+QualType ASTContext::getFunctionTypeWithExceptionSpec(
+ QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) {
// Might have some parens.
if (auto *PT = dyn_cast<ParenType>(Orig))
- return Context.getParenType(
- getFunctionTypeWithExceptionSpec(Context, PT->getInnerType(), ESI));
+ return getParenType(
+ getFunctionTypeWithExceptionSpec(PT->getInnerType(), ESI));
// Might have a calling-convention attribute.
if (auto *AT = dyn_cast<AttributedType>(Orig))
- return Context.getAttributedType(
+ return getAttributedType(
AT->getAttrKind(),
- getFunctionTypeWithExceptionSpec(Context, AT->getModifiedType(), ESI),
- getFunctionTypeWithExceptionSpec(Context, AT->getEquivalentType(),
- ESI));
+ getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI),
+ getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI));
// Anything else must be a function type. Rebuild it with the new exception
// specification.
const FunctionProtoType *Proto = cast<FunctionProtoType>(Orig);
- return Context.getFunctionType(
+ return getFunctionType(
Proto->getReturnType(), Proto->getParamTypes(),
Proto->getExtProtoInfo().withExceptionSpec(ESI));
}
bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T,
QualType U) {
return hasSameType(T, U) ||
(getLangOpts().CPlusPlus17 &&
- hasSameType(getFunctionTypeWithExceptionSpec(*this, T, EST_None),
- getFunctionTypeWithExceptionSpec(*this, U, EST_None)));
+ hasSameType(getFunctionTypeWithExceptionSpec(T, EST_None),
+ getFunctionTypeWithExceptionSpec(U, EST_None)));
}
void ASTContext::adjustExceptionSpec(
FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI,
bool AsWritten) {
// Update the type.
QualType Updated =
- getFunctionTypeWithExceptionSpec(*this, FD->getType(), ESI);
+ getFunctionTypeWithExceptionSpec(FD->getType(), ESI);
FD->setType(Updated);
if (!AsWritten)
@@ -2630,7 +2628,7 @@
// If the type and the type-as-written differ, we may need to update
// the type-as-written too.
if (TSInfo->getType() != FD->getType())
- Updated = getFunctionTypeWithExceptionSpec(*this, TSInfo->getType(), ESI);
+ Updated = getFunctionTypeWithExceptionSpec(TSInfo->getType(), ESI);
// FIXME: When we get proper type location information for exceptions,
// we'll also have to rebuild the TypeSourceInfo. For now, we just patch
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -1475,10 +1475,8 @@
const auto *ToFPT = cast<FunctionProtoType>(ToFn);
if (FromFPT->isNothrow(Context) && !ToFPT->isNothrow(Context)) {
FromFn = cast<FunctionType>(
- Context.getFunctionType(FromFPT->getReturnType(),
- FromFPT->getParamTypes(),
- FromFPT->getExtProtoInfo().withExceptionSpec(
- FunctionProtoType::ExceptionSpecInfo()))
+ Context.getFunctionTypeWithExceptionSpec(QualType(FromFPT, 0),
+ EST_None)
.getTypePtr());
Changed = true;
}
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -924,8 +924,13 @@
if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) {
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(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,
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -3435,9 +3435,7 @@
if (auto *Proto = Type->getAs<FunctionProtoType>()) {
if (Proto->isNothrow(Ctx)) {
Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
- Type = Ctx.getFunctionType(
- Proto->getReturnType(), Proto->getParamTypes(),
- Proto->getExtProtoInfo().withExceptionSpec(EST_None));
+ Type = Ctx.getFunctionTypeWithExceptionSpec(Type, EST_None);
}
}
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -4479,18 +4479,21 @@
CalleeType = getContext().getCanonicalType(CalleeType);
- const auto *FnType =
- cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType());
+ auto PointeeType = cast<PointerType>(CalleeType)->getPointeeType();
CGCallee Callee = OrigCallee;
if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function) &&
(!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
if (llvm::Constant *PrefixSig =
CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
SanitizerScope SanScope(this);
+ // Remove any (C++17) exception specifications, to allow calling e.g. a
+ // noexcept function through a non-noexcept pointer.
+ auto ProtoTy =
+ getContext().getFunctionTypeWithExceptionSpec(PointeeType, EST_None);
llvm::Constant *FTRTTIConst =
- CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), /*ForEH=*/true);
+ CGM.GetAddrOfRTTIDescriptor(ProtoTy, /*ForEH=*/true);
llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), Int32Ty};
llvm::StructType *PrefixStructTy = llvm::StructType::get(
CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true);
@@ -4530,6 +4533,8 @@
}
}
+ const auto *FnType = cast<FunctionType>(PointeeType);
+
// If we are checking indirect calls and this call is indirect, check that the
// function pointer is a member of the bit set for the function type.
if (SanOpts.has(SanitizerKind::CFIICall) &&
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits