[clang][patch][FPEnv] Make initialization of C++ globals strictfp aware

@kpn pointed out that the global variable initialization functions didn't
have the "strictfp" metadata set correctly, and @rjmccall said that there
was buggy code in SetFPModel and StartFunction, this patch is to solve
those problems. When Sema creates a FunctionDecl, it sets the
FunctionDeclBits.UsesFPIntrin to "true" if the lexical FP settings
(i.e. a combination of command line options and #pragma float_control
settings) correspond to ConstrainedFP mode. That bit is used when CodeGen
starts codegen for a llvm function, and it translates into the
"strictfp" function attribute. See bugs.llvm.org/show_bug.cgi?id=44571

Reviewed By: Aaron Ballman

Differential Revision: https://reviews.llvm.org/D102343
This commit is contained in:
Melanie Blower 2021-07-29 12:02:20 -04:00
parent 4acc2f29a2
commit bc5b5ea037
20 changed files with 249 additions and 210 deletions

View File

@ -1990,8 +1990,8 @@ private:
protected: protected:
FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified, TypeSourceInfo *TInfo, StorageClass S, bool UsesFPIntrin,
ConstexprSpecKind ConstexprKind, bool isInlineSpecified, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr); Expr *TrailingRequiresClause = nullptr);
using redeclarable_base = Redeclarable<FunctionDecl>; using redeclarable_base = Redeclarable<FunctionDecl>;
@ -2025,22 +2025,22 @@ public:
static FunctionDecl * static FunctionDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation NLoc, DeclarationName N, QualType T, SourceLocation NLoc, DeclarationName N, QualType T,
TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin = false,
bool hasWrittenPrototype = true, bool isInlineSpecified = false, bool hasWrittenPrototype = true,
ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified, ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified,
Expr *TrailingRequiresClause = nullptr) { Expr *TrailingRequiresClause = nullptr) {
DeclarationNameInfo NameInfo(N, NLoc); DeclarationNameInfo NameInfo(N, NLoc);
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC, return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC,
isInlineSpecified, hasWrittenPrototype, UsesFPIntrin, isInlineSpecified,
ConstexprKind, TrailingRequiresClause); hasWrittenPrototype, ConstexprKind,
TrailingRequiresClause);
} }
static FunctionDecl *Create(ASTContext &C, DeclContext *DC, static FunctionDecl *
SourceLocation StartLoc, Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
TypeSourceInfo *TInfo, StorageClass SC, StorageClass SC, bool UsesFPIntrin, bool isInlineSpecified,
bool isInlineSpecified, bool hasWrittenPrototype, bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind,
ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause); Expr *TrailingRequiresClause);
static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@ -2594,6 +2594,14 @@ public:
FunctionDeclBits.IsInline = I; 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. /// Flag that this function is implicitly inline.
void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; } void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; }

View File

