Skip to content

Commit f4aaed3

Browse files
author
Melanie Blower
committed
Reland D81869 "Modify FPFeatures to use delta not absolute settings"
This reverts commit defd43a. with correction to solve msan report To solve https://bugs.llvm.org/show_bug.cgi?id=46166 where the floating point settings in PCH files aren't compatible, rewrite FPFeatures to use a delta in the settings rather than absolute settings. With this patch, these floating point options can be benign. Reviewers: rjmccall Differential Revision: https://reviews.llvm.org/D81869
1 parent 89812ee commit f4aaed3

38 files changed

+579
-419
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,21 +2118,21 @@ class ParenExpr : public Expr {
21182118
///
21192119
class UnaryOperator final
21202120
: public Expr,
2121-
private llvm::TrailingObjects<UnaryOperator, FPOptions> {
2121+
private llvm::TrailingObjects<UnaryOperator, FPOptionsOverride> {
21222122
Stmt *Val;
21232123

2124-
size_t numTrailingObjects(OverloadToken<FPOptions>) const {
2124+
size_t numTrailingObjects(OverloadToken<FPOptionsOverride>) const {
21252125
return UnaryOperatorBits.HasFPFeatures ? 1 : 0;
21262126
}
21272127

2128-
FPOptions &getTrailingFPFeatures() {
2128+
FPOptionsOverride &getTrailingFPFeatures() {
21292129
assert(UnaryOperatorBits.HasFPFeatures);
2130-
return *getTrailingObjects<FPOptions>();
2130+
return *getTrailingObjects<FPOptionsOverride>();
21312131
}
21322132

2133-
const FPOptions &getTrailingFPFeatures() const {
2133+
const FPOptionsOverride &getTrailingFPFeatures() const {
21342134
assert(UnaryOperatorBits.HasFPFeatures);
2135-
return *getTrailingObjects<FPOptions>();
2135+
return *getTrailingObjects<FPOptionsOverride>();
21362136
}
21372137

21382138
public:
@@ -2141,7 +2141,7 @@ class UnaryOperator final
21412141
protected:
21422142
UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc, QualType type,
21432143
ExprValueKind VK, ExprObjectKind OK, SourceLocation l,
2144-
bool CanOverflow, FPOptions FPFeatures);
2144+
bool CanOverflow, FPOptionsOverride FPFeatures);
21452145

21462146
/// Build an empty unary operator.
21472147
explicit UnaryOperator(bool HasFPFeatures, EmptyShell Empty)
@@ -2156,7 +2156,7 @@ class UnaryOperator final
21562156
static UnaryOperator *Create(const ASTContext &C, Expr *input, Opcode opc,
21572157
QualType type, ExprValueKind VK,
21582158
ExprObjectKind OK, SourceLocation l,
2159-
bool CanOverflow, FPOptions FPFeatures);
2159+
bool CanOverflow, FPOptionsOverride FPFeatures);
21602160

21612161
Opcode getOpcode() const {
21622162
return static_cast<Opcode>(UnaryOperatorBits.Opc);
@@ -2182,13 +2182,13 @@ class UnaryOperator final
21822182
// Get the FP contractability status of this operator. Only meaningful for
21832183
// operations on floating point types.
21842184
bool isFPContractableWithinStatement(const LangOptions &LO) const {
2185-
return getFPFeatures(LO).allowFPContractWithinStatement();
2185+
return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
21862186
}
21872187

21882188
// Get the FENV_ACCESS status of this operator. Only meaningful for
21892189
// operations on floating point types.
21902190
bool isFEnvAccessOn(const LangOptions &LO) const {
2191-
return getFPFeatures(LO).allowFEnvAccess();
2191+
return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
21922192
}
21932193

21942194
/// isPostfix - Return true if this is a postfix operation, like x++.
@@ -2263,19 +2263,26 @@ class UnaryOperator final
22632263

22642264
protected:
22652265
/// Get FPFeatures from trailing storage
2266-
FPOptions getStoredFPFeatures() const { return getTrailingFPFeatures(); }
2266+
FPOptionsOverride getStoredFPFeatures() const {
2267+
return getTrailingFPFeatures();
2268+
}
22672269

22682270
/// Set FPFeatures in trailing storage, used only by Serialization
2269-
void setStoredFPFeatures(FPOptions F) { getTrailingFPFeatures() = F; }
2271+
void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
22702272

22712273
public:
22722274
// Get the FP features status of this operator. Only meaningful for
22732275
// operations on floating point types.
2274-
FPOptions getFPFeatures(const LangOptions &LO) const {
2276+
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
22752277
if (UnaryOperatorBits.HasFPFeatures)
2276-
return getStoredFPFeatures();
2278+
return getStoredFPFeatures().applyOverrides(LO);
22772279
return FPOptions::defaultWithoutTrailingStorage(LO);
22782280
}
2281+
FPOptionsOverride getFPOptionsOverride() const {
2282+
if (UnaryOperatorBits.HasFPFeatures)
2283+
return getStoredFPFeatures();
2284+
return FPOptionsOverride();
2285+
}
22792286

22802287
friend TrailingObjects;
22812288
friend class ASTReader;
@@ -3633,22 +3640,22 @@ class BinaryOperator : public Expr {
36333640
size_t offsetOfTrailingStorage() const;
36343641

36353642
/// Return a pointer to the trailing FPOptions
3636-
FPOptions *getTrailingFPFeatures() {
3643+
FPOptionsOverride *getTrailingFPFeatures() {
36373644
assert(BinaryOperatorBits.HasFPFeatures);
3638-
return reinterpret_cast<FPOptions *>(reinterpret_cast<char *>(this) +
3639-
offsetOfTrailingStorage());
3645+
return reinterpret_cast<FPOptionsOverride *>(
3646+
reinterpret_cast<char *>(this) + offsetOfTrailingStorage());
36403647
}
3641-
const FPOptions *getTrailingFPFeatures() const {
3648+
const FPOptionsOverride *getTrailingFPFeatures() const {
36423649
assert(BinaryOperatorBits.HasFPFeatures);
3643-
return reinterpret_cast<const FPOptions *>(
3650+
return reinterpret_cast<const FPOptionsOverride *>(
36443651
reinterpret_cast<const char *>(this) + offsetOfTrailingStorage());
36453652
}
36463653

36473654
/// Build a binary operator, assuming that appropriate storage has been
36483655
/// allocated for the trailing objects when needed.
36493656
BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
36503657
QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
3651-
SourceLocation opLoc, FPOptions FPFeatures);
3658+
SourceLocation opLoc, FPOptionsOverride FPFeatures);
36523659

36533660
/// Construct an empty binary operator.
36543661
explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) {
@@ -3661,7 +3668,7 @@ class BinaryOperator : public Expr {
36613668
static BinaryOperator *Create(const ASTContext &C, Expr *lhs, Expr *rhs,
36623669
Opcode opc, QualType ResTy, ExprValueKind VK,
36633670
ExprObjectKind OK, SourceLocation opLoc,
3664-
FPOptions FPFeatures);
3671+
FPOptionsOverride FPFeatures);
36653672
SourceLocation getExprLoc() const { return getOperatorLoc(); }
36663673
SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; }
36673674
void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
@@ -3808,40 +3815,48 @@ class BinaryOperator : public Expr {
38083815
bool hasStoredFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; }
38093816

38103817
/// Get FPFeatures from trailing storage
3811-
FPOptions getStoredFPFeatures() const {
3818+
FPOptionsOverride getStoredFPFeatures() const {
38123819
assert(hasStoredFPFeatures());
38133820
return *getTrailingFPFeatures();
38143821
}
38153822
/// Set FPFeatures in trailing storage, used only by Serialization
3816-
void setStoredFPFeatures(FPOptions F) {
3823+
void setStoredFPFeatures(FPOptionsOverride F) {
38173824
assert(BinaryOperatorBits.HasFPFeatures);
38183825
*getTrailingFPFeatures() = F;
38193826
}
38203827

38213828
// Get the FP features status of this operator. Only meaningful for
38223829
// operations on floating point types.
3823-
FPOptions getFPFeatures(const LangOptions &LO) const {
3830+
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
38243831
if (BinaryOperatorBits.HasFPFeatures)
3825-
return getStoredFPFeatures();
3832+
return getStoredFPFeatures().applyOverrides(LO);
38263833
return FPOptions::defaultWithoutTrailingStorage(LO);
38273834
}
38283835

3836+
// This is used in ASTImporter
3837+
FPOptionsOverride getFPFeatures(const LangOptions &LO) const {
3838+
if (BinaryOperatorBits.HasFPFeatures)
3839+
return getStoredFPFeatures();
3840+
return FPOptionsOverride();
3841+
}
3842+
38293843
// Get the FP contractability status of this operator. Only meaningful for
38303844
// operations on floating point types.
38313845
bool isFPContractableWithinStatement(const LangOptions &LO) const {
3832-
return getFPFeatures(LO).allowFPContractWithinStatement();
3846+
return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
38333847
}
38343848

38353849
// Get the FENV_ACCESS status of this operator. Only meaningful for
38363850
// operations on floating point types.
38373851
bool isFEnvAccessOn(const LangOptions &LO) const {
3838-
return getFPFeatures(LO).allowFEnvAccess();
3852+
return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
38393853
}
38403854

38413855
protected:
38423856
BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
38433857
QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
3844-
SourceLocation opLoc, FPOptions FPFeatures, bool dead2);
3858+
SourceLocation opLoc, FPOptionsOverride FPFeatures,
3859+
bool dead2);
38453860

38463861
/// Construct an empty BinaryOperator, SC is CompoundAssignOperator.
38473862
BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
@@ -3851,7 +3866,7 @@ class BinaryOperator : public Expr {
38513866
/// Return the size in bytes needed for the trailing objects.
38523867
/// Used to allocate the right amount of storage.
38533868
static unsigned sizeOfTrailingObjects(bool HasFPFeatures) {
3854-
return HasFPFeatures * sizeof(FPOptions);
3869+
return HasFPFeatures * sizeof(FPOptionsOverride);
38553870
}
38563871
};
38573872

@@ -3873,7 +3888,7 @@ class CompoundAssignOperator : public BinaryOperator {
38733888
protected:
38743889
CompoundAssignOperator(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc,
38753890
QualType ResType, ExprValueKind VK, ExprObjectKind OK,
3876-
SourceLocation OpLoc, FPOptions FPFeatures,
3891+
SourceLocation OpLoc, FPOptionsOverride FPFeatures,
38773892
QualType CompLHSType, QualType CompResultType)
38783893
: BinaryOperator(C, lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
38793894
true),
@@ -3889,7 +3904,7 @@ class CompoundAssignOperator : public BinaryOperator {
38893904
static CompoundAssignOperator *
38903905
Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
38913906
ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
3892-
FPOptions FPFeatures, QualType CompLHSType = QualType(),
3907+
FPOptionsOverride FPFeatures, QualType CompLHSType = QualType(),
38933908
QualType CompResultType = QualType());
38943909

38953910
// The two computation types are the type the LHS is converted

clang/include/clang/AST/ExprCXX.h

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class CXXOperatorCallExpr final : public CallExpr {
8484
friend class ASTStmtWriter;
8585

8686
SourceRange Range;
87+
FPOptionsOverride Overrides;
8788

8889
// CXXOperatorCallExpr has some trailing objects belonging
8990
// to CallExpr. See CallExpr for the details.
@@ -92,7 +93,7 @@ class CXXOperatorCallExpr final : public CallExpr {
9293

9394
CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn,
9495
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
95-
SourceLocation OperatorLoc, FPOptions FPFeatures,
96+
SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
9697
ADLCallKind UsesADL);
9798

9899
CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty);
@@ -101,7 +102,7 @@ class CXXOperatorCallExpr final : public CallExpr {
101102
static CXXOperatorCallExpr *
102103
Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
103104
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
104-
SourceLocation OperatorLoc, FPOptions FPFeatures,
105+
SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
105106
ADLCallKind UsesADL = NotADL);
106107

107108
static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
@@ -164,20 +165,10 @@ class CXXOperatorCallExpr final : public CallExpr {
164165
return T->getStmtClass() == CXXOperatorCallExprClass;
165166
}
166167

167-
// Set the FP contractability status of this operator. Only meaningful for
168+
// Set the FPFeatures status of this operator. Only meaningful for
168169
// operations on floating point types.
169-
void setFPFeatures(FPOptions F) {
170-
CXXOperatorCallExprBits.FPFeatures = F.getAsOpaqueInt();
171-
}
172-
FPOptions getFPFeatures() const {
173-
return FPOptions(CXXOperatorCallExprBits.FPFeatures);
174-
}
175-
176-
// Get the FP contractability status of this operator. Only meaningful for
177-
// operations on floating point types.
178-
bool isFPContractableWithinStatement() const {
179-
return getFPFeatures().allowFPContractWithinStatement();
180-
}
170+
void setFPFeatures(FPOptionsOverride F) { Overrides = F; }
171+
FPOptionsOverride getFPFeatures() const { return Overrides; }
181172
};
182173

183174
/// Represents a call to a member function that

clang/include/clang/AST/Stmt.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,6 @@ class alignas(void *) Stmt {
614614
/// The kind of this overloaded operator. One of the enumerator
615615
/// value of OverloadedOperatorKind.
616616
unsigned OperatorKind : 6;
617-
618-
// Only meaningful for floating point types.
619-
unsigned FPFeatures : 14;
620617
};
621618

622619
class CXXRewrittenBinaryOperatorBitfields {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===--- FPOptions.def - Floating Point Options database --------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// This file defines the Floating Point language options. Users of this file
10+
// must define the FPOPT macro to make use of this information.
11+
#ifndef OPTION
12+
# error Define the OPTION macro to handle floating point language options
13+
#endif
14+
15+
// OPTION(name, type, width, previousName)
16+
OPTION(FPContractMode, LangOptions::FPModeKind, 2, First)
17+
OPTION(RoundingMode, RoundingMode, 3, FPContractMode)
18+
OPTION(FPExceptionMode, LangOptions::FPExceptionModeKind, 2, RoundingMode)
19+
OPTION(AllowFEnvAccess, bool, 1, FPExceptionMode)
20+
OPTION(AllowFPReassociate, bool, 1, AllowFEnvAccess)
21+
OPTION(NoHonorNaNs, bool, 1, AllowFPReassociate)
22+
OPTION(NoHonorInfs, bool, 1, NoHonorNaNs)
23+
OPTION(NoSignedZero, bool, 1, NoHonorInfs)
24+
OPTION(AllowReciprocal, bool, 1, NoSignedZero)
25+
OPTION(AllowApproxFunc, bool, 1, AllowReciprocal)
26+
#undef OPTION

clang/include/clang/Basic/LangOptions.def

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,12 @@ COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
193193
COMPATIBLE_LANGOPT(FastMath , 1, 0, "fast FP math optimizations, and __FAST_MATH__ predefined macro")
194194
COMPATIBLE_LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
195195
COMPATIBLE_LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math")
196-
COMPATIBLE_LANGOPT(AllowFPReassoc , 1, 0, "Permit Floating Point reassociation")
197-
COMPATIBLE_LANGOPT(NoHonorNaNs , 1, 0, "Permit Floating Point optimization without regard to NaN")
198-
COMPATIBLE_LANGOPT(NoHonorInfs , 1, 0, "Permit Floating Point optimization without regard to infinities")
199-
COMPATIBLE_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization without regard to signed zeros")
200-
COMPATIBLE_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal")
201-
COMPATIBLE_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation")
196+
BENIGN_LANGOPT(AllowFPReassoc , 1, 0, "Permit Floating Point reassociation")
197+
BENIGN_LANGOPT(NoHonorNaNs , 1, 0, "Permit Floating Point optimization without regard to NaN")
198+
BENIGN_LANGOPT(NoHonorInfs , 1, 0, "Permit Floating Point optimization without regard to infinities")
199+
BENIGN_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization without regard to signed zeros")
200+
BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal")
201+
BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation")
202202

203203
BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars")
204204

@@ -271,9 +271,9 @@ BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
271271
LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
272272
LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
273273
/// FP_CONTRACT mode (on/off/fast).
274-
ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type")
275-
ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, "FP Rounding Mode type")
276-
ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
274+
BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type")
275+
BENIGN_ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, "FP Rounding Mode type")
276+
BENIGN_ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
277277
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
278278
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
279279
LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")

0 commit comments

Comments
 (0)