diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -1961,8 +1961,8 @@ protected: FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, - TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified, - ConstexprSpecKind ConstexprKind, + TypeSourceInfo *TInfo, StorageClass S, bool UsesFPIntrin, + bool isInlineSpecified, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause = nullptr); using redeclarable_base = Redeclarable; @@ -1996,23 +1996,23 @@ static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, - TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false, - bool hasWrittenPrototype = true, + TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin = false, + bool isInlineSpecified = false, bool hasWrittenPrototype = true, ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified, Expr *TrailingRequiresClause = nullptr) { DeclarationNameInfo NameInfo(N, NLoc); return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC, - isInlineSpecified, hasWrittenPrototype, - ConstexprKind, TrailingRequiresClause); + UsesFPIntrin, isInlineSpecified, + hasWrittenPrototype, ConstexprKind, + TrailingRequiresClause); } - static FunctionDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, QualType T, - TypeSourceInfo *TInfo, StorageClass SC, - bool isInlineSpecified, bool hasWrittenPrototype, - ConstexprSpecKind ConstexprKind, - Expr *TrailingRequiresClause); + static FunctionDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + StorageClass SC, bool UsesFPIntrin, bool isInlineSpecified, + bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind, + Expr *TrailingRequiresClause); static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2565,6 +2565,14 @@ FunctionDeclBits.IsInline = I; } + /// Determine whether the function was declared in source context + /// that requires constrained FP intrinsics + bool UsesFPIntrin() const { return FunctionDeclBits.UsesFPIntrin; } + + /// Set whether the function was declared in source context + /// that requires constrained FP intrinsics + void setUsesFPIntrin(bool I) { FunctionDeclBits.UsesFPIntrin = I; } + /// Flag that this function is implicitly inline. void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; } diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1854,7 +1854,7 @@ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, SourceLocation EndLocation) : FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo, - SC_None, false, ConstexprSpecKind::Unspecified), + SC_None, false, false, ConstexprSpecKind::Unspecified), ExplicitSpec(ES) { if (EndLocation.isValid()) setRangeEnd(EndLocation); @@ -1941,23 +1941,22 @@ CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass SC, - bool isInline, ConstexprSpecKind ConstexprKind, - SourceLocation EndLocation, + bool UsesFPIntrin, bool isInline, + ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr) - : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, isInline, - ConstexprKind, TrailingRequiresClause) { + : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin, + isInline, ConstexprKind, TrailingRequiresClause) { if (EndLocation.isValid()) setRangeEnd(EndLocation); } public: - static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, QualType T, - TypeSourceInfo *TInfo, StorageClass SC, - bool isInline, ConstexprSpecKind ConstexprKind, - SourceLocation EndLocation, - Expr *TrailingRequiresClause = nullptr); + static CXXMethodDecl * + Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + StorageClass SC, bool UsesFPIntrin, bool isInline, + ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, + Expr *TrailingRequiresClause = nullptr); static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2402,7 +2401,8 @@ CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, - TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool isInline, + TypeSourceInfo *TInfo, ExplicitSpecifier ES, + bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited, Expr *TrailingRequiresClause); @@ -2445,8 +2445,8 @@ static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, - ConstexprSpecKind ConstexprKind, + ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, + bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited = InheritedConstructor(), Expr *TrailingRequiresClause = nullptr); @@ -2665,12 +2665,12 @@ CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, - TypeSourceInfo *TInfo, bool isInline, + TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause = nullptr) : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, ConstexprKind, SourceLocation(), - TrailingRequiresClause) { + SC_None, UsesFPIntrin, isInline, ConstexprKind, + SourceLocation(), TrailingRequiresClause) { setImplicit(isImplicitlyDeclared); } @@ -2681,7 +2681,8 @@ SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isInline, bool isImplicitlyDeclared, + bool UsesFPIntrin, bool isInline, + bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause = nullptr); static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID); @@ -2725,7 +2726,7 @@ ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr) : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, ConstexprKind, EndLocation, + SC_None, false, isInline, ConstexprKind, EndLocation, TrailingRequiresClause), ExplicitSpec(ES) {} void anchor() override; diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3412,8 +3412,8 @@ return std::move(Err); if (GetImportedOrCreateDecl( ToFunction, D, Importer.getToContext(), cast(DC), - ToInnerLocStart, NameInfo, T, TInfo, ESpec, D->isInlineSpecified(), - D->isImplicit(), D->getConstexprKind(), + ToInnerLocStart, NameInfo, T, TInfo, ESpec, D->UsesFPIntrin(), + D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind(), InheritedConstructor(), // FIXME: Properly import inherited // constructor info TrailingRequiresClause)) @@ -3429,8 +3429,9 @@ if (GetImportedOrCreateDecl( ToFunction, D, Importer.getToContext(), cast(DC), - ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(), - D->isImplicit(), D->getConstexprKind(), TrailingRequiresClause)) + ToInnerLocStart, NameInfo, T, TInfo, D->UsesFPIntrin(), + D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind(), + TrailingRequiresClause)) return ToFunction; CXXDestructorDecl *ToDtor = cast(ToFunction); @@ -3451,8 +3452,8 @@ if (GetImportedOrCreateDecl( ToFunction, D, Importer.getToContext(), cast(DC), ToInnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(), - Method->isInlineSpecified(), D->getConstexprKind(), - SourceLocation(), TrailingRequiresClause)) + Method->UsesFPIntrin(), Method->isInlineSpecified(), + D->getConstexprKind(), SourceLocation(), TrailingRequiresClause)) return ToFunction; } else if (auto *Guide = dyn_cast(D)) { ExplicitSpecifier ESpec = @@ -3468,9 +3469,9 @@ } else { if (GetImportedOrCreateDecl( ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart, - NameInfo, T, TInfo, D->getStorageClass(), D->isInlineSpecified(), - D->hasWrittenPrototype(), D->getConstexprKind(), - TrailingRequiresClause)) + NameInfo, T, TInfo, D->getStorageClass(), D->UsesFPIntrin(), + D->isInlineSpecified(), D->hasWrittenPrototype(), + D->getConstexprKind(), TrailingRequiresClause)) return ToFunction; } diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2844,7 +2844,7 @@ SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass S, - bool isInlineSpecified, + bool UsesFPIntrin, bool isInlineSpecified, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause) : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, @@ -2870,7 +2870,7 @@ FunctionDeclBits.ConstexprKind = static_cast(ConstexprKind); FunctionDeclBits.InstantiationIsPending = false; FunctionDeclBits.UsesSEHTry = false; - FunctionDeclBits.UsesFPIntrin = false; + FunctionDeclBits.UsesFPIntrin = UsesFPIntrin; FunctionDeclBits.HasSkippedBody = false; FunctionDeclBits.WillHaveBody = false; FunctionDeclBits.IsMultiVersion = false; @@ -4842,18 +4842,16 @@ return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other); } -FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - StorageClass SC, bool isInlineSpecified, - bool hasWrittenPrototype, - ConstexprSpecKind ConstexprKind, - Expr *TrailingRequiresClause) { - FunctionDecl *New = - new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo, - SC, isInlineSpecified, ConstexprKind, - TrailingRequiresClause); +FunctionDecl * +FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin, + bool isInlineSpecified, bool hasWrittenPrototype, + ConstexprSpecKind ConstexprKind, + Expr *TrailingRequiresClause) { + FunctionDecl *New = new (C, DC) FunctionDecl( + Function, C, DC, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin, + isInlineSpecified, ConstexprKind, TrailingRequiresClause); New->setHasWrittenPrototype(hasWrittenPrototype); return New; } @@ -4861,7 +4859,7 @@ FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (C, ID) FunctionDecl( Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), - nullptr, SC_None, false, ConstexprSpecKind::Unspecified, nullptr); + nullptr, SC_None, false, false, ConstexprSpecKind::Unspecified, nullptr); } BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2190,25 +2190,23 @@ return FinalOverriders.size() == 1 ? FinalOverriders.front() : nullptr; } -CXXMethodDecl *CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - StorageClass SC, bool isInline, - ConstexprSpecKind ConstexprKind, - SourceLocation EndLocation, - Expr *TrailingRequiresClause) { - return new (C, RD) - CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo, T, TInfo, SC, - isInline, ConstexprKind, EndLocation, - TrailingRequiresClause); +CXXMethodDecl * +CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin, + bool isInline, ConstexprSpecKind ConstexprKind, + SourceLocation EndLocation, + Expr *TrailingRequiresClause) { + return new (C, RD) CXXMethodDecl( + CXXMethod, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin, + isInline, ConstexprKind, EndLocation, TrailingRequiresClause); } CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) - CXXMethodDecl(CXXMethod, C, nullptr, SourceLocation(), - DeclarationNameInfo(), QualType(), nullptr, SC_None, false, - ConstexprSpecKind::Unspecified, SourceLocation(), nullptr); + return new (C, ID) CXXMethodDecl( + CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(), + QualType(), nullptr, SC_None, false, false, + ConstexprSpecKind::Unspecified, SourceLocation(), nullptr); } CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base, @@ -2580,12 +2578,12 @@ CXXConstructorDecl::CXXConstructorDecl( ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, - ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited, - Expr *TrailingRequiresClause) + ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, + bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, + InheritedConstructor Inherited, Expr *TrailingRequiresClause) : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, ConstexprKind, SourceLocation(), - TrailingRequiresClause) { + SC_None, UsesFPIntrin, isInline, ConstexprKind, + SourceLocation(), TrailingRequiresClause) { setNumCtorInitializers(0); setInheritingConstructor(static_cast(Inherited)); setImplicit(isImplicitlyDeclared); @@ -2608,7 +2606,7 @@ isInheritingConstructor, hasTrailingExplicit); auto *Result = new (C, ID, Extra) CXXConstructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, - ExplicitSpecifier(), false, false, ConstexprSpecKind::Unspecified, + ExplicitSpecifier(), false, false, false, ConstexprSpecKind::Unspecified, InheritedConstructor(), nullptr); Result->setInheritingConstructor(isInheritingConstructor); Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier = @@ -2620,19 +2618,18 @@ CXXConstructorDecl *CXXConstructorDecl::Create( ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, - ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited, - Expr *TrailingRequiresClause) { + ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, + bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, + InheritedConstructor Inherited, Expr *TrailingRequiresClause) { assert(NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName && "Name must refer to a constructor"); unsigned Extra = additionalSizeToAlloc( Inherited ? 1 : 0, ES.getExpr() ? 1 : 0); - return new (C, RD, Extra) - CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, ES, isInline, - isImplicitlyDeclared, ConstexprKind, Inherited, - TrailingRequiresClause); + return new (C, RD, Extra) CXXConstructorDecl( + C, RD, StartLoc, NameInfo, T, TInfo, ES, UsesFPIntrin, isInline, + isImplicitlyDeclared, ConstexprKind, Inherited, TrailingRequiresClause); } CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() const { @@ -2749,20 +2746,20 @@ CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (C, ID) CXXDestructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, - false, false, ConstexprSpecKind::Unspecified, nullptr); + false, false, false, ConstexprSpecKind::Unspecified, nullptr); } CXXDestructorDecl *CXXDestructorDecl::Create( ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, - bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, - Expr *TrailingRequiresClause) { + bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, + ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause) { assert(NameInfo.getName().getNameKind() == DeclarationName::CXXDestructorName && "Name must refer to a destructor"); return new (C, RD) - CXXDestructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, isInline, - isImplicitlyDeclared, ConstexprKind, + CXXDestructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, UsesFPIntrin, + isInline, isImplicitlyDeclared, ConstexprKind, TrailingRequiresClause); } diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -1957,7 +1957,7 @@ FunctionDecl *FD = FunctionDecl::Create( C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, - FunctionTy, nullptr, SC_Static, false, false); + FunctionTy, nullptr, SC_Static, false, false, false); setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI, CGM); // This is necessary to avoid inheriting the previous line number. @@ -2151,7 +2151,7 @@ FunctionDecl *FD = FunctionDecl::Create( C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, - FunctionTy, nullptr, SC_Static, false, false); + FunctionTy, nullptr, SC_Static, false, false, false); setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI, CGM); @@ -2403,9 +2403,10 @@ ArgTys.push_back(Context.VoidPtrTy); QualType FunctionTy = Context.getFunctionType(ReturnTy, ArgTys, {}); - FunctionDecl *FD = FunctionDecl::Create( - Context, Context.getTranslationUnitDecl(), SourceLocation(), - SourceLocation(), II, FunctionTy, nullptr, SC_Static, false, false); + FunctionDecl *FD = + FunctionDecl::Create(Context, Context.getTranslationUnitDecl(), + SourceLocation(), SourceLocation(), II, FunctionTy, + nullptr, SC_Static, false, false, false); CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); @@ -2478,9 +2479,10 @@ ArgTys.push_back(Context.VoidPtrTy); QualType FunctionTy = Context.getFunctionType(R, ArgTys, {}); - FunctionDecl *FD = FunctionDecl::Create( - Context, Context.getTranslationUnitDecl(), SourceLocation(), - SourceLocation(), II, FunctionTy, nullptr, SC_Static, false, false); + FunctionDecl *FD = + FunctionDecl::Create(Context, Context.getTranslationUnitDecl(), + SourceLocation(), SourceLocation(), II, FunctionTy, + nullptr, SC_Static, false, false, false); CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1704,7 +1704,7 @@ IdentifierInfo *II = &Ctx.Idents.get(Name); FunctionDecl *FD = FunctionDecl::Create( Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, - FuncionTy, nullptr, SC_PrivateExtern, false, false); + FuncionTy, nullptr, SC_PrivateExtern, false, false, false); // Avoid generating debug location info for the function. FD->setImplicit(); diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -476,7 +476,7 @@ FunctionDecl *FD = FunctionDecl::Create( Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, Ctx.getFunctionType(Ctx.VoidTy, llvm::None, {}), nullptr, - SC_PrivateExtern, false, false); + SC_PrivateExtern, false, false, false); CodeGenFunction NewCGF(CGM); setCGF(&NewCGF); CGF->StartFunction(FD, Ctx.VoidTy, F, FI, Args); diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -3691,7 +3691,7 @@ FunctionDecl *FD = FunctionDecl::Create( C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, - FunctionTy, nullptr, SC_Static, false, false); + FunctionTy, nullptr, SC_Static, false, false, false); FunctionArgList args; ImplicitParamDecl DstDecl(C, FD, SourceLocation(), /*Id=*/nullptr, DestTy, @@ -3775,7 +3775,7 @@ FunctionDecl *FD = FunctionDecl::Create( C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, - FunctionTy, nullptr, SC_Static, false, false); + FunctionTy, nullptr, SC_Static, false, false, false); FunctionArgList args; ImplicitParamDecl DstDecl(C, FD, SourceLocation(), /*Id=*/nullptr, DestTy, diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -448,7 +448,8 @@ Ctx, Ctx.getTranslationUnitDecl(), FO.S->getBeginLoc(), SourceLocation(), DeclarationName(), FunctionTy, Ctx.getTrivialTypeSourceInfo(FunctionTy), SC_Static, - /*isInlineSpecified=*/false, /*hasWrittenPrototype=*/false); + /*UsesFPIntrin=*/false, /*isInlineSpecified=*/false, + /*hasWrittenPrototype=*/false); } for (const FieldDecl *FD : RD->fields()) { QualType ArgType = FD->getType(); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4575,9 +4575,6 @@ /// point operation, expressed as the maximum relative error in ulp. void SetFPAccuracy(llvm::Value *Val, float Accuracy); - /// SetFPModel - Control floating point behavior via fp-model settings. - void SetFPModel(); - /// Set the codegen fast-math flags. void SetFastMathFlags(FPOptions FPFeatures); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -77,7 +77,6 @@ CGM.getCXXABI().getMangleContext().startNewFunction(); SetFastMathFlags(CurFPFeatures); - SetFPModel(); } CodeGenFunction::~CodeGenFunction() { @@ -108,17 +107,6 @@ llvm_unreachable("Unsupported FP Exception Behavior"); } -void CodeGenFunction::SetFPModel() { - llvm::RoundingMode RM = getLangOpts().getFPRoundingMode(); - auto fpExceptionBehavior = ToConstrainedExceptMD( - getLangOpts().getFPExceptionMode()); - - Builder.setDefaultConstrainedRounding(RM); - Builder.setDefaultConstrainedExcept(fpExceptionBehavior); - Builder.setIsFPConstrained(fpExceptionBehavior != llvm::fp::ebIgnore || - RM != llvm::RoundingMode::NearestTiesToEven); -} - void CodeGenFunction::SetFastMathFlags(FPOptions FPFeatures) { llvm::FastMathFlags FMF; FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate()); @@ -709,9 +697,9 @@ DidCallStackSave = false; CurCodeDecl = D; - if (const auto *FD = dyn_cast_or_null(D)) - if (FD->usesSEHTry()) - CurSEHParent = FD; + const FunctionDecl *FD = dyn_cast_or_null(D); + if (FD && FD->usesSEHTry()) + CurSEHParent = FD; CurFuncDecl = (D ? D->getNonClosureContext() : nullptr); FnRetTy = RetTy; CurFn = Fn; @@ -793,10 +781,9 @@ // are not aware of how to move the extra UBSan instructions across the split // coroutine boundaries. if (D && SanOpts.has(SanitizerKind::Null)) - if (const auto *FD = dyn_cast(D)) - if (FD->getBody() && - FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass) - SanOpts.Mask &= ~SanitizerKind::Null; + if (FD && FD->getBody() && + FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass) + SanOpts.Mask &= ~SanitizerKind::Null; // Apply xray attributes to the function (as a string, for now) bool AlwaysXRayAttr = false; @@ -883,32 +870,29 @@ if (D && D->hasAttr()) Fn->addFnAttr("cfi-canonical-jump-table"); - if (getLangOpts().OpenCL) { + if (FD && getLangOpts().OpenCL) { // Add metadata for a kernel function. - if (const FunctionDecl *FD = dyn_cast_or_null(D)) - EmitOpenCLKernelMetadata(FD, Fn); + EmitOpenCLKernelMetadata(FD, Fn); } // If we are checking function types, emit a function type signature as // prologue data. - 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(ProtoTy, /*ForEH=*/true); - llvm::Constant *FTRTTIConstEncoded = - EncodeAddrForUseInPrologue(Fn, FTRTTIConst); - llvm::Constant *PrologueStructElems[] = {PrologueSig, - FTRTTIConstEncoded}; - llvm::Constant *PrologueStructConst = - llvm::ConstantStruct::getAnon(PrologueStructElems, /*Packed=*/true); - Fn->setPrologueData(PrologueStructConst); - } + if (FD && getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) { + 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(ProtoTy, /*ForEH=*/true); + llvm::Constant *FTRTTIConstEncoded = + EncodeAddrForUseInPrologue(Fn, FTRTTIConst); + llvm::Constant *PrologueStructElems[] = {PrologueSig, + FTRTTIConstEncoded}; + llvm::Constant *PrologueStructConst = + llvm::ConstantStruct::getAnon(PrologueStructElems, /*Packed=*/true); + Fn->setPrologueData(PrologueStructConst); } } @@ -935,25 +919,28 @@ // kernels cannot include RTTI information, exception classes, // recursive code, virtual functions or make use of C++ libraries that // are not compiled for the device. - if (const FunctionDecl *FD = dyn_cast_or_null(D)) { - if ((getLangOpts().CPlusPlus && FD->isMain()) || getLangOpts().OpenCL || - getLangOpts().SYCLIsDevice || - (getLangOpts().CUDA && FD->hasAttr())) - Fn->addFnAttr(llvm::Attribute::NoRecurse); - } + if (FD && ((getLangOpts().CPlusPlus && FD->isMain()) || + getLangOpts().OpenCL || getLangOpts().SYCLIsDevice || + (getLangOpts().CUDA && FD->hasAttr()))) + Fn->addFnAttr(llvm::Attribute::NoRecurse); - if (const FunctionDecl *FD = dyn_cast_or_null(D)) { - Builder.setIsFPConstrained(FD->hasAttr()); - if (FD->hasAttr()) - Fn->addFnAttr(llvm::Attribute::StrictFP); + llvm::RoundingMode RM = getLangOpts().getFPRoundingMode(); + auto fpExceptionBehavior = + ToConstrainedExceptMD(getLangOpts().getFPExceptionMode()); + Builder.setDefaultConstrainedRounding(RM); + Builder.setDefaultConstrainedExcept(fpExceptionBehavior); + if ((FD && (FD->UsesFPIntrin() || FD->hasAttr())) || + (!FD && (fpExceptionBehavior != llvm::fp::ebIgnore || + RM != llvm::RoundingMode::NearestTiesToEven))) { + Builder.setIsFPConstrained(true); + Fn->addFnAttr(llvm::Attribute::StrictFP); } // If a custom alignment is used, force realigning to this alignment on // any main function which certainly will need it. - if (const FunctionDecl *FD = dyn_cast_or_null(D)) - if ((FD->isMain() || FD->isMSVCRTEntryPoint()) && - CGM.getCodeGenOpts().StackAlignment) - Fn->addFnAttr("stackrealign"); + if (FD && ((FD->isMain() || FD->isMSVCRTEntryPoint()) && + CGM.getCodeGenOpts().StackAlignment)) + Fn->addFnAttr("stackrealign"); llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn); @@ -980,7 +967,7 @@ // such as 'this' and 'vtt', show up in the debug info. Preserve the calling // convention. CallingConv CC = CallingConv::CC_C; - if (auto *FD = dyn_cast_or_null(D)) + if (FD) if (const auto *SrcFnTy = FD->getType()->getAs()) CC = SrcFnTy->getCallConv(); SmallVector ArgTypes; diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -2615,9 +2615,10 @@ createGlobalInitOrCleanupFnDecl(CodeGen::CodeGenModule &CGM, StringRef FnName) { ASTContext &Ctx = CGM.getContext(); QualType FunctionTy = Ctx.getFunctionType(Ctx.VoidTy, llvm::None, {}); - return FunctionDecl::Create( - Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), - &Ctx.Idents.get(FnName), FunctionTy, nullptr, SC_Static, false, false); + return FunctionDecl::Create(Ctx, Ctx.getTranslationUnitDecl(), + SourceLocation(), SourceLocation(), + &Ctx.Idents.get(FnName), FunctionTy, nullptr, + SC_Static, false, false, false); } void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2061,8 +2061,9 @@ } FunctionDecl *New = FunctionDecl::Create(Context, Parent, Loc, Loc, II, Type, - /*TInfo=*/nullptr, SC_Extern, false, - Type->isFunctionProtoType()); + /*TInfo=*/nullptr, SC_Extern, + getCurFPFeatures().isFPConstrained(), + false, Type->isFunctionProtoType()); New->setImplicit(); New->addAttr(BuiltinAttr::CreateImplicit(Context, ID)); @@ -8493,10 +8494,11 @@ (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) || (!R->getAsAdjusted() && R->isFunctionProtoType()); - NewFD = FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), NameInfo, - R, TInfo, SC, isInline, HasPrototype, - ConstexprSpecKind::Unspecified, - /*TrailingRequiresClause=*/nullptr); + NewFD = FunctionDecl::Create( + SemaRef.Context, DC, D.getBeginLoc(), NameInfo, R, TInfo, SC, + SemaRef.getCurFPFeatures().isFPConstrained(), isInline, HasPrototype, + ConstexprSpecKind::Unspecified, + /*TrailingRequiresClause=*/nullptr); if (D.isInvalidType()) NewFD->setInvalidDecl(); @@ -8532,9 +8534,9 @@ R = SemaRef.CheckConstructorDeclarator(D, R, SC); return CXXConstructorDecl::Create( SemaRef.Context, cast(DC), D.getBeginLoc(), NameInfo, R, - TInfo, ExplicitSpecifier, isInline, - /*isImplicitlyDeclared=*/false, ConstexprKind, InheritedConstructor(), - TrailingRequiresClause); + TInfo, ExplicitSpecifier, SemaRef.getCurFPFeatures().isFPConstrained(), + isInline, /*isImplicitlyDeclared=*/false, ConstexprKind, + InheritedConstructor(), TrailingRequiresClause); } else if (Name.getNameKind() == DeclarationName::CXXDestructorName) { // This is a C++ destructor declaration. @@ -8543,7 +8545,8 @@ CXXRecordDecl *Record = cast(DC); CXXDestructorDecl *NewDD = CXXDestructorDecl::Create( SemaRef.Context, Record, D.getBeginLoc(), NameInfo, R, TInfo, - isInline, /*isImplicitlyDeclared=*/false, ConstexprKind, + SemaRef.getCurFPFeatures().isFPConstrained(), isInline, + /*isImplicitlyDeclared=*/false, ConstexprKind, TrailingRequiresClause); // If the destructor needs an implicit exception specification, set it @@ -8561,11 +8564,10 @@ // Create a FunctionDecl to satisfy the function definition parsing // code path. - return FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), - D.getIdentifierLoc(), Name, R, TInfo, SC, - isInline, - /*hasPrototype=*/true, ConstexprKind, - TrailingRequiresClause); + return FunctionDecl::Create( + SemaRef.Context, DC, D.getBeginLoc(), D.getIdentifierLoc(), Name, R, + TInfo, SC, SemaRef.getCurFPFeatures().isFPConstrained(), isInline, + /*hasPrototype=*/true, ConstexprKind, TrailingRequiresClause); } } else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) { @@ -8611,8 +8613,8 @@ // This is a C++ method declaration. CXXMethodDecl *Ret = CXXMethodDecl::Create( SemaRef.Context, cast(DC), D.getBeginLoc(), NameInfo, R, - TInfo, SC, isInline, ConstexprKind, SourceLocation(), - TrailingRequiresClause); + TInfo, SC, SemaRef.getCurFPFeatures().isFPConstrained(), isInline, + ConstexprKind, SourceLocation(), TrailingRequiresClause); IsVirtualOkay = !Ret->isStatic(); return Ret; } else { @@ -8624,9 +8626,10 @@ // Determine whether the function was written with a // prototype. This true when: // - we're in C++ (where every function has a prototype), - return FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), NameInfo, - R, TInfo, SC, isInline, true /*HasPrototype*/, - ConstexprKind, TrailingRequiresClause); + return FunctionDecl::Create( + SemaRef.Context, DC, D.getBeginLoc(), NameInfo, R, TInfo, SC, + SemaRef.getCurFPFeatures().isFPConstrained(), isInline, + true /*HasPrototype*/, ConstexprKind, TrailingRequiresClause); } } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -8459,8 +8459,9 @@ NewFD = FunctionDecl::Create( FD->getASTContext(), FD->getDeclContext(), Loc, Loc, DeclarationName(II), FD->getType(), FD->getTypeSourceInfo(), SC_None, - false /*isInlineSpecified*/, FD->hasPrototype(), - ConstexprSpecKind::Unspecified, FD->getTrailingRequiresClause()); + getCurFPFeatures().isFPConstrained(), false /*isInlineSpecified*/, + FD->hasPrototype(), ConstexprSpecKind::Unspecified, + FD->getTrailingRequiresClause()); NewD = NewFD; if (FD->getQualifier()) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -13027,6 +13027,7 @@ CXXConstructorDecl *DefaultCon = CXXConstructorDecl::Create( Context, ClassDecl, ClassLoc, NameInfo, /*Type*/ QualType(), /*TInfo=*/nullptr, ExplicitSpecifier(), + getCurFPFeatures().isFPConstrained(), /*isInline=*/true, /*isImplicitlyDeclared=*/true, Constexpr ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified); @@ -13148,7 +13149,8 @@ CXXConstructorDecl *DerivedCtor = CXXConstructorDecl::Create( Context, Derived, UsingLoc, NameInfo, TInfo->getType(), TInfo, - BaseCtor->getExplicitSpecifier(), /*isInline=*/true, + BaseCtor->getExplicitSpecifier(), getCurFPFeatures().isFPConstrained(), + /*isInline=*/true, /*isImplicitlyDeclared=*/true, Constexpr ? BaseCtor->getConstexprKind() : ConstexprSpecKind::Unspecified, InheritedConstructor(Shadow, BaseCtor), @@ -13305,7 +13307,9 @@ DeclarationNameInfo NameInfo(Name, ClassLoc); CXXDestructorDecl *Destructor = CXXDestructorDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, - QualType(), nullptr, /*isInline=*/true, + QualType(), nullptr, + getCurFPFeatures().isFPConstrained(), + /*isInline=*/true, /*isImplicitlyDeclared=*/true, Constexpr ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified); @@ -13943,6 +13947,7 @@ CXXMethodDecl *CopyAssignment = CXXMethodDecl::Create( Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr, /*StorageClass=*/SC_None, + getCurFPFeatures().isFPConstrained(), /*isInline=*/true, Constexpr ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified, SourceLocation()); @@ -14277,6 +14282,7 @@ CXXMethodDecl *MoveAssignment = CXXMethodDecl::Create( Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr, /*StorageClass=*/SC_None, + getCurFPFeatures().isFPConstrained(), /*isInline=*/true, Constexpr ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified, SourceLocation()); @@ -14659,7 +14665,7 @@ // member of its class. CXXConstructorDecl *CopyConstructor = CXXConstructorDecl::Create( Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr, - ExplicitSpecifier(), + ExplicitSpecifier(), getCurFPFeatures().isFPConstrained(), /*isInline=*/true, /*isImplicitlyDeclared=*/true, Constexpr ? ConstexprSpecKind::Constexpr @@ -14793,7 +14799,7 @@ // member of its class. CXXConstructorDecl *MoveConstructor = CXXConstructorDecl::Create( Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr, - ExplicitSpecifier(), + ExplicitSpecifier(), getCurFPFeatures().isFPConstrained(), /*isInline=*/true, /*isImplicitlyDeclared=*/true, Constexpr ? ConstexprSpecKind::Constexpr diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6196,14 +6196,12 @@ QualType OverloadTy = Context.getFunctionType(FT->getReturnType(), OverloadParams, EPI); DeclContext *Parent = FDecl->getParent(); - FunctionDecl *OverloadDecl = FunctionDecl::Create(Context, Parent, - FDecl->getLocation(), - FDecl->getLocation(), - FDecl->getIdentifier(), - OverloadTy, - /*TInfo=*/nullptr, - SC_Extern, false, - /*hasPrototype=*/true); + FunctionDecl *OverloadDecl = FunctionDecl::Create( + Context, Parent, FDecl->getLocation(), FDecl->getLocation(), + FDecl->getIdentifier(), OverloadTy, + /*TInfo=*/nullptr, SC_Extern, Sema->getCurFPFeatures().isFPConstrained(), + false, + /*hasPrototype=*/true); SmallVector Params; FT = cast(OverloadTy); for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { @@ -19332,7 +19330,8 @@ FunctionDecl *NewFD = FunctionDecl::Create( S.Context, FD->getDeclContext(), Loc, Loc, FD->getNameInfo().getName(), DestType, FD->getTypeSourceInfo(), - SC_None, false /*isInlineSpecified*/, FD->hasPrototype(), + SC_None, S.getCurFPFeatures().isFPConstrained(), + false /*isInlineSpecified*/, FD->hasPrototype(), /*ConstexprKind*/ ConstexprSpecKind::Unspecified); if (FD->getQualifier()) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -3039,8 +3039,9 @@ auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) { QualType FnType = Context.getFunctionType(Return, Params, EPI); FunctionDecl *Alloc = FunctionDecl::Create( - Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, - FnType, /*TInfo=*/nullptr, SC_None, false, true); + Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, FnType, + /*TInfo=*/nullptr, SC_None, getCurFPFeatures().isFPConstrained(), false, + true); Alloc->setImplicit(); // Global allocation functions should always be visible. Alloc->setVisibleDespiteOwningModule(); diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -392,7 +392,7 @@ Context, Class, EndLoc, DeclarationNameInfo(MethodName, IntroducerRange.getBegin(), MethodNameLoc), - MethodType, MethodTypeInfo, SC_None, + MethodType, MethodTypeInfo, SC_None, /*UsesFPIntrin*/ false, /*isInline=*/true, ConstexprKind, EndLoc, TrailingRequiresClause); Method->setAccess(AS_public); if (!TemplateParams) @@ -1483,7 +1483,7 @@ // to the new static invoker parameters - not the call operator's. CXXMethodDecl *Invoke = CXXMethodDecl::Create( S.Context, Class, Loc, DeclarationNameInfo(InvokerName, Loc), - InvokerFunctionTy, CallOperator->getTypeSourceInfo(), SC_Static, + InvokerFunctionTy, CallOperator->getTypeSourceInfo(), SC_Static, false, /*isInline=*/true, ConstexprSpecKind::Unspecified, CallOperator->getBody()->getEndLoc()); for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -859,7 +859,8 @@ for (const auto &FTy : FunctionList) { NewOpenCLBuiltin = FunctionDecl::Create( Context, Parent, Loc, Loc, II, FTy, /*TInfo=*/nullptr, SC_Extern, - false, FTy->isFunctionProtoType()); + S.getCurFPFeatures().isFPConstrained(), false, + FTy->isFunctionProtoType()); NewOpenCLBuiltin->setImplicit(); // Create Decl objects for each parameter, adding them to the diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1989,8 +1989,8 @@ } else { Function = FunctionDecl::Create( SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo, - D->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(), - D->hasWrittenPrototype(), D->getConstexprKind(), + D->getCanonicalDecl()->getStorageClass(), D->UsesFPIntrin(), + D->isInlineSpecified(), D->hasWrittenPrototype(), D->getConstexprKind(), TrailingRequiresClause); Function->setRangeEnd(D->getSourceRange().getEnd()); } @@ -2331,15 +2331,16 @@ if (CXXConstructorDecl *Constructor = dyn_cast(D)) { Method = CXXConstructorDecl::Create( SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, - InstantiatedExplicitSpecifier, Constructor->isInlineSpecified(), false, + InstantiatedExplicitSpecifier, Constructor->UsesFPIntrin(), + Constructor->isInlineSpecified(), false, Constructor->getConstexprKind(), InheritedConstructor(), TrailingRequiresClause); Method->setRangeEnd(Constructor->getEndLoc()); } else if (CXXDestructorDecl *Destructor = dyn_cast(D)) { Method = CXXDestructorDecl::Create( SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, - Destructor->isInlineSpecified(), false, Destructor->getConstexprKind(), - TrailingRequiresClause); + Destructor->UsesFPIntrin(), Destructor->isInlineSpecified(), false, + Destructor->getConstexprKind(), TrailingRequiresClause); Method->setRangeEnd(Destructor->getEndLoc()); } else if (CXXConversionDecl *Conversion = dyn_cast(D)) { Method = CXXConversionDecl::Create( @@ -2349,10 +2350,10 @@ TrailingRequiresClause); } else { StorageClass SC = D->isStatic() ? SC_Static : SC_None; - Method = CXXMethodDecl::Create(SemaRef.Context, Record, StartLoc, NameInfo, - T, TInfo, SC, D->isInlineSpecified(), - D->getConstexprKind(), D->getEndLoc(), - TrailingRequiresClause); + Method = CXXMethodDecl::Create( + SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SC, + D->UsesFPIntrin(), D->isInlineSpecified(), D->getConstexprKind(), + D->getEndLoc(), TrailingRequiresClause); } if (D->isInlined()) diff --git a/clang/test/CodeGen/fp-floatcontrol-class.cpp b/clang/test/CodeGen/fp-floatcontrol-class.cpp --- a/clang/test/CodeGen/fp-floatcontrol-class.cpp +++ b/clang/test/CodeGen/fp-floatcontrol-class.cpp @@ -8,13 +8,13 @@ class ON { float w = 2 + y() * z(); // CHECK-LABEL: define {{.*}} @_ZN2ONC2Ev{{.*}} - //CHECK: call float {{.*}}llvm.fmuladd + // CHECK: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict }; ON on; #pragma float_control(except, off) class OFF { float w = 2 + y() * z(); // CHECK-LABEL: define {{.*}} @_ZN3OFFC2Ev{{.*}} - //CHECK: call float {{.*}}llvm.fmuladd + // CHECK-NOT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict }; OFF off; diff --git a/clang/test/CodeGen/fp-floatcontrol-stack.cpp b/clang/test/CodeGen/fp-floatcontrol-stack.cpp --- a/clang/test/CodeGen/fp-floatcontrol-stack.cpp +++ b/clang/test/CodeGen/fp-floatcontrol-stack.cpp @@ -6,6 +6,10 @@ #define FUN(n) \ (float z) { return n * z + n; } +// CHECK-DDEFAULT Function Attrs: noinline nounwind optnone mustprogress +// CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone strictfp mustprogress +// CHECK-FAST: Function Attrs: noinline nounwind optnone mustprogress +// CHECK-NOHONOR Function Attrs: noinline nounwind optnone mustprogress float fun_default FUN(1) //CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}} #if DEFAULT @@ -28,6 +32,10 @@ // Rule: precise must be enabled #pragma float_control(except, on) #endif + // CHECK-FAST: Function Attrs: noinline nounwind optnone mustprogress + // CHECK-DDEFAULT Function Attrs: noinline nounwind optnone strictfp mustprogress + // CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone strictfp mustprogress + // CHECK-NOHONOR Function Attrs: noinline nounwind optnone strictfp mustprogress float exc_on FUN(2) //CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}} #if DEFAULT @@ -46,7 +54,11 @@ #endif #pragma float_control(pop) - float exc_pop FUN(5) + // CHECK-DDEFAULT Function Attrs: noinline nounwind optnone mustprogress + // CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone strictfp mustprogress + // CHECK-FAST: Function Attrs: noinline nounwind optnone mustprogress + // CHECK-NOHONOR Function Attrs: noinline nounwind optnone mustprogress + float exc_pop FUN(5) //CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}} #if DEFAULT //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}} @@ -63,7 +75,7 @@ #endif #pragma float_control(except, off) - float exc_off FUN(5) + float exc_off FUN(5) //CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}} #if DEFAULT //CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}} @@ -80,7 +92,7 @@ #endif #pragma float_control(precise, on, push) - float precise_on FUN(3) + float precise_on FUN(3) //CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}} #if DEFAULT //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}} @@ -97,7 +109,7 @@ #endif #pragma float_control(pop) - float precise_pop FUN(3) + float precise_pop FUN(3) //CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}} #if DEFAULT //CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}} @@ -113,7 +125,7 @@ //CHECK-FAST: fadd fast float #endif #pragma float_control(precise, off) - float precise_off FUN(4) + float precise_off FUN(4) //CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}} #if DEFAULT // Note: precise_off enables fp_contract=fast and the instructions @@ -137,7 +149,7 @@ #endif #pragma float_control(precise, on) - float precise_on2 FUN(3) + float precise_on2 FUN(3) //CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}} #if DEFAULT //CHECK-DDEFAULT: llvm.fmuladd{{.*}} @@ -154,7 +166,7 @@ #endif #pragma float_control(push) - float precise_push FUN(3) + float precise_push FUN(3) //CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}} #if DEFAULT //CHECK-DDEFAULT: llvm.fmuladd{{.*}} @@ -170,7 +182,7 @@ #endif #pragma float_control(precise, off) - float precise_off2 FUN(4) + float precise_off2 FUN(4) //CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}} #if DEFAULT //CHECK-DDEFAULT: fmul fast float @@ -191,7 +203,7 @@ #endif #pragma float_control(pop) - float precise_pop2 FUN(3) + float precise_pop2 FUN(3) //CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}} #if DEFAULT //CHECK-DDEFAULT: llvm.fmuladd{{.*}} @@ -210,27 +222,34 @@ // Rule: precise must be enabled #pragma float_control(except, on) #endif - float y(); + float y(); +// CHECK-DDEFAULT Function Attrs: noinline nounwind optnone mustprogress +// CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone strictfp mustprogress +// CHECK-FAST: Function Attrs: noinline nounwind optnone mustprogress +// CHECK-NOHONOR Function Attrs: noinline nounwind optnone mustprogress class ON { // Settings for top level class initializer use program source setting. float z = 2 + y() * 7; //CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}} #if DEFAULT -//CHECK-DDEFAULT: call float {{.*}}llvm.fmuladd +// CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict #endif #if EBSTRICT -//Currently, same as default [command line options not considered] -//CHECK-DEBSTRICT: call float {{.*}}llvm.fmuladd +// CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict #endif #if NOHONOR -//CHECK-NOHONOR: call float {{.*}}llvm.fmuladd +// CHECK-NOHONOR: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict #endif #if FAST -//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} +// CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} #endif }; ON on; #pragma float_control(except, off) +// CHECK-DDEFAULT Function Attrs: noinline nounwind optnone +// CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone +// CHECK-FAST: Function Attrs: noinline nounwind optnone +// CHECK-NOHONOR Function Attrs: noinline nounwind optnone class OFF { float w = 2 + y() * 7; //CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} @@ -259,3 +278,9 @@ MyComplex b (2, 4); return a + b; } + +// CHECK-DDEFAULT Function Attrs: noinline nounwind +// CHECK-DEBSTRICT Function Attrs: noinline nounwind strictfp +// CHECK-FAST: Function Attrs: noinline nounwind +// CHECK-NOHONOR Function Attrs: noinline nounwind +// CHECK-LABEL: define{{.*}} @_GLOBAL__sub_I_fp_floatcontrol_stack diff --git a/clang/unittests/Sema/ExternalSemaSourceTest.cpp b/clang/unittests/Sema/ExternalSemaSourceTest.cpp --- a/clang/unittests/Sema/ExternalSemaSourceTest.cpp +++ b/clang/unittests/Sema/ExternalSemaSourceTest.cpp @@ -163,7 +163,8 @@ CurrentSema->getPreprocessor().getIdentifierInfo(CorrectTo); auto *NewFunction = FunctionDecl::Create( Context, DestContext, SourceLocation(), SourceLocation(), ToIdent, - Context.getFunctionType(Context.VoidTy, {}, {}), nullptr, SC_Static); + Context.getFunctionType(Context.VoidTy, {}, {}), nullptr, SC_Static, + /*UsesFPIntrin*/ false); DestContext->addDecl(NewFunction); TypoCorrection Correction(ToIdent); Correction.addCorrectionDecl(NewFunction);