@ -1857,7 +1857,7 @@ private:
TypeSourceInfo *TInfo, SourceLocation EndLocation, TypeSourceInfo *TInfo, SourceLocation EndLocation,
CXXConstructorDecl *Ctor) CXXConstructorDecl *Ctor)
: FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo, : FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
SC_None, false, ConstexprSpecKind::Unspecified), SC_None, false, false, ConstexprSpecKind::Unspecified),
Ctor(Ctor), ExplicitSpec(ES) { Ctor(Ctor), ExplicitSpec(ES) {
if (EndLocation.isValid()) if (EndLocation.isValid())
setRangeEnd(EndLocation); setRangeEnd(EndLocation);
@ -1952,22 +1952,21 @@ protected:
CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD, CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo, StorageClass SC, QualType T, TypeSourceInfo *TInfo, StorageClass SC,
bool isInline, ConstexprSpecKind ConstexprKind, bool UsesFPIntrin, bool isInline,
SourceLocation EndLocation, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr) Expr *TrailingRequiresClause = nullptr)
: FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, isInline, : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
ConstexprKind, TrailingRequiresClause) { isInline, ConstexprKind, TrailingRequiresClause) {
if (EndLocation.isValid()) if (EndLocation.isValid())
setRangeEnd(EndLocation); setRangeEnd(EndLocation);
} }
public: public:
static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD, static CXXMethodDecl *
SourceLocation StartLoc, Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
TypeSourceInfo *TInfo, StorageClass SC, StorageClass SC, bool UsesFPIntrin, bool isInline,
bool isInline, ConstexprSpecKind ConstexprKind, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr); Expr *TrailingRequiresClause = nullptr);
static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@ -2413,7 +2412,8 @@ class CXXConstructorDecl final
CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool isInline, TypeSourceInfo *TInfo, ExplicitSpecifier ES,
bool UsesFPIntrin, bool isInline,
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
InheritedConstructor Inherited, InheritedConstructor Inherited,
Expr *TrailingRequiresClause); Expr *TrailingRequiresClause);
@ -2456,8 +2456,8 @@ public:
static CXXConstructorDecl * static CXXConstructorDecl *
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
ConstexprSpecKind ConstexprKind, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
InheritedConstructor Inherited = InheritedConstructor(), InheritedConstructor Inherited = InheritedConstructor(),
Expr *TrailingRequiresClause = nullptr); Expr *TrailingRequiresClause = nullptr);
@ -2676,23 +2676,22 @@ class CXXDestructorDecl : public CXXMethodDecl {
CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, bool isInline, TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr) Expr *TrailingRequiresClause = nullptr)
: CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo, : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, ConstexprKind, SourceLocation(), SC_None, UsesFPIntrin, isInline, ConstexprKind,
TrailingRequiresClause) { SourceLocation(), TrailingRequiresClause) {
setImplicit(isImplicitlyDeclared); setImplicit(isImplicitlyDeclared);
} }
void anchor() override; void anchor() override;
public: public:
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, static CXXDestructorDecl *
SourceLocation StartLoc, Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
QualType T, TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
bool isInline, bool isImplicitlyDeclared,
ConstexprSpecKind ConstexprKind, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr); Expr *TrailingRequiresClause = nullptr);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID); static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
@ -2732,12 +2731,13 @@ public:
class CXXConversionDecl : public CXXMethodDecl { class CXXConversionDecl : public CXXMethodDecl {
CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, bool isInline, ExplicitSpecifier ES, TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr) Expr *TrailingRequiresClause = nullptr)
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo, : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, ConstexprKind, EndLocation, SC_None, UsesFPIntrin, isInline, ConstexprKind,
TrailingRequiresClause), EndLocation, TrailingRequiresClause),
ExplicitSpec(ES) {} ExplicitSpec(ES) {}
void anchor() override; void anchor() override;
@ -2750,8 +2750,9 @@ public:
static CXXConversionDecl * static CXXConversionDecl *
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr);
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID); static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
ExplicitSpecifier getExplicitSpecifier() { ExplicitSpecifier getExplicitSpecifier() {

View File

@ -3461,8 +3461,8 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
return std::move(Err); return std::move(Err);
if (GetImportedOrCreateDecl<CXXConstructorDecl>( if (GetImportedOrCreateDecl<CXXConstructorDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC), ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
ToInnerLocStart, NameInfo, T, TInfo, ESpec, D->isInlineSpecified(), ToInnerLocStart, NameInfo, T, TInfo, ESpec, D->UsesFPIntrin(),
D->isImplicit(), D->getConstexprKind(), D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind(),
InheritedConstructor(), // FIXME: Properly import inherited InheritedConstructor(), // FIXME: Properly import inherited
// constructor info // constructor info
TrailingRequiresClause)) TrailingRequiresClause))
@ -3478,8 +3478,9 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (GetImportedOrCreateDecl<CXXDestructorDecl>( if (GetImportedOrCreateDecl<CXXDestructorDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC), ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(), ToInnerLocStart, NameInfo, T, TInfo, D->UsesFPIntrin(),
D->isImplicit(), D->getConstexprKind(), TrailingRequiresClause)) D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind(),
TrailingRequiresClause))
return ToFunction; return ToFunction;
CXXDestructorDecl *ToDtor = cast<CXXDestructorDecl>(ToFunction); CXXDestructorDecl *ToDtor = cast<CXXDestructorDecl>(ToFunction);
@ -3493,15 +3494,16 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
return std::move(Err); return std::move(Err);
if (GetImportedOrCreateDecl<CXXConversionDecl>( if (GetImportedOrCreateDecl<CXXConversionDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC), ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(), ESpec, ToInnerLocStart, NameInfo, T, TInfo, D->UsesFPIntrin(),
D->getConstexprKind(), SourceLocation(), TrailingRequiresClause)) D->isInlineSpecified(), ESpec, D->getConstexprKind(),
SourceLocation(), TrailingRequiresClause))
return ToFunction; return ToFunction;
} else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) { } else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) {
if (GetImportedOrCreateDecl<CXXMethodDecl>( if (GetImportedOrCreateDecl<CXXMethodDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC), ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
ToInnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(), ToInnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(),
Method->isInlineSpecified(), D->getConstexprKind(), Method->UsesFPIntrin(), Method->isInlineSpecified(),
SourceLocation(), TrailingRequiresClause)) D->getConstexprKind(), SourceLocation(), TrailingRequiresClause))
return ToFunction; return ToFunction;
} else if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) { } else if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
ExplicitSpecifier ESpec = ExplicitSpecifier ESpec =
@ -3519,9 +3521,9 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
} else { } else {
if (GetImportedOrCreateDecl( if (GetImportedOrCreateDecl(
ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart, ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart,
NameInfo, T, TInfo, D->getStorageClass(), D->isInlineSpecified(), NameInfo, T, TInfo, D->getStorageClass(), D->UsesFPIntrin(),
D->hasWrittenPrototype(), D->getConstexprKind(), D->isInlineSpecified(), D->hasWrittenPrototype(),
TrailingRequiresClause)) D->getConstexprKind(), TrailingRequiresClause))
return ToFunction; return ToFunction;
} }

View File

@ -2852,7 +2852,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, StorageClass S, TypeSourceInfo *TInfo, StorageClass S,
bool isInlineSpecified, bool UsesFPIntrin, bool isInlineSpecified,
ConstexprSpecKind ConstexprKind, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause) Expr *TrailingRequiresClause)
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
@ -2878,7 +2878,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
FunctionDeclBits.ConstexprKind = static_cast<uint64_t>(ConstexprKind); FunctionDeclBits.ConstexprKind = static_cast<uint64_t>(ConstexprKind);
FunctionDeclBits.InstantiationIsPending = false; FunctionDeclBits.InstantiationIsPending = false;
FunctionDeclBits.UsesSEHTry = false; FunctionDeclBits.UsesSEHTry = false;
FunctionDeclBits.UsesFPIntrin = false; FunctionDeclBits.UsesFPIntrin = UsesFPIntrin;
FunctionDeclBits.HasSkippedBody = false; FunctionDeclBits.HasSkippedBody = false;
FunctionDeclBits.WillHaveBody = false; FunctionDeclBits.WillHaveBody = false;
FunctionDeclBits.IsMultiVersion = false; FunctionDeclBits.IsMultiVersion = false;
@ -4857,18 +4857,16 @@ ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C,
return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other); return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other);
} }
FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, FunctionDecl *
SourceLocation StartLoc, FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, const DeclarationNameInfo &NameInfo, QualType T,
QualType T, TypeSourceInfo *TInfo, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin,
StorageClass SC, bool isInlineSpecified, bool isInlineSpecified, bool hasWrittenPrototype,
bool hasWrittenPrototype,
ConstexprSpecKind ConstexprKind, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause) { Expr *TrailingRequiresClause) {
FunctionDecl *New = FunctionDecl *New = new (C, DC) FunctionDecl(
new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo, Function, C, DC, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
SC, isInlineSpecified, ConstexprKind, isInlineSpecified, ConstexprKind, TrailingRequiresClause);
TrailingRequiresClause);
New->setHasWrittenPrototype(hasWrittenPrototype); New->setHasWrittenPrototype(hasWrittenPrototype);
return New; return New;
} }
@ -4876,7 +4874,7 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) FunctionDecl( return new (C, ID) FunctionDecl(
Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), 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) { BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {

View File

@ -2178,24 +2178,22 @@ CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
return FinalOverriders.size() == 1 ? FinalOverriders.front() : nullptr; return FinalOverriders.size() == 1 ? FinalOverriders.front() : nullptr;
} }
CXXMethodDecl *CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, CXXMethodDecl *
SourceLocation StartLoc, CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, const DeclarationNameInfo &NameInfo, QualType T,
QualType T, TypeSourceInfo *TInfo, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin,
StorageClass SC, bool isInline, bool isInline, ConstexprSpecKind ConstexprKind,
ConstexprSpecKind ConstexprKind,
SourceLocation EndLocation, SourceLocation EndLocation,
Expr *TrailingRequiresClause) { Expr *TrailingRequiresClause) {
return new (C, RD) return new (C, RD) CXXMethodDecl(
CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo, T, TInfo, SC, CXXMethod, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
isInline, ConstexprKind, EndLocation, isInline, ConstexprKind, EndLocation, TrailingRequiresClause);
TrailingRequiresClause);
} }
CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) { CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) return new (C, ID) CXXMethodDecl(
CXXMethodDecl(CXXMethod, C, nullptr, SourceLocation(), CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(),
DeclarationNameInfo(), QualType(), nullptr, SC_None, false, QualType(), nullptr, SC_None, false, false,
ConstexprSpecKind::Unspecified, SourceLocation(), nullptr); ConstexprSpecKind::Unspecified, SourceLocation(), nullptr);
} }
@ -2568,12 +2566,12 @@ SourceRange CXXCtorInitializer::getSourceRange() const {
CXXConstructorDecl::CXXConstructorDecl( CXXConstructorDecl::CXXConstructorDecl(
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause) InheritedConstructor Inherited, Expr *TrailingRequiresClause)
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, ConstexprKind, SourceLocation(), SC_None, UsesFPIntrin, isInline, ConstexprKind,
TrailingRequiresClause) { SourceLocation(), TrailingRequiresClause) {
setNumCtorInitializers(0); setNumCtorInitializers(0);
setInheritingConstructor(static_cast<bool>(Inherited)); setInheritingConstructor(static_cast<bool>(Inherited));
setImplicit(isImplicitlyDeclared); setImplicit(isImplicitlyDeclared);
@ -2596,7 +2594,7 @@ CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C,
isInheritingConstructor, hasTrailingExplicit); isInheritingConstructor, hasTrailingExplicit);
auto *Result = new (C, ID, Extra) CXXConstructorDecl( auto *Result = new (C, ID, Extra) CXXConstructorDecl(
C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
ExplicitSpecifier(), false, false, ConstexprSpecKind::Unspecified, ExplicitSpecifier(), false, false, false, ConstexprSpecKind::Unspecified,
InheritedConstructor(), nullptr); InheritedConstructor(), nullptr);
Result->setInheritingConstructor(isInheritingConstructor); Result->setInheritingConstructor(isInheritingConstructor);
Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier = Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier =
@ -2608,19 +2606,18 @@ CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C,
CXXConstructorDecl *CXXConstructorDecl::Create( CXXConstructorDecl *CXXConstructorDecl::Create(
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause) { InheritedConstructor Inherited, Expr *TrailingRequiresClause) {
assert(NameInfo.getName().getNameKind() assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXConstructorName && == DeclarationName::CXXConstructorName &&
"Name must refer to a constructor"); "Name must refer to a constructor");
unsigned Extra = unsigned Extra =
additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>( additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>(
Inherited ? 1 : 0, ES.getExpr() ? 1 : 0); Inherited ? 1 : 0, ES.getExpr() ? 1 : 0);
return new (C, RD, Extra) return new (C, RD, Extra) CXXConstructorDecl(
CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, ES, isInline, C, RD, StartLoc, NameInfo, T, TInfo, ES, UsesFPIntrin, isInline,
isImplicitlyDeclared, ConstexprKind, Inherited, isImplicitlyDeclared, ConstexprKind, Inherited, TrailingRequiresClause);
TrailingRequiresClause);
} }
CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() const { CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() const {
@ -2737,21 +2734,20 @@ CXXDestructorDecl *
CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) { CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) CXXDestructorDecl( return new (C, ID) CXXDestructorDecl(
C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
false, false, ConstexprSpecKind::Unspecified, nullptr); false, false, false, ConstexprSpecKind::Unspecified, nullptr);
} }
CXXDestructorDecl *CXXDestructorDecl::Create( CXXDestructorDecl *CXXDestructorDecl::Create(
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
Expr *TrailingRequiresClause) { ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause) {
assert(NameInfo.getName().getNameKind() assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXDestructorName && == DeclarationName::CXXDestructorName &&
"Name must refer to a destructor"); "Name must refer to a destructor");
return new (C, RD) return new (C, RD) CXXDestructorDecl(
CXXDestructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, isInline, C, RD, StartLoc, NameInfo, T, TInfo, UsesFPIntrin, isInline,
isImplicitlyDeclared, ConstexprKind, isImplicitlyDeclared, ConstexprKind, TrailingRequiresClause);
TrailingRequiresClause);
} }
void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) { void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) {
@ -2770,20 +2766,21 @@ CXXConversionDecl *
CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) CXXConversionDecl( return new (C, ID) CXXConversionDecl(
C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified, false, false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified,
SourceLocation(), nullptr); SourceLocation(), nullptr);
} }
CXXConversionDecl *CXXConversionDecl::Create( CXXConversionDecl *CXXConversionDecl::Create(
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
SourceLocation EndLocation, Expr *TrailingRequiresClause) { ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
Expr *TrailingRequiresClause) {
assert(NameInfo.getName().getNameKind() assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXConversionFunctionName && == DeclarationName::CXXConversionFunctionName &&
"Name must refer to a conversion function"); "Name must refer to a conversion function");
return new (C, RD) return new (C, RD) CXXConversionDecl(
CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo, isInline, ES, C, RD, StartLoc, NameInfo, T, TInfo, UsesFPIntrin, isInline, ES,
ConstexprKind, EndLocation, TrailingRequiresClause); ConstexprKind, EndLocation, TrailingRequiresClause);
} }

View File

