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 cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits