Skip to content

Commit bc5b5ea

Browse files
author
Melanie Blower
committed
[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
1 parent 4acc2f2 commit bc5b5ea

20 files changed

+249
-210
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,8 +1990,8 @@ class FunctionDecl : public DeclaratorDecl,
19901990
protected:
19911991
FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
19921992
const DeclarationNameInfo &NameInfo, QualType T,
1993-
TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified,
1994-
ConstexprSpecKind ConstexprKind,
1993+
TypeSourceInfo *TInfo, StorageClass S, bool UsesFPIntrin,
1994+
bool isInlineSpecified, ConstexprSpecKind ConstexprKind,
19951995
Expr *TrailingRequiresClause = nullptr);
19961996

19971997
using redeclarable_base = Redeclarable<FunctionDecl>;
@@ -2025,23 +2025,23 @@ class FunctionDecl : public DeclaratorDecl,
20252025
static FunctionDecl *
20262026
Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
20272027
SourceLocation NLoc, DeclarationName N, QualType T,
2028-
TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false,
2029-
bool hasWrittenPrototype = true,
2028+
TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin = false,
2029+
bool isInlineSpecified = false, bool hasWrittenPrototype = true,
20302030
ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified,
20312031
Expr *TrailingRequiresClause = nullptr) {
20322032
DeclarationNameInfo NameInfo(N, NLoc);
20332033
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC,
2034-
isInlineSpecified, hasWrittenPrototype,
2035-
ConstexprKind, TrailingRequiresClause);
2034+
UsesFPIntrin, isInlineSpecified,
2035+
hasWrittenPrototype, ConstexprKind,
2036+
TrailingRequiresClause);
20362037
}
20372038

2038-
static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
2039-
SourceLocation StartLoc,
2040-
const DeclarationNameInfo &NameInfo, QualType T,
2041-
TypeSourceInfo *TInfo, StorageClass SC,
2042-
bool isInlineSpecified, bool hasWrittenPrototype,
2043-
ConstexprSpecKind ConstexprKind,
2044-
Expr *TrailingRequiresClause);
2039+
static FunctionDecl *
2040+
Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
2041+
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2042+
StorageClass SC, bool UsesFPIntrin, bool isInlineSpecified,
2043+
bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind,
2044+
Expr *TrailingRequiresClause);
20452045

20462046
static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
20472047

@@ -2594,6 +2594,14 @@ class FunctionDecl : public DeclaratorDecl,
25942594
FunctionDeclBits.IsInline = I;
25952595
}
25962596

2597+
/// Determine whether the function was declared in source context
2598+
/// that requires constrained FP intrinsics
2599+
bool UsesFPIntrin() const { return FunctionDeclBits.UsesFPIntrin; }
2600+
2601+
/// Set whether the function was declared in source context
2602+
/// that requires constrained FP intrinsics
2603+
void setUsesFPIntrin(bool I) { FunctionDeclBits.UsesFPIntrin = I; }
2604+
25972605
/// Flag that this function is implicitly inline.
25982606
void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; }
25992607

clang/include/clang/AST/DeclCXX.h

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,7 +1857,7 @@ class CXXDeductionGuideDecl : public FunctionDecl {
18571857
TypeSourceInfo *TInfo, SourceLocation EndLocation,
18581858
CXXConstructorDecl *Ctor)
18591859
: FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
1860-
SC_None, false, ConstexprSpecKind::Unspecified),
1860+
SC_None, false, false, ConstexprSpecKind::Unspecified),
18611861
Ctor(Ctor), ExplicitSpec(ES) {
18621862
if (EndLocation.isValid())
18631863
setRangeEnd(EndLocation);
@@ -1952,23 +1952,22 @@ class CXXMethodDecl : public FunctionDecl {
19521952
CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
19531953
SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
19541954
QualType T, TypeSourceInfo *TInfo, StorageClass SC,
1955-
bool isInline, ConstexprSpecKind ConstexprKind,
1956-
SourceLocation EndLocation,
1955+
bool UsesFPIntrin, bool isInline,
1956+
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
19571957
Expr *TrailingRequiresClause = nullptr)
1958-
: FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, isInline,
1959-
ConstexprKind, TrailingRequiresClause) {
1958+
: FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
1959+
isInline, ConstexprKind, TrailingRequiresClause) {
19601960
if (EndLocation.isValid())
19611961
setRangeEnd(EndLocation);
19621962
}
19631963

19641964
public:
1965-
static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
1966-
SourceLocation StartLoc,
1967-
const DeclarationNameInfo &NameInfo, QualType T,
1968-
TypeSourceInfo *TInfo, StorageClass SC,
1969-
bool isInline, ConstexprSpecKind ConstexprKind,
1970-
SourceLocation EndLocation,
1971-
Expr *TrailingRequiresClause = nullptr);
1965+
static CXXMethodDecl *
1966+
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
1967+
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
1968+
StorageClass SC, bool UsesFPIntrin, bool isInline,
1969+
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
1970+
Expr *TrailingRequiresClause = nullptr);
19721971

19731972
static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
19741973

@@ -2413,7 +2412,8 @@ class CXXConstructorDecl final
24132412

24142413
CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
24152414
const DeclarationNameInfo &NameInfo, QualType T,
2416-
TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool isInline,
2415+
TypeSourceInfo *TInfo, ExplicitSpecifier ES,
2416+
bool UsesFPIntrin, bool isInline,
24172417
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
24182418
InheritedConstructor Inherited,
24192419
Expr *TrailingRequiresClause);
@@ -2456,8 +2456,8 @@ class CXXConstructorDecl final
24562456
static CXXConstructorDecl *
24572457
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
24582458
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2459-
ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
2460-
ConstexprSpecKind ConstexprKind,
2459+
ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
2460+
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
24612461
InheritedConstructor Inherited = InheritedConstructor(),
24622462
Expr *TrailingRequiresClause = nullptr);
24632463

@@ -2676,25 +2676,24 @@ class CXXDestructorDecl : public CXXMethodDecl {
26762676

26772677
CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
26782678
const DeclarationNameInfo &NameInfo, QualType T,
2679-
TypeSourceInfo *TInfo, bool isInline,
2679+
TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
26802680
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
26812681
Expr *TrailingRequiresClause = nullptr)
26822682
: CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
2683-
SC_None, isInline, ConstexprKind, SourceLocation(),
2684-
TrailingRequiresClause) {
2683+
SC_None, UsesFPIntrin, isInline, ConstexprKind,
2684+
SourceLocation(), TrailingRequiresClause) {
26852685
setImplicit(isImplicitlyDeclared);
26862686
}
26872687

26882688
void anchor() override;
26892689

26902690
public:
2691-
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
2692-
SourceLocation StartLoc,
2693-
const DeclarationNameInfo &NameInfo,
2694-
QualType T, TypeSourceInfo *TInfo,
2695-
bool isInline, bool isImplicitlyDeclared,
2696-
ConstexprSpecKind ConstexprKind,
2697-
Expr *TrailingRequiresClause = nullptr);
2691+
static CXXDestructorDecl *
2692+
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
2693+
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2694+
bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
2695+
ConstexprSpecKind ConstexprKind,
2696+
Expr *TrailingRequiresClause = nullptr);
26982697
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
26992698

27002699
void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
@@ -2732,12 +2731,13 @@ class CXXDestructorDecl : public CXXMethodDecl {
27322731
class CXXConversionDecl : public CXXMethodDecl {
27332732
CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
27342733
const DeclarationNameInfo &NameInfo, QualType T,
2735-
TypeSourceInfo *TInfo, bool isInline, ExplicitSpecifier ES,
2736-
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
2734+
TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
2735+
ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
2736+
SourceLocation EndLocation,
27372737
Expr *TrailingRequiresClause = nullptr)
27382738
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
2739-
SC_None, isInline, ConstexprKind, EndLocation,
2740-
TrailingRequiresClause),
2739+
SC_None, UsesFPIntrin, isInline, ConstexprKind,
2740+
EndLocation, TrailingRequiresClause),
27412741
ExplicitSpec(ES) {}
27422742
void anchor() override;
27432743

@@ -2750,8 +2750,9 @@ class CXXConversionDecl : public CXXMethodDecl {
27502750
static CXXConversionDecl *
27512751
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
27522752
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2753-
bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
2754-
SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr);
2753+
bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
2754+
ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
2755+
Expr *TrailingRequiresClause = nullptr);
27552756
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
27562757

27572758
ExplicitSpecifier getExplicitSpecifier() {

clang/lib/AST/ASTImporter.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3461,8 +3461,8 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
34613461
return std::move(Err);
34623462
if (GetImportedOrCreateDecl<CXXConstructorDecl>(
34633463
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
3464-
ToInnerLocStart, NameInfo, T, TInfo, ESpec, D->isInlineSpecified(),
3465-
D->isImplicit(), D->getConstexprKind(),
3464+
ToInnerLocStart, NameInfo, T, TInfo, ESpec, D->UsesFPIntrin(),
3465+
D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind(),
34663466
InheritedConstructor(), // FIXME: Properly import inherited
34673467
// constructor info
34683468
TrailingRequiresClause))
@@ -3477,9 +3477,10 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
34773477
return std::move(Err);
34783478

34793479
if (GetImportedOrCreateDecl<CXXDestructorDecl>(
3480-
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
3481-
ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
3482-
D->isImplicit(), D->getConstexprKind(), TrailingRequiresClause))
3480+
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
3481+
ToInnerLocStart, NameInfo, T, TInfo, D->UsesFPIntrin(),
3482+
D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind(),
3483+
TrailingRequiresClause))
34833484
return ToFunction;
34843485