@ -3697,7 +3697,7 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
FunctionDecl *FD = FunctionDecl::Create( FunctionDecl *FD = FunctionDecl::Create(
C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
FunctionTy, nullptr, SC_Static, false, false); FunctionTy, nullptr, SC_Static, false, false, false);
FunctionArgList args; FunctionArgList args;
ParmVarDecl *Params[2]; ParmVarDecl *Params[2];
@ -3787,7 +3787,7 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
FunctionDecl *FD = FunctionDecl::Create( FunctionDecl *FD = FunctionDecl::Create(
C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
FunctionTy, nullptr, SC_Static, false, false); FunctionTy, nullptr, SC_Static, false, false, false);
FunctionArgList args; FunctionArgList args;
ParmVarDecl *Params[2]; ParmVarDecl *Params[2];

View File

@ -450,7 +450,8 @@ static llvm::Function *emitOutlinedFunctionPrologue(
Ctx, Ctx.getTranslationUnitDecl(), FO.S->getBeginLoc(), Ctx, Ctx.getTranslationUnitDecl(), FO.S->getBeginLoc(),
SourceLocation(), DeclarationName(), FunctionTy, SourceLocation(), DeclarationName(), FunctionTy,
Ctx.getTrivialTypeSourceInfo(FunctionTy), SC_Static, Ctx.getTrivialTypeSourceInfo(FunctionTy), SC_Static,
/*isInlineSpecified=*/false, /*hasWrittenPrototype=*/false); /*UsesFPIntrin=*/false, /*isInlineSpecified=*/false,
/*hasWrittenPrototype=*/false);
} }
for (const FieldDecl *FD : RD->fields()) { for (const FieldDecl *FD : RD->fields()) {
QualType ArgType = FD->getType(); QualType ArgType = FD->getType();

View File

@ -78,7 +78,6 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
EHStack.setCGF(this); EHStack.setCGF(this);
SetFastMathFlags(CurFPFeatures); SetFastMathFlags(CurFPFeatures);
SetFPModel();
} }
CodeGenFunction::~CodeGenFunction() { CodeGenFunction::~CodeGenFunction() {
@ -109,17 +108,6 @@ clang::ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind) {
llvm_unreachable("Unsupported FP Exception Behavior"); 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) { void CodeGenFunction::SetFastMathFlags(FPOptions FPFeatures) {
llvm::FastMathFlags FMF; llvm::FastMathFlags FMF;
FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate()); FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
@ -947,9 +935,15 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
(getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>()))) (getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>())))
Fn->addFnAttr(llvm::Attribute::NoRecurse); Fn->addFnAttr(llvm::Attribute::NoRecurse);
if (FD) { llvm::RoundingMode RM = getLangOpts().getFPRoundingMode();
Builder.setIsFPConstrained(FD->hasAttr<StrictFPAttr>()); llvm::fp::ExceptionBehavior FPExceptionBehavior =
if (FD->hasAttr<StrictFPAttr>()) ToConstrainedExceptMD(getLangOpts().getFPExceptionMode());
Builder.setDefaultConstrainedRounding(RM);
Builder.setDefaultConstrainedExcept(FPExceptionBehavior);
if ((FD && (FD->UsesFPIntrin() || FD->hasAttr<StrictFPAttr>())) ||
(!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||
RM != llvm::RoundingMode::NearestTiesToEven))) {
Builder.setIsFPConstrained(true);
Fn->addFnAttr(llvm::Attribute::StrictFP); Fn->addFnAttr(llvm::Attribute::StrictFP);
} }

View File

@ -4588,9 +4588,6 @@ public:
/// point operation, expressed as the maximum relative error in ulp. /// point operation, expressed as the maximum relative error in ulp.
void SetFPAccuracy(llvm::Value *Val, float Accuracy); void SetFPAccuracy(llvm::Value *Val, float Accuracy);
/// SetFPModel - Control floating point behavior via fp-model settings.
void SetFPModel();
/// Set the codegen fast-math flags. /// Set the codegen fast-math flags.
void SetFastMathFlags(FPOptions FPFeatures); void SetFastMathFlags(FPOptions FPFeatures);

View File

@ -2113,8 +2113,9 @@ FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, QualType Type,
} }
FunctionDecl *New = FunctionDecl::Create(Context, Parent, Loc, Loc, II, Type, FunctionDecl *New = FunctionDecl::Create(Context, Parent, Loc, Loc, II, Type,
/*TInfo=*/nullptr, SC_Extern, false, /*TInfo=*/nullptr, SC_Extern,
Type->isFunctionProtoType()); getCurFPFeatures().isFPConstrained(),
false, Type->isFunctionProtoType());
New->setImplicit(); New->setImplicit();
New->addAttr(BuiltinAttr::CreateImplicit(Context, ID)); New->addAttr(BuiltinAttr::CreateImplicit(Context, ID));
@ -8552,8 +8553,9 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
(D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) || (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) ||
(!R->getAsAdjusted<FunctionType>() && R->isFunctionProtoType()); (!R->getAsAdjusted<FunctionType>() && R->isFunctionProtoType());
NewFD = FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), NameInfo, NewFD = FunctionDecl::Create(
R, TInfo, SC, isInline, HasPrototype, SemaRef.Context, DC, D.getBeginLoc(), NameInfo, R, TInfo, SC,
SemaRef.getCurFPFeatures().isFPConstrained(), isInline, HasPrototype,
ConstexprSpecKind::Unspecified, ConstexprSpecKind::Unspecified,
/*TrailingRequiresClause=*/nullptr); /*TrailingRequiresClause=*/nullptr);
if (D.isInvalidType()) if (D.isInvalidType())
@ -8591,9 +8593,9 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
R = SemaRef.CheckConstructorDeclarator(D, R, SC); R = SemaRef.CheckConstructorDeclarator(D, R, SC);
return CXXConstructorDecl::Create( return CXXConstructorDecl::Create(
SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R, SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R,
TInfo, ExplicitSpecifier, isInline, TInfo, ExplicitSpecifier, SemaRef.getCurFPFeatures().isFPConstrained(),
/*isImplicitlyDeclared=*/false, ConstexprKind, InheritedConstructor(), isInline, /*isImplicitlyDeclared=*/false, ConstexprKind,
TrailingRequiresClause); InheritedConstructor(), TrailingRequiresClause);
} else if (Name.getNameKind() == DeclarationName::CXXDestructorName) { } else if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
// This is a C++ destructor declaration. // This is a C++ destructor declaration.
@ -8602,7 +8604,8 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
CXXRecordDecl *Record = cast<CXXRecordDecl>(DC); CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
CXXDestructorDecl *NewDD = CXXDestructorDecl::Create( CXXDestructorDecl *NewDD = CXXDestructorDecl::Create(
SemaRef.Context, Record, D.getBeginLoc(), NameInfo, R, TInfo, SemaRef.Context, Record, D.getBeginLoc(), NameInfo, R, TInfo,
isInline, /*isImplicitlyDeclared=*/false, ConstexprKind, SemaRef.getCurFPFeatures().isFPConstrained(), isInline,
/*isImplicitlyDeclared=*/false, ConstexprKind,
TrailingRequiresClause); TrailingRequiresClause);
// If the destructor needs an implicit exception specification, set it // If the destructor needs an implicit exception specification, set it
@ -8620,11 +8623,10 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
// Create a FunctionDecl to satisfy the function definition parsing // Create a FunctionDecl to satisfy the function definition parsing
// code path. // code path.
return FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), return FunctionDecl::Create(
D.getIdentifierLoc(), Name, R, TInfo, SC, SemaRef.Context, DC, D.getBeginLoc(), D.getIdentifierLoc(), Name, R,
isInline, TInfo, SC, SemaRef.getCurFPFeatures().isFPConstrained(), isInline,
/*hasPrototype=*/true, ConstexprKind, /*hasPrototype=*/true, ConstexprKind, TrailingRequiresClause);
TrailingRequiresClause);
} }
} else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) { } else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
@ -8641,7 +8643,8 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
IsVirtualOkay = true; IsVirtualOkay = true;
return CXXConversionDecl::Create( return CXXConversionDecl::Create(
SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R, SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R,
TInfo, isInline, ExplicitSpecifier, ConstexprKind, SourceLocation(), TInfo, SemaRef.getCurFPFeatures().isFPConstrained(), isInline,
ExplicitSpecifier, ConstexprKind, SourceLocation(),
TrailingRequiresClause); TrailingRequiresClause);
} else if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) { } else if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) {
@ -8670,8 +8673,8 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
// This is a C++ method declaration. // This is a C++ method declaration.
CXXMethodDecl *Ret = CXXMethodDecl::Create( CXXMethodDecl *Ret = CXXMethodDecl::Create(
SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R, SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R,
TInfo, SC, isInline, ConstexprKind, SourceLocation(), TInfo, SC, SemaRef.getCurFPFeatures().isFPConstrained(), isInline,
TrailingRequiresClause); ConstexprKind, SourceLocation(), TrailingRequiresClause);
IsVirtualOkay = !Ret->isStatic(); IsVirtualOkay = !Ret->isStatic();
return Ret; return Ret;
} else { } else {
@ -8683,9 +8686,10 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
// Determine whether the function was written with a // Determine whether the function was written with a
// prototype. This true when: // prototype. This true when:
// - we're in C++ (where every function has a prototype), // - we're in C++ (where every function has a prototype),
return FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), NameInfo, return FunctionDecl::Create(
R, TInfo, SC, isInline, true /*HasPrototype*/, SemaRef.Context, DC, D.getBeginLoc(), NameInfo, R, TInfo, SC,
ConstexprKind, TrailingRequiresClause); SemaRef.getCurFPFeatures().isFPConstrained(), isInline,
true /*HasPrototype*/, ConstexprKind, TrailingRequiresClause);
} }
} }

View File

@ -8592,8 +8592,9 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
NewFD = FunctionDecl::Create( NewFD = FunctionDecl::Create(
FD->getASTContext(), FD->getDeclContext(), Loc, Loc, FD->getASTContext(), FD->getDeclContext(), Loc, Loc,
DeclarationName(II), FD->getType(), FD->getTypeSourceInfo(), SC_None, DeclarationName(II), FD->getType(), FD->getTypeSourceInfo(), SC_None,
false /*isInlineSpecified*/, FD->hasPrototype(), getCurFPFeatures().isFPConstrained(), false /*isInlineSpecified*/,
ConstexprSpecKind::Unspecified, FD->getTrailingRequiresClause()); FD->hasPrototype(), ConstexprSpecKind::Unspecified,
FD->getTrailingRequiresClause());
NewD = NewFD; NewD = NewFD;
if (FD->getQualifier()) if (FD->getQualifier())

View File