34853486
CXXDestructorDecl *ToDtor = cast<CXXDestructorDecl>(ToFunction);
@@ -3493,15 +3494,16 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
34933494
return std::move(Err);
34943495
if (GetImportedOrCreateDecl<CXXConversionDecl>(
34953496
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
3496-
ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(), ESpec,
3497-
D->getConstexprKind(), SourceLocation(), TrailingRequiresClause))
3497+
ToInnerLocStart, NameInfo, T, TInfo, D->UsesFPIntrin(),
3498+
D->isInlineSpecified(), ESpec, D->getConstexprKind(),
3499+
SourceLocation(), TrailingRequiresClause))
34983500
return ToFunction;
34993501
} else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) {
35003502
if (GetImportedOrCreateDecl<CXXMethodDecl>(
35013503
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
35023504
ToInnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(),
3503-
Method->isInlineSpecified(), D->getConstexprKind(),
3504-
SourceLocation(), TrailingRequiresClause))
3505+
Method->UsesFPIntrin(), Method->isInlineSpecified(),
3506+
D->getConstexprKind(), SourceLocation(), TrailingRequiresClause))
35053507
return ToFunction;
35063508
} else if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
35073509
ExplicitSpecifier ESpec =
@@ -3519,9 +3521,9 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
35193521
} else {
35203522
if (GetImportedOrCreateDecl(
35213523
ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart,
3522-
NameInfo, T, TInfo, D->getStorageClass(), D->isInlineSpecified(),
3523-
D->hasWrittenPrototype(), D->getConstexprKind(),
3524-
TrailingRequiresClause))
3524+
NameInfo, T, TInfo, D->getStorageClass(), D->UsesFPIntrin(),
3525+
D->isInlineSpecified(), D->hasWrittenPrototype(),
3526+
D->getConstexprKind(), TrailingRequiresClause))
35253527
return ToFunction;
35263528
}
35273529

clang/lib/AST/Decl.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2852,7 +2852,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
28522852
SourceLocation StartLoc,
28532853
const DeclarationNameInfo &NameInfo, QualType T,
28542854
TypeSourceInfo *TInfo, StorageClass S,
2855-
bool isInlineSpecified,
2855+
bool UsesFPIntrin, bool isInlineSpecified,
28562856
ConstexprSpecKind ConstexprKind,
28572857
Expr *TrailingRequiresClause)
28582858
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
@@ -2878,7 +2878,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
28782878
FunctionDeclBits.ConstexprKind = static_cast<uint64_t>(ConstexprKind);
28792879
FunctionDeclBits.InstantiationIsPending = false;
28802880
FunctionDeclBits.UsesSEHTry = false;
2881-
FunctionDeclBits.UsesFPIntrin = false;
2881+
FunctionDeclBits.UsesFPIntrin = UsesFPIntrin;
28822882
FunctionDeclBits.HasSkippedBody = false;
28832883
FunctionDeclBits.WillHaveBody = false;
28842884
FunctionDeclBits.IsMultiVersion = false;
@@ -4857,26 +4857,24 @@ ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C,
48574857
return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other);
48584858
}
48594859

4860-
FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
4861-
SourceLocation StartLoc,
4862-
const DeclarationNameInfo &NameInfo,
4863-
QualType T, TypeSourceInfo *TInfo,
4864-
StorageClass SC, bool isInlineSpecified,
4865-
bool hasWrittenPrototype,
4866-
ConstexprSpecKind ConstexprKind,
4867-
Expr *TrailingRequiresClause) {
4868-
FunctionDecl *New =
4869-
new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo,
4870-
SC, isInlineSpecified, ConstexprKind,
4871-
TrailingRequiresClause);
4860+
FunctionDecl *
4861+
FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
4862+
const DeclarationNameInfo &NameInfo, QualType T,
4863+
TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin,
4864+
bool isInlineSpecified, bool hasWrittenPrototype,
4865+
ConstexprSpecKind ConstexprKind,
4866+
Expr *TrailingRequiresClause) {
4867+
FunctionDecl *New = new (C, DC) FunctionDecl(
4868+
Function, C, DC, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
4869+
isInlineSpecified, ConstexprKind, TrailingRequiresClause);
48724870
New->setHasWrittenPrototype(hasWrittenPrototype);
48734871
return New;
48744872
}
48754873

48764874
FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
48774875
return new (C, ID) FunctionDecl(
48784876
Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(),
4879-
nullptr, SC_None, false, ConstexprSpecKind::Unspecified, nullptr);
4877+
nullptr, SC_None, false, false, ConstexprSpecKind::Unspecified, nullptr);
48804878
}
48814879

48824880
BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {

0 commit comments

Comments
 (0)