@ -13234,6 +13234,7 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
CXXConstructorDecl *DefaultCon = CXXConstructorDecl::Create( CXXConstructorDecl *DefaultCon = CXXConstructorDecl::Create(
Context, ClassDecl, ClassLoc, NameInfo, /*Type*/ QualType(), Context, ClassDecl, ClassLoc, NameInfo, /*Type*/ QualType(),
/*TInfo=*/nullptr, ExplicitSpecifier(), /*TInfo=*/nullptr, ExplicitSpecifier(),
getCurFPFeatures().isFPConstrained(),
/*isInline=*/true, /*isImplicitlyDeclared=*/true, /*isInline=*/true, /*isImplicitlyDeclared=*/true,
Constexpr ? ConstexprSpecKind::Constexpr Constexpr ? ConstexprSpecKind::Constexpr
: ConstexprSpecKind::Unspecified); : ConstexprSpecKind::Unspecified);
@ -13355,7 +13356,8 @@ Sema::findInheritingConstructor(SourceLocation Loc,
CXXConstructorDecl *DerivedCtor = CXXConstructorDecl::Create( CXXConstructorDecl *DerivedCtor = CXXConstructorDecl::Create(
Context, Derived, UsingLoc, NameInfo, TInfo->getType(), TInfo, Context, Derived, UsingLoc, NameInfo, TInfo->getType(), TInfo,
BaseCtor->getExplicitSpecifier(), /*isInline=*/true, BaseCtor->getExplicitSpecifier(), getCurFPFeatures().isFPConstrained(),
/*isInline=*/true,
/*isImplicitlyDeclared=*/true, /*isImplicitlyDeclared=*/true,
Constexpr ? BaseCtor->getConstexprKind() : ConstexprSpecKind::Unspecified, Constexpr ? BaseCtor->getConstexprKind() : ConstexprSpecKind::Unspecified,
InheritedConstructor(Shadow, BaseCtor), InheritedConstructor(Shadow, BaseCtor),
@ -13510,9 +13512,10 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
DeclarationName Name DeclarationName Name
= Context.DeclarationNames.getCXXDestructorName(ClassType); = Context.DeclarationNames.getCXXDestructorName(ClassType);
DeclarationNameInfo NameInfo(Name, ClassLoc); DeclarationNameInfo NameInfo(Name, ClassLoc);
CXXDestructorDecl *Destructor = CXXDestructorDecl *Destructor = CXXDestructorDecl::Create(
CXXDestructorDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, Context, ClassDecl, ClassLoc, NameInfo, QualType(), nullptr,
QualType(), nullptr, /*isInline=*/true, getCurFPFeatures().isFPConstrained(),
/*isInline=*/true,
/*isImplicitlyDeclared=*/true, /*isImplicitlyDeclared=*/true,
Constexpr ? ConstexprSpecKind::Constexpr Constexpr ? ConstexprSpecKind::Constexpr
: ConstexprSpecKind::Unspecified); : ConstexprSpecKind::Unspecified);
@ -14151,6 +14154,7 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
CXXMethodDecl *CopyAssignment = CXXMethodDecl::Create( CXXMethodDecl *CopyAssignment = CXXMethodDecl::Create(
Context, ClassDecl, ClassLoc, NameInfo, QualType(), Context, ClassDecl, ClassLoc, NameInfo, QualType(),
/*TInfo=*/nullptr, /*StorageClass=*/SC_None, /*TInfo=*/nullptr, /*StorageClass=*/SC_None,
getCurFPFeatures().isFPConstrained(),
/*isInline=*/true, /*isInline=*/true,
Constexpr ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified, Constexpr ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified,
SourceLocation()); SourceLocation());
@ -14485,6 +14489,7 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
CXXMethodDecl *MoveAssignment = CXXMethodDecl::Create( CXXMethodDecl *MoveAssignment = CXXMethodDecl::Create(
Context, ClassDecl, ClassLoc, NameInfo, QualType(), Context, ClassDecl, ClassLoc, NameInfo, QualType(),
/*TInfo=*/nullptr, /*StorageClass=*/SC_None, /*TInfo=*/nullptr, /*StorageClass=*/SC_None,
getCurFPFeatures().isFPConstrained(),
/*isInline=*/true, /*isInline=*/true,
Constexpr ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified, Constexpr ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified,
SourceLocation()); SourceLocation());
@ -14864,7 +14869,7 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
// member of its class. // member of its class.
CXXConstructorDecl *CopyConstructor = CXXConstructorDecl::Create( CXXConstructorDecl *CopyConstructor = CXXConstructorDecl::Create(
Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr, Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr,
ExplicitSpecifier(), ExplicitSpecifier(), getCurFPFeatures().isFPConstrained(),
/*isInline=*/true, /*isInline=*/true,
/*isImplicitlyDeclared=*/true, /*isImplicitlyDeclared=*/true,
Constexpr ? ConstexprSpecKind::Constexpr Constexpr ? ConstexprSpecKind::Constexpr
@ -15004,7 +15009,7 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
// member of its class. // member of its class.
CXXConstructorDecl *MoveConstructor = CXXConstructorDecl::Create( CXXConstructorDecl *MoveConstructor = CXXConstructorDecl::Create(
Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr, Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr,
ExplicitSpecifier(), ExplicitSpecifier(), getCurFPFeatures().isFPConstrained(),
/*isInline=*/true, /*isInline=*/true,
/*isImplicitlyDeclared=*/true, /*isImplicitlyDeclared=*/true,
Constexpr ? ConstexprSpecKind::Constexpr Constexpr ? ConstexprSpecKind::Constexpr

View File

@ -6280,13 +6280,11 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context,
QualType OverloadTy = Context.getFunctionType(FT->getReturnType(), QualType OverloadTy = Context.getFunctionType(FT->getReturnType(),
OverloadParams, EPI); OverloadParams, EPI);
DeclContext *Parent = FDecl->getParent(); DeclContext *Parent = FDecl->getParent();
FunctionDecl *OverloadDecl = FunctionDecl::Create(Context, Parent, FunctionDecl *OverloadDecl = FunctionDecl::Create(
FDecl->getLocation(), Context, Parent, FDecl->getLocation(), FDecl->getLocation(),
FDecl->getLocation(), FDecl->getIdentifier(), OverloadTy,
FDecl->getIdentifier(), /*TInfo=*/nullptr, SC_Extern, Sema->getCurFPFeatures().isFPConstrained(),
OverloadTy, false,
/*TInfo=*/nullptr,
SC_Extern, false,
/*hasPrototype=*/true); /*hasPrototype=*/true);
SmallVector<ParmVarDecl*, 16> Params; SmallVector<ParmVarDecl*, 16> Params;
FT = cast<FunctionProtoType>(OverloadTy); FT = cast<FunctionProtoType>(OverloadTy);
@ -19529,7 +19527,8 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {
FunctionDecl *NewFD = FunctionDecl::Create( FunctionDecl *NewFD = FunctionDecl::Create(
S.Context, FD->getDeclContext(), Loc, Loc, S.Context, FD->getDeclContext(), Loc, Loc,
FD->getNameInfo().getName(), DestType, FD->getTypeSourceInfo(), FD->getNameInfo().getName(), DestType, FD->getTypeSourceInfo(),
SC_None, false /*isInlineSpecified*/, FD->hasPrototype(), SC_None, S.getCurFPFeatures().isFPConstrained(),
false /*isInlineSpecified*/, FD->hasPrototype(),
/*ConstexprKind*/ ConstexprSpecKind::Unspecified); /*ConstexprKind*/ ConstexprSpecKind::Unspecified);
if (FD->getQualifier()) if (FD->getQualifier())

View File

@ -3057,8 +3057,9 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) { auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) {
QualType FnType = Context.getFunctionType(Return, Params, EPI); QualType FnType = Context.getFunctionType(Return, Params, EPI);
FunctionDecl *Alloc = FunctionDecl::Create( FunctionDecl *Alloc = FunctionDecl::Create(
Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, FnType,
FnType, /*TInfo=*/nullptr, SC_None, false, true); /*TInfo=*/nullptr, SC_None, getCurFPFeatures().isFPConstrained(), false,
true);
Alloc->setImplicit(); Alloc->setImplicit();
// Global allocation functions should always be visible. // Global allocation functions should always be visible.
Alloc->setVisibleDespiteOwningModule(); Alloc->setVisibleDespiteOwningModule();

View File

@ -392,7 +392,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
Context, Class, EndLoc, Context, Class, EndLoc,
DeclarationNameInfo(MethodName, IntroducerRange.getBegin(), DeclarationNameInfo(MethodName, IntroducerRange.getBegin(),
MethodNameLoc), MethodNameLoc),
MethodType, MethodTypeInfo, SC_None, MethodType, MethodTypeInfo, SC_None, getCurFPFeatures().isFPConstrained(),
/*isInline=*/true, ConstexprKind, EndLoc, TrailingRequiresClause); /*isInline=*/true, ConstexprKind, EndLoc, TrailingRequiresClause);
Method->setAccess(AS_public); Method->setAccess(AS_public);
if (!TemplateParams) if (!TemplateParams)
@ -1447,6 +1447,7 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
CXXConversionDecl *Conversion = CXXConversionDecl::Create( CXXConversionDecl *Conversion = CXXConversionDecl::Create(
S.Context, Class, Loc, S.Context, Class, Loc,
DeclarationNameInfo(ConversionName, Loc, ConvNameLoc), ConvTy, ConvTSI, DeclarationNameInfo(ConversionName, Loc, ConvNameLoc), ConvTy, ConvTSI,
S.getCurFPFeatures().isFPConstrained(),
/*isInline=*/true, ExplicitSpecifier(), /*isInline=*/true, ExplicitSpecifier(),
S.getLangOpts().CPlusPlus17 ? ConstexprSpecKind::Constexpr S.getLangOpts().CPlusPlus17 ? ConstexprSpecKind::Constexpr
: ConstexprSpecKind::Unspecified, : ConstexprSpecKind::Unspecified,
@ -1488,6 +1489,7 @@ static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange,
CXXMethodDecl *Invoke = CXXMethodDecl::Create( CXXMethodDecl *Invoke = CXXMethodDecl::Create(
S.Context, Class, Loc, DeclarationNameInfo(InvokerName, Loc), S.Context, Class, Loc, DeclarationNameInfo(InvokerName, Loc),
InvokerFunctionTy, CallOperator->getTypeSourceInfo(), SC_Static, InvokerFunctionTy, CallOperator->getTypeSourceInfo(), SC_Static,
S.getCurFPFeatures().isFPConstrained(),
/*isInline=*/true, ConstexprSpecKind::Unspecified, /*isInline=*/true, ConstexprSpecKind::Unspecified,
CallOperator->getBody()->getEndLoc()); CallOperator->getBody()->getEndLoc());
for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I)
@ -1556,6 +1558,7 @@ static void addBlockPointerConversion(Sema &S,
CXXConversionDecl *Conversion = CXXConversionDecl::Create( CXXConversionDecl *Conversion = CXXConversionDecl::Create(
S.Context, Class, Loc, DeclarationNameInfo(Name, Loc, NameLoc), ConvTy, S.Context, Class, Loc, DeclarationNameInfo(Name, Loc, NameLoc), ConvTy,
S.Context.getTrivialTypeSourceInfo(ConvTy, Loc), S.Context.getTrivialTypeSourceInfo(ConvTy, Loc),
S.getCurFPFeatures().isFPConstrained(),
/*isInline=*/true, ExplicitSpecifier(), ConstexprSpecKind::Unspecified, /*isInline=*/true, ExplicitSpecifier(), ConstexprSpecKind::Unspecified,
CallOperator->getBody()->getEndLoc()); CallOperator->getBody()->getEndLoc());
Conversion->setAccess(AS_public); Conversion->setAccess(AS_public);

View File

@ -859,7 +859,8 @@ static void InsertOCLBuiltinDeclarationsFromTable(Sema &S, LookupResult &LR,
for (const auto &FTy : FunctionList) { for (const auto &FTy : FunctionList) {
NewOpenCLBuiltin = FunctionDecl::Create( NewOpenCLBuiltin = FunctionDecl::Create(
Context, Parent, Loc, Loc, II, FTy, /*TInfo=*/nullptr, SC_Extern, Context, Parent, Loc, Loc, II, FTy, /*TInfo=*/nullptr, SC_Extern,
false, FTy->isFunctionProtoType()); S.getCurFPFeatures().isFPConstrained(), false,
FTy->isFunctionProtoType());
NewOpenCLBuiltin->setImplicit(); NewOpenCLBuiltin->setImplicit();
// Create Decl objects for each parameter, adding them to the // Create Decl objects for each parameter, adding them to the

View File

@ -2051,8 +2051,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
} else { } else {
Function = FunctionDecl::Create( Function = FunctionDecl::Create(
SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo, SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo,
D->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(), D->getCanonicalDecl()->getStorageClass(), D->UsesFPIntrin(),
D->hasWrittenPrototype(), D->getConstexprKind(), D->isInlineSpecified(), D->hasWrittenPrototype(), D->getConstexprKind(),
TrailingRequiresClause); TrailingRequiresClause);
Function->setRangeEnd(D->getSourceRange().getEnd()); Function->setRangeEnd(D->getSourceRange().getEnd());
} }
@ -2407,15 +2407,16 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) { if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
Method = CXXConstructorDecl::Create( Method = CXXConstructorDecl::Create(
SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
InstantiatedExplicitSpecifier, Constructor->isInlineSpecified(), false, InstantiatedExplicitSpecifier, Constructor->UsesFPIntrin(),
Constructor->isInlineSpecified(), false,
Constructor->getConstexprKind(), InheritedConstructor(), Constructor->getConstexprKind(), InheritedConstructor(),
TrailingRequiresClause); TrailingRequiresClause);
Method->setRangeEnd(Constructor->getEndLoc()); Method->setRangeEnd(Constructor->getEndLoc());
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) { } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
Method = CXXDestructorDecl::Create( Method = CXXDestructorDecl::Create(
SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
Destructor->isInlineSpecified(), false, Destructor->getConstexprKind(), Destructor->UsesFPIntrin(), Destructor->isInlineSpecified(), false,
TrailingRequiresClause); Destructor->getConstexprKind(), TrailingRequiresClause);
Method->setRangeEnd(Destructor->getEndLoc()); Method->setRangeEnd(Destructor->getEndLoc());
Method->setDeclName(SemaRef.Context.DeclarationNames.getCXXDestructorName( Method->setDeclName(SemaRef.Context.DeclarationNames.getCXXDestructorName(
SemaRef.Context.getCanonicalType( SemaRef.Context.getCanonicalType(
@ -2423,15 +2424,15 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
} else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) { } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
Method = CXXConversionDecl::Create( Method = CXXConversionDecl::Create(
SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
Conversion->isInlineSpecified(), InstantiatedExplicitSpecifier, Conversion->UsesFPIntrin(), Conversion->isInlineSpecified(),
Conversion->getConstexprKind(), Conversion->getEndLoc(), InstantiatedExplicitSpecifier, Conversion->getConstexprKind(),
TrailingRequiresClause); Conversion->getEndLoc(), TrailingRequiresClause);
} else { } else {
StorageClass SC = D->isStatic() ? SC_Static : SC_None; StorageClass SC = D->isStatic() ? SC_Static : SC_None;
Method = CXXMethodDecl::Create(SemaRef.Context, Record, StartLoc, NameInfo, Method = CXXMethodDecl::Create(
T, TInfo, SC, D->isInlineSpecified(), SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SC,
D->getConstexprKind(), D->getEndLoc(), D->UsesFPIntrin(), D->isInlineSpecified(), D->getConstexprKind(),
TrailingRequiresClause); D->getEndLoc(), TrailingRequiresClause);
} }
if (D->isInlined()) if (D->isInlined())

View File

@ -8,13 +8,13 @@ float z();
class ON { class ON {
float w = 2 + y() * z(); float w = 2 + y() * z();
// CHECK-LABEL: define {{.*}} @_ZN2ONC2Ev{{.*}} // CHECK-LABEL: define {{.*}} @_ZN2ONC2Ev{{.*}}
//CHECK: call float {{.*}}llvm.fmuladd // CHECK: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
}; };
ON on; ON on;
#pragma float_control(except, off) #pragma float_control(except, off)
class OFF { class OFF {
float w = 2 + y() * z(); float w = 2 + y() * z();
// CHECK-LABEL: define {{.*}} @_ZN3OFFC2Ev{{.*}} // CHECK-LABEL: define {{.*}} @_ZN3OFFC2Ev{{.*}}
//CHECK: call float {{.*}}llvm.fmuladd // CHECK-NOT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
}; };
OFF off; OFF off;

View File

@ -6,6 +6,10 @@
#define FUN(n) \ #define FUN(n) \
(float z) { return n * z + 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: mustprogress noinline nounwind optnone
// CHECK-NOHONOR Function Attrs: noinline nounwind optnone mustprogress
float fun_default FUN(1) float fun_default FUN(1)
//CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}} //CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}}
#if DEFAULT #if DEFAULT
@ -28,6 +32,10 @@ float fun_default FUN(1)
// Rule: precise must be enabled // Rule: precise must be enabled
#pragma float_control(except, on) #pragma float_control(except, on)
#endif #endif
// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone
// 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) float exc_on FUN(2)
//CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}} //CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}}
#if DEFAULT #if DEFAULT
@ -46,6 +54,10 @@ float fun_default FUN(1)
#endif #endif
#pragma float_control(pop) #pragma float_control(pop)
// CHECK-DDEFAULT Function Attrs: noinline nounwind optnone mustprogress
// CHECK-DEBSTRICT Function Attrs: noinline nounwind optnone strictfp mustprogress
// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone
// CHECK-NOHONOR Function Attrs: noinline nounwind optnone mustprogress
float exc_pop FUN(5) float exc_pop FUN(5)
//CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}} //CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}}
#if DEFAULT #if DEFAULT
@ -211,26 +223,33 @@ float fun_default FUN(1)
#pragma float_control(except, on) #pragma float_control(except, on)
#endif #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: mustprogress noinline nounwind optnone
// CHECK-NOHONOR Function Attrs: noinline nounwind optnone mustprogress
class ON { class ON {
// Settings for top level class initializer use program source setting. // Settings for top level class initializer use program source setting.
float z = 2 + y() * 7; float z = 2 + y() * 7;
//CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}} //CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}}
#if DEFAULT #if DEFAULT
//CHECK-DDEFAULT: call float {{.*}}llvm.fmuladd // CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
#endif #endif
#if EBSTRICT #if EBSTRICT
//Currently, same as default [command line options not considered] // CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
//CHECK-DEBSTRICT: call float {{.*}}llvm.fmuladd
#endif #endif
#if NOHONOR #if NOHONOR
//CHECK-NOHONOR: call float {{.*}}llvm.fmuladd // CHECK-NOHONOR: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
#endif #endif
#if FAST #if FAST
//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} // CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}}
#endif #endif
}; };
ON on; ON on;
#pragma float_control(except, off) #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 { class OFF {
float w = 2 + y() * 7; float w = 2 + y() * 7;
//CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} //CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}}
@ -259,3 +278,9 @@ MyComplex useAdd() {
MyComplex b (2, 4); MyComplex b (2, 4);
return a + b; 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

View File

@ -163,7 +163,8 @@ public:
CurrentSema->getPreprocessor().getIdentifierInfo(CorrectTo); CurrentSema->getPreprocessor().getIdentifierInfo(CorrectTo);
auto *NewFunction = FunctionDecl::Create( auto *NewFunction = FunctionDecl::Create(
Context, DestContext, SourceLocation(), SourceLocation(), ToIdent, Context, DestContext, SourceLocation(), SourceLocation(), ToIdent,
Context.getFunctionType(Context.VoidTy, {}, {}), nullptr, SC_Static); Context.getFunctionType(Context.VoidTy, {}, {}), nullptr, SC_Static,
/*UsesFPIntrin*/ false);
DestContext->addDecl(NewFunction); DestContext->addDecl(NewFunction);
TypoCorrection Correction(ToIdent); TypoCorrection Correction(ToIdent);
Correction.addCorrectionDecl(NewFunction); Correction.addCorrectionDecl(NewFunction);