[clang] b55d723 - Revert "Modify FPFeatures to use delta not absolute settings"
Melanie Blower via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 26 07:53:24 PDT 2020
Author: Melanie Blower
Date: 2020-06-26T07:52:57-07:00
New Revision: b55d723ed61052b77e720dcffecac43abe873186
URL: https://github.com/llvm/llvm-project/commit/b55d723ed61052b77e720dcffecac43abe873186
DIFF: https://github.com/llvm/llvm-project/commit/b55d723ed61052b77e720dcffecac43abe873186.diff
LOG: Revert "Modify FPFeatures to use delta not absolute settings"
This reverts commit 3a748cbf86cea3844fada04eeff4cc64b01f67e0.
I'm reverting this commit because I forgot to format the commit message
propertly. Sorry for the thrash.
Added:
Modified:
clang/include/clang/AST/Expr.h
clang/include/clang/AST/ExprCXX.h
clang/include/clang/AST/Stmt.h
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/Sema.h
clang/include/clang/Serialization/ASTWriter.h
clang/include/clang/module.modulemap
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/Expr.cpp
clang/lib/AST/ExprCXX.cpp
clang/lib/Analysis/BodyFarm.cpp
clang/lib/Basic/LangOptions.cpp
clang/lib/CodeGen/CGExprScalar.cpp
clang/lib/CodeGen/CGObjC.cpp
clang/lib/CodeGen/CGStmtOpenMP.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
clang/lib/Frontend/Rewrite/RewriteObjC.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Parse/ParsePragma.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaAttr.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprObjC.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaPseudoObject.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/test/CodeGen/fp-floatcontrol-pragma.cpp
clang/test/CodeGenOpenCL/relaxed-fpmath.cl
clang/test/PCH/pragma-floatcontrol.c
Removed:
clang/include/clang/Basic/FPOptions.def
clang/test/SemaOpenCL/fp-options.cl
################################################################################
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 66eafaaab715..8ee8aa96ae63 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -2118,21 +2118,21 @@ class ParenExpr : public Expr {
///
class UnaryOperator final
: public Expr,
- private llvm::TrailingObjects<UnaryOperator, FPOptionsOverride> {
+ private llvm::TrailingObjects<UnaryOperator, FPOptions> {
Stmt *Val;
- size_t numTrailingObjects(OverloadToken<FPOptionsOverride>) const {
+ size_t numTrailingObjects(OverloadToken<FPOptions>) const {
return UnaryOperatorBits.HasFPFeatures ? 1 : 0;
}
- FPOptionsOverride &getTrailingFPFeatures() {
+ FPOptions &getTrailingFPFeatures() {
assert(UnaryOperatorBits.HasFPFeatures);
- return *getTrailingObjects<FPOptionsOverride>();
+ return *getTrailingObjects<FPOptions>();
}
- const FPOptionsOverride &getTrailingFPFeatures() const {
+ const FPOptions &getTrailingFPFeatures() const {
assert(UnaryOperatorBits.HasFPFeatures);
- return *getTrailingObjects<FPOptionsOverride>();
+ return *getTrailingObjects<FPOptions>();
}
public:
@@ -2141,7 +2141,7 @@ class UnaryOperator final
protected:
UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc, QualType type,
ExprValueKind VK, ExprObjectKind OK, SourceLocation l,
- bool CanOverflow, FPOptionsOverride FPFeatures);
+ bool CanOverflow, FPOptions FPFeatures);
/// Build an empty unary operator.
explicit UnaryOperator(bool HasFPFeatures, EmptyShell Empty)
@@ -2156,7 +2156,7 @@ class UnaryOperator final
static UnaryOperator *Create(const ASTContext &C, Expr *input, Opcode opc,
QualType type, ExprValueKind VK,
ExprObjectKind OK, SourceLocation l,
- bool CanOverflow, FPOptionsOverride FPFeatures);
+ bool CanOverflow, FPOptions FPFeatures);
Opcode getOpcode() const {
return static_cast<Opcode>(UnaryOperatorBits.Opc);
@@ -2182,13 +2182,13 @@ class UnaryOperator final
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
bool isFPContractableWithinStatement(const LangOptions &LO) const {
- return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
+ return getFPFeatures(LO).allowFPContractWithinStatement();
}
// Get the FENV_ACCESS status of this operator. Only meaningful for
// operations on floating point types.
bool isFEnvAccessOn(const LangOptions &LO) const {
- return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
+ return getFPFeatures(LO).allowFEnvAccess();
}
/// isPostfix - Return true if this is a postfix operation, like x++.
@@ -2263,25 +2263,18 @@ class UnaryOperator final
protected:
/// Get FPFeatures from trailing storage
- FPOptionsOverride getStoredFPFeatures() const {
- return getTrailingFPFeatures();
- }
+ FPOptions getStoredFPFeatures() const { return getTrailingFPFeatures(); }
/// Set FPFeatures in trailing storage, used only by Serialization
- void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
+ void setStoredFPFeatures(FPOptions F) { getTrailingFPFeatures() = F; }
public:
// Get the FP features status of this operator. Only meaningful for
// operations on floating point types.
- FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
- if (UnaryOperatorBits.HasFPFeatures)
- return getStoredFPFeatures().applyOverrides(LO);
- return FPOptions::defaultWithoutTrailingStorage(LO);
- }
- FPOptionsOverride getFPOptionsOverride() const {
+ FPOptions getFPFeatures(const LangOptions &LO) const {
if (UnaryOperatorBits.HasFPFeatures)
return getStoredFPFeatures();
- return FPOptionsOverride();
+ return FPOptions::defaultWithoutTrailingStorage(LO);
}
friend TrailingObjects;
@@ -3640,14 +3633,14 @@ class BinaryOperator : public Expr {
size_t offsetOfTrailingStorage() const;
/// Return a pointer to the trailing FPOptions
- FPOptionsOverride *getTrailingFPFeatures() {
+ FPOptions *getTrailingFPFeatures() {
assert(BinaryOperatorBits.HasFPFeatures);
- return reinterpret_cast<FPOptionsOverride *>(
- reinterpret_cast<char *>(this) + offsetOfTrailingStorage());
+ return reinterpret_cast<FPOptions *>(reinterpret_cast<char *>(this) +
+ offsetOfTrailingStorage());
}
- const FPOptionsOverride *getTrailingFPFeatures() const {
+ const FPOptions *getTrailingFPFeatures() const {
assert(BinaryOperatorBits.HasFPFeatures);
- return reinterpret_cast<const FPOptionsOverride *>(
+ return reinterpret_cast<const FPOptions *>(
reinterpret_cast<const char *>(this) + offsetOfTrailingStorage());
}
@@ -3655,7 +3648,7 @@ class BinaryOperator : public Expr {
/// allocated for the trailing objects when needed.
BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, FPOptionsOverride FPFeatures);
+ SourceLocation opLoc, FPOptions FPFeatures);
/// Construct an empty binary operator.
explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) {
@@ -3668,7 +3661,7 @@ class BinaryOperator : public Expr {
static BinaryOperator *Create(const ASTContext &C, Expr *lhs, Expr *rhs,
Opcode opc, QualType ResTy, ExprValueKind VK,
ExprObjectKind OK, SourceLocation opLoc,
- FPOptionsOverride FPFeatures);
+ FPOptions FPFeatures);
SourceLocation getExprLoc() const { return getOperatorLoc(); }
SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; }
void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; }
@@ -3815,48 +3808,40 @@ class BinaryOperator : public Expr {
bool hasStoredFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; }
/// Get FPFeatures from trailing storage
- FPOptionsOverride getStoredFPFeatures() const {
+ FPOptions getStoredFPFeatures() const {
assert(hasStoredFPFeatures());
return *getTrailingFPFeatures();
}
/// Set FPFeatures in trailing storage, used only by Serialization
- void setStoredFPFeatures(FPOptionsOverride F) {
+ void setStoredFPFeatures(FPOptions F) {
assert(BinaryOperatorBits.HasFPFeatures);
*getTrailingFPFeatures() = F;
}
// Get the FP features status of this operator. Only meaningful for
// operations on floating point types.
- FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
- if (BinaryOperatorBits.HasFPFeatures)
- return getStoredFPFeatures().applyOverrides(LO);
- return FPOptions::defaultWithoutTrailingStorage(LO);
- }
-
- // This is used in ASTImporter
- FPOptionsOverride getFPFeatures(const LangOptions &LO) const {
+ FPOptions getFPFeatures(const LangOptions &LO) const {
if (BinaryOperatorBits.HasFPFeatures)
return getStoredFPFeatures();
- return FPOptionsOverride();
+ return FPOptions::defaultWithoutTrailingStorage(LO);
}
// Get the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
bool isFPContractableWithinStatement(const LangOptions &LO) const {
- return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
+ return getFPFeatures(LO).allowFPContractWithinStatement();
}
// Get the FENV_ACCESS status of this operator. Only meaningful for
// operations on floating point types.
bool isFEnvAccessOn(const LangOptions &LO) const {
- return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
+ return getFPFeatures(LO).allowFEnvAccess();
}
protected:
BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation opLoc, FPOptionsOverride FPFeatures,
- bool dead2);
+ SourceLocation opLoc, FPOptions FPFeatures, bool dead2);
/// Construct an empty BinaryOperator, SC is CompoundAssignOperator.
BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
@@ -3866,7 +3851,7 @@ class BinaryOperator : public Expr {
/// Return the size in bytes needed for the trailing objects.
/// Used to allocate the right amount of storage.
static unsigned sizeOfTrailingObjects(bool HasFPFeatures) {
- return HasFPFeatures * sizeof(FPOptionsOverride);
+ return HasFPFeatures * sizeof(FPOptions);
}
};
@@ -3888,7 +3873,7 @@ class CompoundAssignOperator : public BinaryOperator {
protected:
CompoundAssignOperator(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc,
QualType ResType, ExprValueKind VK, ExprObjectKind OK,
- SourceLocation OpLoc, FPOptionsOverride FPFeatures,
+ SourceLocation OpLoc, FPOptions FPFeatures,
QualType CompLHSType, QualType CompResultType)
: BinaryOperator(C, lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
true),
@@ -3904,7 +3889,7 @@ class CompoundAssignOperator : public BinaryOperator {
static CompoundAssignOperator *
Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
- FPOptionsOverride FPFeatures, QualType CompLHSType = QualType(),
+ FPOptions FPFeatures, QualType CompLHSType = QualType(),
QualType CompResultType = QualType());
// The two computation types are the type the LHS is converted
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 9906cd9df074..4c65daaa63fc 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -84,7 +84,6 @@ class CXXOperatorCallExpr final : public CallExpr {
friend class ASTStmtWriter;
SourceRange Range;
- FPOptionsOverride Overrides;
// CXXOperatorCallExpr has some trailing objects belonging
// to CallExpr. See CallExpr for the details.
@@ -93,7 +92,7 @@ class CXXOperatorCallExpr final : public CallExpr {
CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
+ SourceLocation OperatorLoc, FPOptions FPFeatures,
ADLCallKind UsesADL);
CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty);
@@ -102,7 +101,7 @@ class CXXOperatorCallExpr final : public CallExpr {
static CXXOperatorCallExpr *
Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
+ SourceLocation OperatorLoc, FPOptions FPFeatures,
ADLCallKind UsesADL = NotADL);
static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
@@ -165,10 +164,20 @@ class CXXOperatorCallExpr final : public CallExpr {
return T->getStmtClass() == CXXOperatorCallExprClass;
}
- // Set the FPFeatures status of this operator. Only meaningful for
+ // Set the FP contractability status of this operator. Only meaningful for
// operations on floating point types.
- void setFPFeatures(FPOptionsOverride F) { Overrides = F; }
- FPOptionsOverride getFPFeatures() const { return Overrides; }
+ void setFPFeatures(FPOptions F) {
+ CXXOperatorCallExprBits.FPFeatures = F.getAsOpaqueInt();
+ }
+ FPOptions getFPFeatures() const {
+ return FPOptions(CXXOperatorCallExprBits.FPFeatures);
+ }
+
+ // Get the FP contractability status of this operator. Only meaningful for
+ // operations on floating point types.
+ bool isFPContractableWithinStatement() const {
+ return getFPFeatures().allowFPContractWithinStatement();
+ }
};
/// Represents a call to a member function that
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 6c3f036d45ca..a226790aa76c 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -614,6 +614,9 @@ class alignas(void *) Stmt {
/// The kind of this overloaded operator. One of the enumerator
/// value of OverloadedOperatorKind.
unsigned OperatorKind : 6;
+
+ // Only meaningful for floating point types.
+ unsigned FPFeatures : 14;
};
class CXXRewrittenBinaryOperatorBitfields {
diff --git a/clang/include/clang/Basic/FPOptions.def b/clang/include/clang/Basic/FPOptions.def
deleted file mode 100644
index 6b6789b8ecc8..000000000000
--- a/clang/include/clang/Basic/FPOptions.def
+++ /dev/null
@@ -1,26 +0,0 @@
-//===--- FPOptions.def - Floating Point Options database --------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// This file defines the Floating Point language options. Users of this file
-// must define the FPOPT macro to make use of this information.
-#ifndef OPTION
-# error Define the OPTION macro to handle floating point language options
-#endif
-
-// OPTION(name, type, width, previousName)
-OPTION(FPContractMode, LangOptions::FPModeKind, 2, First)
-OPTION(RoundingMode, RoundingMode, 3, FPContractMode)
-OPTION(FPExceptionMode, LangOptions::FPExceptionModeKind, 2, RoundingMode)
-OPTION(AllowFEnvAccess, bool, 1, FPExceptionMode)
-OPTION(AllowFPReassociate, bool, 1, AllowFEnvAccess)
-OPTION(NoHonorNaNs, bool, 1, AllowFPReassociate)
-OPTION(NoHonorInfs, bool, 1, NoHonorNaNs)
-OPTION(NoSignedZero, bool, 1, NoHonorInfs)
-OPTION(AllowReciprocal, bool, 1, NoSignedZero)
-OPTION(AllowApproxFunc, bool, 1, AllowReciprocal)
-#undef OPTION
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index a20639c828c3..b0d9b3a0c632 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -193,12 +193,12 @@ COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
COMPATIBLE_LANGOPT(FastMath , 1, 0, "fast FP math optimizations, and __FAST_MATH__ predefined macro")
COMPATIBLE_LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro")
COMPATIBLE_LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math")
-BENIGN_LANGOPT(AllowFPReassoc , 1, 0, "Permit Floating Point reassociation")
-BENIGN_LANGOPT(NoHonorNaNs , 1, 0, "Permit Floating Point optimization without regard to NaN")
-BENIGN_LANGOPT(NoHonorInfs , 1, 0, "Permit Floating Point optimization without regard to infinities")
-BENIGN_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization without regard to signed zeros")
-BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal")
-BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation")
+COMPATIBLE_LANGOPT(AllowFPReassoc , 1, 0, "Permit Floating Point reassociation")
+COMPATIBLE_LANGOPT(NoHonorNaNs , 1, 0, "Permit Floating Point optimization without regard to NaN")
+COMPATIBLE_LANGOPT(NoHonorInfs , 1, 0, "Permit Floating Point optimization without regard to infinities")
+COMPATIBLE_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization without regard to signed zeros")
+COMPATIBLE_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal")
+COMPATIBLE_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation")
BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars")
@@ -271,9 +271,9 @@ BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
/// FP_CONTRACT mode (on/off/fast).
-BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type")
-BENIGN_ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, "FP Rounding Mode type")
-BENIGN_ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
+ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type")
+ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, "FP Rounding Mode type")
+ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index ca0e7fceddb8..7b92a8964862 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -366,176 +366,176 @@ class LangOptions : public LangOptionsBase {
};
/// Floating point control options
-class FPOptionsOverride;
class FPOptions {
-public:
- // We start by defining the layout.
- using storage_type = uint16_t;
-
using RoundingMode = llvm::RoundingMode;
- // Define a fake option named "First" so that we have a PREVIOUS even for the
- // real first option.
- static constexpr storage_type FirstShift = 0, FirstWidth = 0;
-#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
- static constexpr storage_type NAME##Shift = \
- PREVIOUS##Shift + PREVIOUS##Width; \
- static constexpr storage_type NAME##Width = WIDTH; \
- static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1) \
- << NAME##Shift;
-#include "clang/Basic/FPOptions.def"
-
-private:
- storage_type Value;
-
public:
- FPOptions() : Value(0) {
- setFPContractMode(LangOptions::FPM_Off);
- setRoundingMode(static_cast<RoundingMode>(LangOptions::FPR_ToNearest));
- setFPExceptionMode(LangOptions::FPE_Ignore);
- }
+ FPOptions()
+ : fp_contract(LangOptions::FPM_Off), fenv_access(LangOptions::FPM_Off),
+ rounding(LangOptions::FPR_ToNearest),
+ exceptions(LangOptions::FPE_Ignore), allow_reassoc(0), no_nans(0),
+ no_infs(0), no_signed_zeros(0), allow_reciprocal(0), approx_func(0) {}
+
// Used for serializing.
explicit FPOptions(unsigned I) { getFromOpaqueInt(I); }
- explicit FPOptions(const LangOptions &LO) {
- setFPContractMode(LO.getDefaultFPContractMode());
- setRoundingMode(LO.getFPRoundingMode());
- setFPExceptionMode(LO.getFPExceptionMode());
- setAllowFEnvAccess(LangOptions::FPM_Off),
- setAllowFPReassociate(LO.AllowFPReassoc);
- setNoHonorNaNs(LO.NoHonorNaNs);
- setNoHonorInfs(LO.NoHonorInfs);
- setNoSignedZero(LO.NoSignedZero);
- setAllowReciprocal(LO.AllowRecip);
- setAllowApproxFunc(LO.ApproxFunc);
+ explicit FPOptions(const LangOptions &LangOpts)
+ : fp_contract(LangOpts.getDefaultFPContractMode()),
+ fenv_access(LangOptions::FPM_Off),
+ rounding(static_cast<unsigned>(LangOpts.getFPRoundingMode())),
+ exceptions(LangOpts.getFPExceptionMode()),
+ allow_reassoc(LangOpts.AllowFPReassoc), no_nans(LangOpts.NoHonorNaNs),
+ no_infs(LangOpts.NoHonorInfs), no_signed_zeros(LangOpts.NoSignedZero),
+ allow_reciprocal(LangOpts.AllowRecip),
+ approx_func(LangOpts.ApproxFunc) {}
+ // FIXME: Use getDefaultFEnvAccessMode() when available.
+
+ void setFastMath(bool B = true) {
+ allow_reassoc = no_nans = no_infs = no_signed_zeros = approx_func =
+ allow_reciprocal = B;
}
+ /// Return the default value of FPOptions that's used when trailing
+ /// storage isn't required.
+ static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO);
+
+ /// Does this FPOptions require trailing storage when stored in various
+ /// AST nodes, or can it be recreated using `defaultWithoutTrailingStorage`?
+ bool requiresTrailingStorage(const LangOptions &LO);
+
bool allowFPContractWithinStatement() const {
- return getFPContractMode() == LangOptions::FPM_On;
- }
- void setAllowFPContractWithinStatement() {
- setFPContractMode(LangOptions::FPM_On);
+ return fp_contract == LangOptions::FPM_On;
}
bool allowFPContractAcrossStatement() const {
- return getFPContractMode() == LangOptions::FPM_Fast;
+ return fp_contract == LangOptions::FPM_Fast;
}
- void setAllowFPContractAcrossStatement() {
- setFPContractMode(LangOptions::FPM_Fast);
+
+ void setAllowFPContractWithinStatement() {
+ fp_contract = LangOptions::FPM_On;
}
- bool isFPConstrained() const {
- return getRoundingMode() !=
- static_cast<unsigned>(RoundingMode::NearestTiesToEven) ||
- getFPExceptionMode() != LangOptions::FPE_Ignore ||
- getAllowFEnvAccess();
+ void setAllowFPContractAcrossStatement() {
+ fp_contract = LangOptions::FPM_Fast;
}
- bool operator==(FPOptions other) const { return Value == other.Value; }
+ void setDisallowFPContract() { fp_contract = LangOptions::FPM_Off; }
- /// Return the default value of FPOptions that's used when trailing
- /// storage isn't required.
- static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO);
+ bool allowFEnvAccess() const { return fenv_access == LangOptions::FPM_On; }
- storage_type getAsOpaqueInt() const { return Value; }
- void getFromOpaqueInt(storage_type value) { Value = value; }
+ void setAllowFEnvAccess() { fenv_access = LangOptions::FPM_On; }
- // We can define most of the accessors automatically:
-#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
- unsigned get##NAME() const { \
- return static_cast<unsigned>(TYPE((Value & NAME##Mask) >> NAME##Shift)); \
- } \
- void set##NAME(TYPE value) { \
- Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \
+ void setFPPreciseEnabled(bool Value) {
+ if (Value) {
+ /* Precise mode implies fp_contract=on and disables ffast-math */
+ setFastMath(false);
+ setAllowFPContractWithinStatement();
+ } else {
+ /* Precise mode implies fp_contract=fast and enables ffast-math */
+ setFastMath(true);
+ setAllowFPContractAcrossStatement();
+ }
}
-#include "clang/Basic/FPOptions.def"
- LLVM_DUMP_METHOD void dump();
-};
-
-/// The FPOptions override type is value of the new FPOptions
-/// plus a mask showing which fields are actually set in it:
-class FPOptionsOverride {
- FPOptions Options;
- FPOptions::storage_type OverrideMask = 0;
-
-public:
- using RoundingMode = llvm::RoundingMode;
- FPOptionsOverride() {}
- // Used for serializing.
- explicit FPOptionsOverride(unsigned I) { getFromOpaqueInt(I); }
+ void setDisallowFEnvAccess() { fenv_access = LangOptions::FPM_Off; }
- bool requiresTrailingStorage() const { return OverrideMask != 0; }
+ RoundingMode getRoundingMode() const {
+ return static_cast<RoundingMode>(rounding);
+ }
- void setAllowFPContractWithinStatement() {
- setFPContractModeOverride(LangOptions::FPM_On);
+ void setRoundingMode(RoundingMode RM) {
+ rounding = static_cast<unsigned>(RM);
}
- void setAllowFPContractAcrossStatement() {
- setFPContractModeOverride(LangOptions::FPM_Fast);
+ LangOptions::FPExceptionModeKind getExceptionMode() const {
+ return static_cast<LangOptions::FPExceptionModeKind>(exceptions);
}
- void setDisallowFPContract() {
- setFPContractModeOverride(LangOptions::FPM_Off);
+ void setExceptionMode(LangOptions::FPExceptionModeKind EM) {
+ exceptions = EM;
}
- void setFPPreciseEnabled(bool Value) {
- setAllowFPReassociateOverride(!Value);
- setNoHonorNaNsOverride(!Value);
- setNoHonorInfsOverride(!Value);
- setNoSignedZeroOverride(!Value);
- setAllowReciprocalOverride(!Value);
- setAllowApproxFuncOverride(!Value);
- if (Value)
- /* Precise mode implies fp_contract=on and disables ffast-math */
- setAllowFPContractWithinStatement();
- else
- /* Precise mode disabled sets fp_contract=fast and enables ffast-math */
- setAllowFPContractAcrossStatement();
+ /// FMF Flag queries
+ bool allowAssociativeMath() const { return allow_reassoc; }
+ bool noHonorNaNs() const { return no_nans; }
+ bool noHonorInfs() const { return no_infs; }
+ bool noSignedZeros() const { return no_signed_zeros; }
+ bool allowReciprocalMath() const { return allow_reciprocal; }
+ bool allowApproximateFunctions() const { return approx_func; }
+
+ /// Flag setters
+ void setAllowAssociativeMath(bool B = true) { allow_reassoc = B; }
+ void setNoHonorNaNs(bool B = true) { no_nans = B; }
+ void setNoHonorInfs(bool B = true) { no_infs = B; }
+ void setNoSignedZeros(bool B = true) { no_signed_zeros = B; }
+ void setAllowReciprocalMath(bool B = true) { allow_reciprocal = B; }
+ void setAllowApproximateFunctions(bool B = true) { approx_func = B; }
+
+ bool isFPConstrained() const {
+ return getRoundingMode() != RoundingMode::NearestTiesToEven ||
+ getExceptionMode() != LangOptions::FPE_Ignore ||
+ allowFEnvAccess();
}
+ /// Used to serialize this.
unsigned getAsOpaqueInt() const {
- return Options.getAsOpaqueInt() << 16 | OverrideMask;
- }
- void getFromOpaqueInt(unsigned I) {
- OverrideMask = I & 0xffff;
- Options.getFromOpaqueInt(I >> 16);
+ return fp_contract | (fenv_access << 2) | (rounding << 3) |
+ (exceptions << 6) | (allow_reassoc << 8) | (no_nans << 9) |
+ (no_infs << 10) | (no_signed_zeros << 11) |
+ (allow_reciprocal << 12) | (approx_func << 13);
}
- FPOptions applyOverrides(const LangOptions &LO) {
- FPOptions Base(LO);
- FPOptions result((Base.getAsOpaqueInt() & ~OverrideMask) |
- (Options.getAsOpaqueInt() & OverrideMask));
- return result;
+ /// Used with getAsOpaqueInt() to manage the float_control pragma stack.
+ void getFromOpaqueInt(unsigned I) {
+ fp_contract = (static_cast<LangOptions::FPModeKind>(I & 3));
+ fenv_access = ((I >> 2) & 1);
+ rounding = static_cast<unsigned>(static_cast<RoundingMode>((I >> 3) & 7));
+ exceptions = (static_cast<LangOptions::FPExceptionModeKind>((I >> 6) & 3));
+ allow_reassoc = ((I >> 8) & 1);
+ no_nans = ((I >> 9) & 1);
+ no_infs = ((I >> 10) & 1);
+ no_signed_zeros = ((I >> 11) & 1);
+ allow_reciprocal = ((I >> 12) & 1);
+ approx_func = ((I >> 13) & 1);
}
- bool operator==(FPOptionsOverride other) const {
- return Options == other.Options && OverrideMask == other.OverrideMask;
- }
- bool operator!=(FPOptionsOverride other) const { return !(*this == other); }
-
-#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
- bool has##NAME##Override() const { \
- return OverrideMask & FPOptions::NAME##Mask; \
- } \
- unsigned get##NAME##Override() const { \
- assert(has##NAME##Override()); \
- return Options.get##NAME(); \
- } \
- void clear##NAME##Override() { \
- /* Clear the actual value so that we don't have spurious
diff erences when \
- * testing equality. */ \
- Options.set##NAME(TYPE(0)); \
- OverrideMask &= ~FPOptions::NAME##Mask; \
- } \
- void set##NAME##Override(TYPE value) { \
- Options.set##NAME(value); \
- OverrideMask |= FPOptions::NAME##Mask; \
- }
-#include "clang/Basic/FPOptions.def"
- LLVM_DUMP_METHOD void dump();
+private:
+ /// Adjust BinaryOperatorBitfields::FPFeatures and
+ /// CXXOperatorCallExprBitfields::FPFeatures to match the total bit-field size
+ /// of these fields.
+ unsigned fp_contract : 2;
+ unsigned fenv_access : 1;
+ unsigned rounding : 3;
+ unsigned exceptions : 2;
+ /// Allow reassociation transformations for floating-point instructions
+ /// across multiple statements.
+ unsigned allow_reassoc : 1;
+ /// No NaNs - Allow optimizations to assume the arguments and result
+ /// are not NaN. If an argument is a nan, or the result would be a nan,
+ /// it produces a :ref:`poison value <poisonvalues>` instead.
+ unsigned no_nans : 1;
+ /// No Infs - Allow optimizations to assume the arguments and result
+ /// are not +/-Inf. If an argument is +/-Inf, or the result would be +/-Inf,
+ /// it produces a :ref:`poison value <poisonvalues>` instead.
+ unsigned no_infs : 1;
+ /// No Signed Zeros - Allow optimizations to treat the sign of a zero
+ /// argument or result as insignificant.
+ unsigned no_signed_zeros : 1;
+ /// Allow Reciprocal - Allow optimizations to use the reciprocal
+ /// of an argument rather than perform division.
+ unsigned allow_reciprocal : 1;
+ /// Approximate functions - Allow substitution of approximate calculations
+ /// for functions (sin, log, sqrt, etc).
+ unsigned approx_func : 1;
};
+inline bool operator==(FPOptions LHS, FPOptions RHS) {
+ return LHS.getAsOpaqueInt() == RHS.getAsOpaqueInt();
+}
+inline bool operator!=(FPOptions LHS, FPOptions RHS) {
+ return LHS.getAsOpaqueInt() != RHS.getAsOpaqueInt();
+}
+
/// Describes the kind of translation unit being processed.
enum TranslationUnitKind {
/// The translation unit is a complete translation unit.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index c5e2b4440390..f3024efa293c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -557,15 +557,6 @@ class Sema final {
// This stack tracks the current state of Sema.CurFPFeatures.
PragmaStack<unsigned> FpPragmaStack;
- FPOptionsOverride CurFPFeatureOverrides() {
- FPOptionsOverride result;
- if (!FpPragmaStack.hasValue()) {
- result = FPOptionsOverride();
- } else {
- result = FPOptionsOverride(FpPragmaStack.CurrentValue);
- }
- return result;
- }
// RAII object to push / pop sentinel slots for all MS #pragma stacks.
// Actions should be performed only if we enter / exit a C++ method body.
@@ -1367,19 +1358,12 @@ class Sema final {
/// statements.
class FPFeaturesStateRAII {
public:
- FPFeaturesStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.CurFPFeatures) {
- OldOverrides = S.FpPragmaStack.CurrentValue;
- }
- ~FPFeaturesStateRAII() {
- S.CurFPFeatures = OldFPFeaturesState;
- S.FpPragmaStack.CurrentValue = OldOverrides;
- }
- unsigned getOverrides() { return OldOverrides; }
+ FPFeaturesStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.CurFPFeatures) {}
+ ~FPFeaturesStateRAII() { S.CurFPFeatures = OldFPFeaturesState; }
private:
Sema& S;
FPOptions OldFPFeaturesState;
- unsigned OldOverrides;
};
void addImplicitTypedef(StringRef Name, QualType T);
@@ -9622,10 +9606,10 @@ class Sema final {
/// Are precise floating point semantics currently enabled?
bool isPreciseFPEnabled() {
- return !CurFPFeatures.getAllowFPReassociate() &&
- !CurFPFeatures.getNoSignedZero() &&
- !CurFPFeatures.getAllowReciprocal() &&
- !CurFPFeatures.getAllowApproxFunc();
+ return !CurFPFeatures.allowAssociativeMath() &&
+ !CurFPFeatures.noSignedZeros() &&
+ !CurFPFeatures.allowReciprocalMath() &&
+ !CurFPFeatures.allowApproximateFunctions();
}
/// ActOnPragmaFloatControl - Call on well-formed \#pragma float_control
@@ -9668,21 +9652,21 @@ class Sema final {
/// ActOnPragmaFPContract - Called on well formed
/// \#pragma {STDC,OPENCL} FP_CONTRACT and
/// \#pragma clang fp contract
- void ActOnPragmaFPContract(SourceLocation Loc, LangOptions::FPModeKind FPC);
+ void ActOnPragmaFPContract(LangOptions::FPModeKind FPC);
/// Called on well formed
/// \#pragma clang fp reassociate
- void ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled);
+ void ActOnPragmaFPReassociate(bool IsEnabled);
/// ActOnPragmaFenvAccess - Called on well formed
/// \#pragma STDC FENV_ACCESS
void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled);
/// Called to set rounding mode for floating point operations.
- void setRoundingMode(SourceLocation Loc, llvm::RoundingMode);
+ void setRoundingMode(llvm::RoundingMode);
/// Called to set exception behavior for floating point operations.
- void setExceptionMode(SourceLocation Loc, LangOptions::FPExceptionModeKind);
+ void setExceptionMode(LangOptions::FPExceptionModeKind);
/// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
/// a the record decl, to handle '\#pragma pack' and '\#pragma options align'.
diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h
index 7a6664af65d8..35f73e1dfd7c 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -62,7 +62,6 @@ class CXXRecordDecl;
class CXXTemporary;
class FileEntry;
class FPOptions;
-class FPOptionsOverride;
class FunctionDecl;
class HeaderSearch;
class HeaderSearchOptions;
@@ -507,7 +506,7 @@ class ASTWriter : public ASTDeserializationListener,
bool IsModule);
void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
void WriteDeclContextVisibleUpdate(const DeclContext *DC);
- void WriteFPPragmaOptions(const FPOptionsOverride &Opts);
+ void WriteFPPragmaOptions(const FPOptions &Opts);
void WriteOpenCLExtensions(Sema &SemaRef);
void WriteOpenCLExtensionTypes(Sema &SemaRef);
void WriteOpenCLExtensionDecls(Sema &SemaRef);
diff --git a/clang/include/clang/module.modulemap b/clang/include/clang/module.modulemap
index 13d4dbf9dc2e..7549ff2e3bcd 100644
--- a/clang/include/clang/module.modulemap
+++ b/clang/include/clang/module.modulemap
@@ -54,7 +54,6 @@ module Clang_Basic {
textual header "Basic/CodeGenOptions.def"
textual header "Basic/DiagnosticOptions.def"
textual header "Basic/Features.def"
- textual header "Basic/FPOptions.def"
textual header "Basic/MSP430Target.def"
textual header "Basic/LangOptions.def"
textual header "Basic/OpenCLExtensions.def"
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index a47be2da4aab..8b96e20e374d 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -6676,7 +6676,7 @@ ExpectedStmt ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
return UnaryOperator::Create(
Importer.getToContext(), ToSubExpr, E->getOpcode(), ToType,
E->getValueKind(), E->getObjectKind(), ToOperatorLoc, E->canOverflow(),
- E->getFPOptionsOverride());
+ E->getFPFeatures(Importer.getFromContext().getLangOpts()));
}
ExpectedStmt
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 96a70307235b..ebb11346a003 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -4468,7 +4468,7 @@ ParenListExpr *ParenListExpr::CreateEmpty(const ASTContext &Ctx,
BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
Opcode opc, QualType ResTy, ExprValueKind VK,
ExprObjectKind OK, SourceLocation opLoc,
- FPOptionsOverride FPFeatures)
+ FPOptions FPFeatures)
: Expr(BinaryOperatorClass, ResTy, VK, OK) {
BinaryOperatorBits.Opc = opc;
assert(!isCompoundAssignmentOp() &&
@@ -4476,7 +4476,8 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
BinaryOperatorBits.OpLoc = opLoc;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
- BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ BinaryOperatorBits.HasFPFeatures =
+ FPFeatures.requiresTrailingStorage(Ctx.getLangOpts());
if (BinaryOperatorBits.HasFPFeatures)
*getTrailingFPFeatures() = FPFeatures;
setDependence(computeDependence(this));
@@ -4485,7 +4486,7 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
Opcode opc, QualType ResTy, ExprValueKind VK,
ExprObjectKind OK, SourceLocation opLoc,
- FPOptionsOverride FPFeatures, bool dead2)
+ FPOptions FPFeatures, bool dead2)
: Expr(CompoundAssignOperatorClass, ResTy, VK, OK) {
BinaryOperatorBits.Opc = opc;
assert(isCompoundAssignmentOp() &&
@@ -4493,7 +4494,8 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
BinaryOperatorBits.OpLoc = opLoc;
SubExprs[LHS] = lhs;
SubExprs[RHS] = rhs;
- BinaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ BinaryOperatorBits.HasFPFeatures =
+ FPFeatures.requiresTrailingStorage(Ctx.getLangOpts());
if (BinaryOperatorBits.HasFPFeatures)
*getTrailingFPFeatures() = FPFeatures;
setDependence(computeDependence(this));
@@ -4511,8 +4513,8 @@ BinaryOperator *BinaryOperator::Create(const ASTContext &C, Expr *lhs,
Expr *rhs, Opcode opc, QualType ResTy,
ExprValueKind VK, ExprObjectKind OK,
SourceLocation opLoc,
- FPOptionsOverride FPFeatures) {
- bool HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ FPOptions FPFeatures) {
+ bool HasFPFeatures = FPFeatures.requiresTrailingStorage(C.getLangOpts());
unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
void *Mem =
C.Allocate(sizeof(BinaryOperator) + Extra, alignof(BinaryOperator));
@@ -4528,13 +4530,11 @@ CompoundAssignOperator::CreateEmpty(const ASTContext &C, bool HasFPFeatures) {
return new (Mem) CompoundAssignOperator(C, EmptyShell(), HasFPFeatures);
}
-CompoundAssignOperator *
-CompoundAssignOperator::Create(const ASTContext &C, Expr *lhs, Expr *rhs,
- Opcode opc, QualType ResTy, ExprValueKind VK,
- ExprObjectKind OK, SourceLocation opLoc,
- FPOptionsOverride FPFeatures,
- QualType CompLHSType, QualType CompResultType) {
- bool HasFPFeatures = FPFeatures.requiresTrailingStorage();
+CompoundAssignOperator *CompoundAssignOperator::Create(
+ const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
+ ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc,
+ FPOptions FPFeatures, QualType CompLHSType, QualType CompResultType) {
+ bool HasFPFeatures = FPFeatures.requiresTrailingStorage(C.getLangOpts());
unsigned Extra = sizeOfTrailingObjects(HasFPFeatures);
void *Mem = C.Allocate(sizeof(CompoundAssignOperator) + Extra,
alignof(CompoundAssignOperator));
@@ -4545,7 +4545,7 @@ CompoundAssignOperator::Create(const ASTContext &C, Expr *lhs, Expr *rhs,
UnaryOperator *UnaryOperator::CreateEmpty(const ASTContext &C,
bool hasFPFeatures) {
- void *Mem = C.Allocate(totalSizeToAlloc<FPOptionsOverride>(hasFPFeatures),
+ void *Mem = C.Allocate(totalSizeToAlloc<FPOptions>(hasFPFeatures),
alignof(UnaryOperator));
return new (Mem) UnaryOperator(hasFPFeatures, EmptyShell());
}
@@ -4553,12 +4553,13 @@ UnaryOperator *UnaryOperator::CreateEmpty(const ASTContext &C,
UnaryOperator::UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc,
QualType type, ExprValueKind VK, ExprObjectKind OK,
SourceLocation l, bool CanOverflow,
- FPOptionsOverride FPFeatures)
+ FPOptions FPFeatures)
: Expr(UnaryOperatorClass, type, VK, OK), Val(input) {
UnaryOperatorBits.Opc = opc;
UnaryOperatorBits.CanOverflow = CanOverflow;
UnaryOperatorBits.Loc = l;
- UnaryOperatorBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
+ UnaryOperatorBits.HasFPFeatures =
+ FPFeatures.requiresTrailingStorage(Ctx.getLangOpts());
setDependence(computeDependence(this));
}
@@ -4566,9 +4567,9 @@ UnaryOperator *UnaryOperator::Create(const ASTContext &C, Expr *input,
Opcode opc, QualType type,
ExprValueKind VK, ExprObjectKind OK,
SourceLocation l, bool CanOverflow,
- FPOptionsOverride FPFeatures) {
- bool HasFPFeatures = FPFeatures.requiresTrailingStorage();
- unsigned Size = totalSizeToAlloc<FPOptionsOverride>(HasFPFeatures);
+ FPOptions FPFeatures) {
+ bool HasFPFeatures = FPFeatures.requiresTrailingStorage(C.getLangOpts());
+ unsigned Size = totalSizeToAlloc<FPOptions>(HasFPFeatures);
void *Mem = C.Allocate(Size, alignof(UnaryOperator));
return new (Mem)
UnaryOperator(C, input, opc, type, VK, OK, l, CanOverflow, FPFeatures);
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 2889604308dd..f9f825b29ed0 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -525,27 +525,27 @@ CXXOperatorCallExpr::CXXOperatorCallExpr(OverloadedOperatorKind OpKind,
Expr *Fn, ArrayRef<Expr *> Args,
QualType Ty, ExprValueKind VK,
SourceLocation OperatorLoc,
- FPOptionsOverride FPFeatures,
+ FPOptions FPFeatures,
ADLCallKind UsesADL)
: CallExpr(CXXOperatorCallExprClass, Fn, /*PreArgs=*/{}, Args, Ty, VK,
OperatorLoc, /*MinNumArgs=*/0, UsesADL) {
CXXOperatorCallExprBits.OperatorKind = OpKind;
+ CXXOperatorCallExprBits.FPFeatures = FPFeatures.getAsOpaqueInt();
assert(
(CXXOperatorCallExprBits.OperatorKind == static_cast<unsigned>(OpKind)) &&
"OperatorKind overflow!");
+ assert((CXXOperatorCallExprBits.FPFeatures == FPFeatures.getAsOpaqueInt()) &&
+ "FPFeatures overflow!");
Range = getSourceRangeImpl();
- Overrides = FPFeatures;
}
CXXOperatorCallExpr::CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty)
: CallExpr(CXXOperatorCallExprClass, /*NumPreArgs=*/0, NumArgs, Empty) {}
-CXXOperatorCallExpr *
-CXXOperatorCallExpr::Create(const ASTContext &Ctx,
- OverloadedOperatorKind OpKind, Expr *Fn,
- ArrayRef<Expr *> Args, QualType Ty,
- ExprValueKind VK, SourceLocation OperatorLoc,
- FPOptionsOverride FPFeatures, ADLCallKind UsesADL) {
+CXXOperatorCallExpr *CXXOperatorCallExpr::Create(
+ const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
+ ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
+ SourceLocation OperatorLoc, FPOptions FPFeatures, ADLCallKind UsesADL) {
// Allocate storage for the trailing objects of CallExpr.
unsigned NumArgs = Args.size();
unsigned SizeOfTrailingObjects =
diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp
index f9f0553d28f0..e10fbce71146 100644
--- a/clang/lib/Analysis/BodyFarm.cpp
+++ b/clang/lib/Analysis/BodyFarm.cpp
@@ -116,17 +116,18 @@ BinaryOperator *ASTMaker::makeAssignment(const Expr *LHS, const Expr *RHS,
QualType Ty) {
return BinaryOperator::Create(
C, const_cast<Expr *>(LHS), const_cast<Expr *>(RHS), BO_Assign, Ty,
- VK_RValue, OK_Ordinary, SourceLocation(), FPOptionsOverride());
+ VK_RValue, OK_Ordinary, SourceLocation(), FPOptions(C.getLangOpts()));
}
BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
BinaryOperator::Opcode Op) {
assert(BinaryOperator::isLogicalOp(Op) ||
BinaryOperator::isComparisonOp(Op));
- return BinaryOperator::Create(
- C, const_cast<Expr *>(LHS), const_cast<Expr *>(RHS), Op,
- C.getLogicalOperationType(), VK_RValue, OK_Ordinary, SourceLocation(),
- FPOptionsOverride());
+ return BinaryOperator::Create(C, const_cast<Expr *>(LHS),
+ const_cast<Expr *>(RHS), Op,
+ C.getLogicalOperationType(), VK_RValue,
+ OK_Ordinary, SourceLocation(),
+ FPOptions(C.getLangOpts()));
}
CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
@@ -147,7 +148,8 @@ DeclRefExpr *ASTMaker::makeDeclRefExpr(
UnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) {
return UnaryOperator::Create(C, const_cast<Expr *>(Arg), UO_Deref, Ty,
VK_LValue, OK_Ordinary, SourceLocation(),
- /*CanOverflow*/ false, FPOptionsOverride());
+ /*CanOverflow*/ false,
+ FPOptions(C.getLangOpts()));
}
ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
@@ -295,7 +297,7 @@ static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
/*QualType=*/C.VoidTy,
/*ExprValueType=*/VK_RValue,
/*SourceLocation=*/SourceLocation(),
- /*FPFeatures=*/FPOptionsOverride());
+ /*FPFeatures=*/FPOptions(C.getLangOpts()));
}
/// Create a fake body for std::call_once.
@@ -455,7 +457,7 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) {
/* QualType=*/C.IntTy,
/* ExprValueKind=*/VK_RValue,
/* ExprObjectKind=*/OK_Ordinary, SourceLocation(),
- /* CanOverflow*/ false, FPOptionsOverride());
+ /* CanOverflow*/ false, FPOptions(C.getLangOpts()));
// Create assignment.
BinaryOperator *FlagAssignment = M.makeAssignment(
@@ -520,7 +522,7 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
Expr *DoneValue =
UnaryOperator::Create(C, M.makeIntegerLiteral(0, C.LongTy), UO_Not,
C.LongTy, VK_RValue, OK_Ordinary, SourceLocation(),
- /*CanOverflow*/ false, FPOptionsOverride());
+ /*CanOverflow*/ false, FPOptions(C.getLangOpts()));
BinaryOperator *B =
M.makeAssignment(
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index c08670c87fb6..a74efdc460bf 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -24,7 +24,7 @@ void LangOptions::resetNonModularOptions() {
#define LANGOPT(Name, Bits, Default, Description)
#define BENIGN_LANGOPT(Name, Bits, Default, Description) Name = Default;
#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
- Name = static_cast<unsigned>(Default);
+ Name = Default;
#include "clang/Basic/LangOptions.def"
// These options do not affect AST generation.
@@ -53,17 +53,6 @@ FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) {
return result;
}
-LLVM_DUMP_METHOD void FPOptions::dump() {
-#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
- llvm::errs() << "\n " #NAME " " << get##NAME();
-#include "clang/Basic/FPOptions.def"
- llvm::errs() << "\n";
-}
-
-LLVM_DUMP_METHOD void FPOptionsOverride::dump() {
-#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
- if (has##NAME##Override()) \
- llvm::errs() << "\n " #NAME " Override is " << get##NAME##Override();
-#include "clang/Basic/FPOptions.def"
- llvm::errs() << "\n";
+bool FPOptions::requiresTrailingStorage(const LangOptions &LO) {
+ return getAsOpaqueInt() != defaultWithoutTrailingStorage(LO).getAsOpaqueInt();
}
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 1bbfc27403ed..f48f7185b55f 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2389,7 +2389,7 @@ llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
if (!E->canOverflow())
return Builder.CreateNSWAdd(InVal, Amount, Name);
return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
- E, InVal, IsInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
+ E, InVal, IsInc, E->getFPFeatures(CGF.getLangOpts())));
}
llvm_unreachable("Unknown SignedOverflowBehaviorTy");
}
@@ -2536,7 +2536,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
} else if (E->canOverflow() && type->isUnsignedIntegerType() &&
CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) {
value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
- E, value, isInc, E->getFPFeaturesInEffect(CGF.getLangOpts())));
+ E, value, isInc, E->getFPFeatures(CGF.getLangOpts())));
} else {
llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
@@ -2736,7 +2736,7 @@ Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
BinOp.Ty = E->getType();
BinOp.Opcode = BO_Sub;
- BinOp.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
+ BinOp.FPFeatures = E->getFPFeatures(CGF.getLangOpts());
BinOp.E = E;
return EmitSub(BinOp);
}
@@ -2757,7 +2757,7 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
Value *Result;
if (Oper->getType()->isFPOrFPVectorTy()) {
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
- CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
+ CGF, E->getFPFeatures(CGF.getLangOpts()));
Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp");
} else
Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp");
@@ -2960,7 +2960,7 @@ BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) {
Result.RHS = Visit(E->getRHS());
Result.Ty = E->getType();
Result.Opcode = E->getOpcode();
- Result.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
+ Result.FPFeatures = E->getFPFeatures(CGF.getLangOpts());
Result.E = E;
return Result;
}
@@ -2980,7 +2980,7 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(
OpInfo.RHS = Visit(E->getRHS());
OpInfo.Ty = E->getComputationResultType();
OpInfo.Opcode = E->getOpcode();
- OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
+ OpInfo.FPFeatures = E->getFPFeatures(CGF.getLangOpts());
OpInfo.E = E;
// Load/convert the LHS.
LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
@@ -4214,7 +4214,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
if (LHS->getType()->isFPOrFPVectorTy()) {
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
- CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
+ CGF, E->getFPFeatures(CGF.getLangOpts()));
LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
} else {
@@ -4300,7 +4300,7 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
if (LHS->getType()->isFPOrFPVectorTy()) {
CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
- CGF, E->getFPFeaturesInEffect(CGF.getLangOpts()));
+ CGF, E->getFPFeatures(CGF.getLangOpts()));
LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp");
RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp");
} else {
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 158a548e66c1..4c5311cf001d 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1493,7 +1493,8 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
BinaryOperator *assign = BinaryOperator::Create(
getContext(), &ivarRef, finalArg, BO_Assign, ivarRef.getType(), VK_RValue,
- OK_Ordinary, SourceLocation(), FPOptionsOverride());
+ OK_Ordinary, SourceLocation(),
+ FPOptions(getContext().getLangOpts()));
EmitStmt(assign);
}
@@ -3555,18 +3556,18 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
DeclRefExpr DstExpr(C, &DstDecl, false, DestTy, VK_RValue, SourceLocation());
UnaryOperator *DST = UnaryOperator::Create(
C, &DstExpr, UO_Deref, DestTy->getPointeeType(), VK_LValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(C.getLangOpts()));
DeclRefExpr SrcExpr(C, &SrcDecl, false, SrcTy, VK_RValue, SourceLocation());
UnaryOperator *SRC = UnaryOperator::Create(
C, &SrcExpr, UO_Deref, SrcTy->getPointeeType(), VK_LValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(C.getLangOpts()));
Expr *Args[2] = {DST, SRC};
CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment());
CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(
C, OO_Equal, CalleeExp->getCallee(), Args, DestTy->getPointeeType(),
- VK_LValue, SourceLocation(), FPOptionsOverride());
+ VK_LValue, SourceLocation(), FPOptions(C.getLangOpts()));
EmitStmt(TheCall);
@@ -3640,7 +3641,7 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
UnaryOperator *SRC = UnaryOperator::Create(
C, &SrcExpr, UO_Deref, SrcTy->getPointeeType(), VK_LValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(C.getLangOpts()));
CXXConstructExpr *CXXConstExpr =
cast<CXXConstructExpr>(PID->getGetterCXXConstructor());
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 7904d4a8c420..b380143fe52f 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -3328,11 +3328,11 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
// Generate condition for loop.
BinaryOperator *Cond = BinaryOperator::Create(
C, &IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue, OK_Ordinary,
- S.getBeginLoc(), FPOptionsOverride());
+ S.getBeginLoc(), FPOptions(C.getLangOpts()));
// Increment for loop counter.
UnaryOperator *Inc = UnaryOperator::Create(
C, &IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
- S.getBeginLoc(), true, FPOptionsOverride());
+ S.getBeginLoc(), true, FPOptions(C.getLangOpts()));
auto &&BodyGen = [CapturedStmt, CS, &S, &IV](CodeGenFunction &CGF) {
// Iterate through all sections and emit a switch construct:
// switch (IV) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index cfd32d1b77ed..23208b2d84e4 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -117,12 +117,12 @@ void CodeGenFunction::SetFPModel() {
void CodeGenFunction::SetFastMathFlags(FPOptions FPFeatures) {
llvm::FastMathFlags FMF;
- FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
- FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());
- FMF.setNoInfs(FPFeatures.getNoHonorInfs());
- FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());
- FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());
- FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());
+ FMF.setAllowReassoc(FPFeatures.allowAssociativeMath());
+ FMF.setNoNaNs(FPFeatures.noHonorNaNs());
+ FMF.setNoInfs(FPFeatures.noHonorInfs());
+ FMF.setNoSignedZeros(FPFeatures.noSignedZeros());
+ FMF.setAllowReciprocal(FPFeatures.allowReciprocalMath());
+ FMF.setApproxFunc(FPFeatures.allowApproximateFunctions());
FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement());
Builder.setFastMathFlags(FMF);
}
@@ -137,12 +137,10 @@ CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF,
FMFGuard.emplace(CGF.Builder);
- llvm::RoundingMode NewRoundingBehavior =
- static_cast<llvm::RoundingMode>(FPFeatures.getRoundingMode());
+ auto NewRoundingBehavior = FPFeatures.getRoundingMode();
CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
auto NewExceptionBehavior =
- ToConstrainedExceptMD(static_cast<LangOptions::FPExceptionModeKind>(
- FPFeatures.getFPExceptionMode()));
+ ToConstrainedExceptMD(FPFeatures.getExceptionMode());
CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);
CGF.SetFastMathFlags(FPFeatures);
@@ -161,13 +159,13 @@ CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF,
if (OldValue != NewValue)
CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue));
};
- mergeFnAttrValue("no-infs-fp-math", FPFeatures.getNoHonorInfs());
- mergeFnAttrValue("no-nans-fp-math", FPFeatures.getNoHonorNaNs());
- mergeFnAttrValue("no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
- mergeFnAttrValue("unsafe-fp-math", FPFeatures.getAllowFPReassociate() &&
- FPFeatures.getAllowReciprocal() &&
- FPFeatures.getAllowApproxFunc() &&
- FPFeatures.getNoSignedZero());
+ mergeFnAttrValue("no-infs-fp-math", FPFeatures.noHonorInfs());
+ mergeFnAttrValue("no-nans-fp-math", FPFeatures.noHonorNaNs());
+ mergeFnAttrValue("no-signed-zeros-fp-math", FPFeatures.noSignedZeros());
+ mergeFnAttrValue(
+ "unsafe-fp-math",
+ FPFeatures.allowAssociativeMath() && FPFeatures.allowReciprocalMath() &&
+ FPFeatures.allowApproximateFunctions() && FPFeatures.noSignedZeros());
}
CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() {
diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index e122b10e76d3..bb195ade1409 100644
--- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -2590,7 +2590,7 @@ Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
Expr *Unop = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), DRE, UO_AddrOf,
Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
// cast to NSConstantString *
CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
CK_CPointerToObjCPointerCast, Unop);
@@ -3287,7 +3287,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
SuperRep = NoTypeInfoCStyleCastExpr(Context,
Context->getPointerType(superType),
CK_BitCast, SuperRep);
@@ -3305,7 +3305,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
}
MsgExprs.push_back(SuperRep);
break;
@@ -3382,7 +3382,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
SuperRep = NoTypeInfoCStyleCastExpr(Context,
Context->getPointerType(superType),
CK_BitCast, SuperRep);
@@ -4706,9 +4706,10 @@ Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
if (VarDecl *Var = dyn_cast<VarDecl>(VD))
if (!ImportedLocalExternalDecls.count(Var))
return DRE;
- Expr *Exp = UnaryOperator::Create(
- const_cast<ASTContext &>(*Context), DRE, UO_Deref, DRE->getType(),
- VK_LValue, OK_Ordinary, DRE->getLocation(), false, FPOptionsOverride());
+ Expr *Exp = UnaryOperator::Create(const_cast<ASTContext &>(*Context), DRE,
+ UO_Deref, DRE->getType(), VK_LValue,
+ OK_Ordinary, DRE->getLocation(), false,
+ FPOptions(Context->getLangOpts()));
// Need parens to enforce precedence.
ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
Exp);
@@ -5299,7 +5300,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy,
VK_LValue, SourceLocation()),
UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue,
- OK_Ordinary, SourceLocation(), false, FPOptionsOverride());
+ OK_Ordinary, SourceLocation(), false, FPOptions(Context->getLangOpts()));
InitExprs.push_back(DescRefExpr);
// Add initializers for any closure decl refs.
@@ -5316,9 +5317,10 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
if (HasLocalVariableExternalStorage(*I)) {
QualType QT = (*I)->getType();
QT = Context->getPointerType(QT);
- Exp = UnaryOperator::Create(
- const_cast<ASTContext &>(*Context), Exp, UO_AddrOf, QT, VK_RValue,
- OK_Ordinary, SourceLocation(), false, FPOptionsOverride());
+ Exp = UnaryOperator::Create(const_cast<ASTContext &>(*Context), Exp,
+ UO_AddrOf, QT, VK_RValue, OK_Ordinary,
+ SourceLocation(), false,
+ FPOptions(Context->getLangOpts()));
}
} else if (isTopLevelBlockPointerType((*I)->getType())) {
FD = SynthBlockInitFunctionDecl((*I)->getName());
@@ -5333,9 +5335,10 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
if (HasLocalVariableExternalStorage(*I)) {
QualType QT = (*I)->getType();
QT = Context->getPointerType(QT);
- Exp = UnaryOperator::Create(
- const_cast<ASTContext &>(*Context), Exp, UO_AddrOf, QT, VK_RValue,
- OK_Ordinary, SourceLocation(), false, FPOptionsOverride());
+ Exp = UnaryOperator::Create(const_cast<ASTContext &>(*Context), Exp,
+ UO_AddrOf, QT, VK_RValue, OK_Ordinary,
+ SourceLocation(), false,
+ FPOptions(Context->getLangOpts()));
}
}
@@ -5376,7 +5379,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
Exp = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), Exp, UO_AddrOf,
Context->getPointerType(Exp->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
InitExprs.push_back(Exp);
}
@@ -5403,7 +5406,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
NewRep = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), NewRep, UO_AddrOf,
Context->getPointerType(NewRep->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
NewRep);
// Put Paren around the call.
@@ -7491,7 +7494,7 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
BinaryOperator *addExpr = BinaryOperator::Create(
*Context, castExpr, DRE, BO_Add,
Context->getPointerType(Context->CharTy), VK_RValue, OK_Ordinary,
- SourceLocation(), FPOptionsOverride());
+ SourceLocation(), FPOptions(Context->getLangOpts()));
// Don't forget the parens to enforce the proper binding.
ParenExpr *PE = new (Context) ParenExpr(SourceLocation(),
SourceLocation(),
@@ -7542,9 +7545,10 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
CK_BitCast,
PE);
- Expr *Exp = UnaryOperator::Create(
- const_cast<ASTContext &>(*Context), castExpr, UO_Deref, IvarT,
- VK_LValue, OK_Ordinary, SourceLocation(), false, FPOptionsOverride());
+ Expr *Exp = UnaryOperator::Create(const_cast<ASTContext &>(*Context),
+ castExpr, UO_Deref, IvarT, VK_LValue,
+ OK_Ordinary, SourceLocation(), false,
+ FPOptions(Context->getLangOpts()));
PE = new (Context) ParenExpr(OldRange.getBegin(),
OldRange.getEnd(),
Exp);
diff --git a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
index 3f320dc57aa6..8b618d90b47e 100644
--- a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -2517,7 +2517,7 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
Expr *Unop = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), DRE, UO_AddrOf,
Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
// cast to NSConstantString *
CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
CK_CPointerToObjCPointerCast, Unop);
@@ -2718,7 +2718,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
SuperRep = NoTypeInfoCStyleCastExpr(Context,
Context->getPointerType(superType),
CK_BitCast, SuperRep);
@@ -2736,7 +2736,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
}
MsgExprs.push_back(SuperRep);
break;
@@ -2813,7 +2813,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
SuperRep = NoTypeInfoCStyleCastExpr(Context,
Context->getPointerType(superType),
CK_BitCast, SuperRep);
@@ -2999,7 +2999,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SourceLocation());
BinaryOperator *lessThanExpr = BinaryOperator::Create(
*Context, sizeofExpr, limit, BO_LE, Context->IntTy, VK_RValue,
- OK_Ordinary, SourceLocation(), FPOptionsOverride());
+ OK_Ordinary, SourceLocation(), FPOptions(Context->getLangOpts()));
// (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
ConditionalOperator *CondExpr =
new (Context) ConditionalOperator(lessThanExpr,
@@ -3052,7 +3052,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
Expr *DerefExpr = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), DRE, UO_AddrOf,
Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
CK_BitCast,
DerefExpr);
@@ -3877,9 +3877,10 @@ Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
if (VarDecl *Var = dyn_cast<VarDecl>(VD))
if (!ImportedLocalExternalDecls.count(Var))
return DRE;
- Expr *Exp = UnaryOperator::Create(
- const_cast<ASTContext &>(*Context), DRE, UO_Deref, DRE->getType(),
- VK_LValue, OK_Ordinary, DRE->getLocation(), false, FPOptionsOverride());
+ Expr *Exp = UnaryOperator::Create(const_cast<ASTContext &>(*Context), DRE,
+ UO_Deref, DRE->getType(), VK_LValue,
+ OK_Ordinary, DRE->getLocation(), false,
+ FPOptions(Context->getLangOpts()));
// Need parens to enforce precedence.
ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
Exp);
@@ -4439,7 +4440,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy,
VK_LValue, SourceLocation()),
UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue,
- OK_Ordinary, SourceLocation(), false, FPOptionsOverride());
+ OK_Ordinary, SourceLocation(), false, FPOptions(Context->getLangOpts()));
InitExprs.push_back(DescRefExpr);
// Add initializers for any closure decl refs.
@@ -4456,9 +4457,10 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
if (HasLocalVariableExternalStorage(*I)) {
QualType QT = (*I)->getType();
QT = Context->getPointerType(QT);
- Exp = UnaryOperator::Create(
- const_cast<ASTContext &>(*Context), Exp, UO_AddrOf, QT, VK_RValue,
- OK_Ordinary, SourceLocation(), false, FPOptionsOverride());
+ Exp = UnaryOperator::Create(const_cast<ASTContext &>(*Context), Exp,
+ UO_AddrOf, QT, VK_RValue, OK_Ordinary,
+ SourceLocation(), false,
+ FPOptions(Context->getLangOpts()));
}
} else if (isTopLevelBlockPointerType((*I)->getType())) {
FD = SynthBlockInitFunctionDecl((*I)->getName());
@@ -4473,9 +4475,10 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
if (HasLocalVariableExternalStorage(*I)) {
QualType QT = (*I)->getType();
QT = Context->getPointerType(QT);
- Exp = UnaryOperator::Create(
- const_cast<ASTContext &>(*Context), Exp, UO_AddrOf, QT, VK_RValue,
- OK_Ordinary, SourceLocation(), false, FPOptionsOverride());
+ Exp = UnaryOperator::Create(const_cast<ASTContext &>(*Context), Exp,
+ UO_AddrOf, QT, VK_RValue, OK_Ordinary,
+ SourceLocation(), false,
+ FPOptions(Context->getLangOpts()));
}
}
InitExprs.push_back(Exp);
@@ -4515,7 +4518,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
Exp = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), Exp, UO_AddrOf,
Context->getPointerType(Exp->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
InitExprs.push_back(Exp);
}
@@ -4534,7 +4537,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
NewRep = UnaryOperator::Create(
const_cast<ASTContext &>(*Context), NewRep, UO_AddrOf,
Context->getPointerType(NewRep->getType()), VK_RValue, OK_Ordinary,
- SourceLocation(), false, FPOptionsOverride());
+ SourceLocation(), false, FPOptions(Context->getLangOpts()));
NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
NewRep);
BlockDeclRefs.clear();
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index ab94e4c45709..06ac545da519 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -3371,10 +3371,8 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
// to the levels specified on the command line. Previous level
// will be restored when the RAII object is destroyed.
Sema::FPFeaturesStateRAII SaveFPFeaturesState(Actions);
- FPOptionsOverride NewOverrides;
- Actions.CurFPFeatures = NewOverrides.applyOverrides(getLangOpts());
- Actions.FpPragmaStack.Act(Tok.getLocation(), Sema::PSK_Reset, StringRef(),
- 0 /*unused*/);
+ FPOptions fpOptions(getLangOpts());
+ Actions.CurFPFeatures.getFromOpaqueInt(fpOptions.getAsOpaqueInt());
SourceLocation SavedPrevTokLocation = PrevTokLocation;
ParseLexedPragmas(getCurrentClass());
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 6402b31d00b2..eacb54e81ae6 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -654,8 +654,8 @@ void Parser::HandlePragmaFPContract() {
break;
}
- SourceLocation PragmaLoc = ConsumeAnnotationToken();
- Actions.ActOnPragmaFPContract(PragmaLoc, FPC);
+ Actions.ActOnPragmaFPContract(FPC);
+ ConsumeAnnotationToken();
}
void Parser::HandlePragmaFloatControl() {
@@ -2935,8 +2935,8 @@ void Parser::HandlePragmaFP() {
reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue());
if (AnnotValue->FlagKind == TokFPAnnotValue::Reassociate)
- Actions.ActOnPragmaFPReassociate(
- Tok.getLocation(), AnnotValue->FlagValue == TokFPAnnotValue::On);
+ Actions.ActOnPragmaFPReassociate(AnnotValue->FlagValue ==
+ TokFPAnnotValue::On);
else {
LangOptions::FPModeKind FPC;
switch (AnnotValue->FlagValue) {
@@ -2950,7 +2950,7 @@ void Parser::HandlePragmaFP() {
FPC = LangOptions::FPM_Fast;
break;
}
- Actions.ActOnPragmaFPContract(Tok.getLocation(), FPC);
+ Actions.ActOnPragmaFPContract(FPC);
}
ConsumeAnnotationToken();
}
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 2f2b52106f3d..fc3fb524c8f4 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -159,8 +159,9 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
LangOpts.getMSPointerToMemberRepresentationMethod()),
VtorDispStack(LangOpts.getVtorDispMode()), PackStack(0),
DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr),
- CodeSegStack(nullptr), FpPragmaStack(0xffffffff), CurInitSeg(nullptr),
- VisContext(nullptr), PragmaAttributeCurrentTargetDecl(nullptr),
+ CodeSegStack(nullptr), FpPragmaStack(CurFPFeatures.getAsOpaqueInt()),
+ CurInitSeg(nullptr), VisContext(nullptr),
+ PragmaAttributeCurrentTargetDecl(nullptr),
IsBuildingRecoveryCallExpr(false), Cleanup{}, LateTemplateParser(nullptr),
LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp),
StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr),
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index a51d1c3d7e12..977e92475182 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -417,10 +417,8 @@ void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name,
void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
PragmaMsStackAction Action,
PragmaFloatControlKind Value) {
- unsigned NewValue = FpPragmaStack.hasValue()
- ? FpPragmaStack.CurrentValue
- : CurFPFeatureOverrides().getAsOpaqueInt();
- FPOptionsOverride NewFPFeatures(NewValue);
+ auto NewValue = FpPragmaStack.CurrentValue;
+ FPOptions NewFPFeatures(NewValue);
if ((Action == PSK_Push_Set || Action == PSK_Push || Action == PSK_Pop) &&
!(CurContext->isTranslationUnit()) && !CurContext->isNamespace()) {
// Push and pop can only occur at file or namespace scope.
@@ -431,34 +429,38 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
default:
llvm_unreachable("invalid pragma float_control kind");
case PFC_Precise:
- NewFPFeatures.setFPPreciseEnabled(true);
- NewValue = NewFPFeatures.getAsOpaqueInt();
+ CurFPFeatures.setFPPreciseEnabled(true);
+ NewValue = CurFPFeatures.getAsOpaqueInt();
FpPragmaStack.Act(Loc, Action, StringRef(), NewValue);
break;
case PFC_NoPrecise:
- if (CurFPFeatures.getFPExceptionMode() == LangOptions::FPE_Strict)
+ if (CurFPFeatures.getExceptionMode() == LangOptions::FPE_Strict)
Diag(Loc, diag::err_pragma_fc_noprecise_requires_noexcept);
- else if (CurFPFeatures.getAllowFEnvAccess())
+ else if (CurFPFeatures.allowFEnvAccess())
Diag(Loc, diag::err_pragma_fc_noprecise_requires_nofenv);
else
- NewFPFeatures.setFPPreciseEnabled(false);
- NewValue = NewFPFeatures.getAsOpaqueInt();
+ CurFPFeatures.setFPPreciseEnabled(false);
+ NewValue = CurFPFeatures.getAsOpaqueInt();
FpPragmaStack.Act(Loc, Action, StringRef(), NewValue);
break;
case PFC_Except:
if (!isPreciseFPEnabled())
Diag(Loc, diag::err_pragma_fc_except_requires_precise);
else
- NewFPFeatures.setFPExceptionModeOverride(LangOptions::FPE_Strict);
- NewValue = NewFPFeatures.getAsOpaqueInt();
+ CurFPFeatures.setExceptionMode(LangOptions::FPE_Strict);
+ NewValue = CurFPFeatures.getAsOpaqueInt();
FpPragmaStack.Act(Loc, Action, StringRef(), NewValue);
break;
case PFC_NoExcept:
- NewFPFeatures.setFPExceptionModeOverride(LangOptions::FPE_Ignore);
- NewValue = NewFPFeatures.getAsOpaqueInt();
+ CurFPFeatures.setExceptionMode(LangOptions::FPE_Ignore);
+ NewValue = CurFPFeatures.getAsOpaqueInt();
FpPragmaStack.Act(Loc, Action, StringRef(), NewValue);
break;
case PFC_Push:
+ if (FpPragmaStack.Stack.empty()) {
+ FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(),
+ CurFPFeatures.getAsOpaqueInt());
+ }
FpPragmaStack.Act(Loc, Sema::PSK_Push_Set, StringRef(),
NewFPFeatures.getAsOpaqueInt());
break;
@@ -470,12 +472,9 @@ void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
}
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures.getAsOpaqueInt());
NewValue = FpPragmaStack.CurrentValue;
+ CurFPFeatures.getFromOpaqueInt(NewValue);
break;
}
- FPOptionsOverride NewOverrides;
- if (NewValue != FpPragmaStack.DefaultValue)
- NewOverrides.getFromOpaqueInt(NewValue);
- CurFPFeatures = NewOverrides.applyOverrides(getLangOpts());
}
void Sema::ActOnPragmaMSPointersToMembers(
@@ -1004,70 +1003,33 @@ void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType,
}
}
-void Sema::ActOnPragmaFPContract(SourceLocation Loc,
- LangOptions::FPModeKind FPC) {
- unsigned NewValue = FpPragmaStack.hasValue()
- ? FpPragmaStack.CurrentValue
- : CurFPFeatureOverrides().getAsOpaqueInt();
- FPOptionsOverride NewFPFeatures(NewValue);
+void Sema::ActOnPragmaFPContract(LangOptions::FPModeKind FPC) {
switch (FPC) {
case LangOptions::FPM_On:
- NewFPFeatures.setAllowFPContractWithinStatement();
+ CurFPFeatures.setAllowFPContractWithinStatement();
break;
case LangOptions::FPM_Fast:
- NewFPFeatures.setAllowFPContractAcrossStatement();
+ CurFPFeatures.setAllowFPContractAcrossStatement();
break;
case LangOptions::FPM_Off:
- NewFPFeatures.setDisallowFPContract();
+ CurFPFeatures.setDisallowFPContract();
break;
}
- CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
- FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(),
- NewFPFeatures.getAsOpaqueInt());
}
-void Sema::ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled) {
- unsigned NewValue = FpPragmaStack.hasValue()
- ? FpPragmaStack.CurrentValue
- : CurFPFeatureOverrides().getAsOpaqueInt();
- FPOptionsOverride NewFPFeatures(NewValue);
- NewFPFeatures.setAllowFPReassociateOverride(IsEnabled);
- NewValue = NewFPFeatures.getAsOpaqueInt();
- FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewValue);
- FPOptionsOverride NewOverrides(NewValue);
- CurFPFeatures = NewOverrides.applyOverrides(getLangOpts());
+void Sema::ActOnPragmaFPReassociate(bool IsEnabled) {
+ CurFPFeatures.setAllowAssociativeMath(IsEnabled);
}
-void Sema::setRoundingMode(SourceLocation Loc, llvm::RoundingMode FPR) {
- unsigned NewValue = FpPragmaStack.hasValue()
- ? FpPragmaStack.CurrentValue
- : CurFPFeatureOverrides().getAsOpaqueInt();
- FPOptionsOverride NewFPFeatures(NewValue);
- NewFPFeatures.setRoundingModeOverride(FPR);
- NewValue = NewFPFeatures.getAsOpaqueInt();
- FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewValue);
- FPOptionsOverride NewOverrides(NewValue);
- CurFPFeatures = NewOverrides.applyOverrides(getLangOpts());
+void Sema::setRoundingMode(llvm::RoundingMode FPR) {
+ CurFPFeatures.setRoundingMode(FPR);
}
-void Sema::setExceptionMode(SourceLocation Loc,
- LangOptions::FPExceptionModeKind FPE) {
- unsigned NewValue = FpPragmaStack.hasValue()
- ? FpPragmaStack.CurrentValue
- : CurFPFeatureOverrides().getAsOpaqueInt();
- FPOptionsOverride NewFPFeatures(NewValue);
- NewFPFeatures.setFPExceptionModeOverride(FPE);
- NewValue = NewFPFeatures.getAsOpaqueInt();
- FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewValue);
- FPOptionsOverride NewOverrides(NewValue);
- CurFPFeatures = NewOverrides.applyOverrides(getLangOpts());
+void Sema::setExceptionMode(LangOptions::FPExceptionModeKind FPE) {
+ CurFPFeatures.setExceptionMode(FPE);
}
void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled) {
- unsigned NewValue = FpPragmaStack.hasValue()
- ? FpPragmaStack.CurrentValue
- : CurFPFeatureOverrides().getAsOpaqueInt();
- FPOptionsOverride NewFPFeatures(NewValue);
if (IsEnabled) {
// Verify Microsoft restriction:
// You can't enable fenv_access unless precise semantics are enabled.
@@ -1075,13 +1037,9 @@ void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled) {
// pragma, or by using the /fp:precise or /fp:strict compiler options
if (!isPreciseFPEnabled())
Diag(Loc, diag::err_pragma_fenv_requires_precise);
- NewFPFeatures.setAllowFEnvAccessOverride(true);
+ CurFPFeatures.setAllowFEnvAccess();
} else
- NewFPFeatures.setAllowFEnvAccessOverride(false);
- NewValue = NewFPFeatures.getAsOpaqueInt();
- FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewValue);
- FPOptionsOverride NewOverrides(NewValue);
- CurFPFeatures = NewOverrides.applyOverrides(getLangOpts());
+ CurFPFeatures.setDisallowFEnvAccess();
}
void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index ef555788ee0e..a2ada2053534 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -13526,11 +13526,11 @@ buildMemcpyForAssignmentOp(Sema &S, SourceLocation Loc, QualType T,
Expr *From = FromB.build(S, Loc);
From = UnaryOperator::Create(
S.Context, From, UO_AddrOf, S.Context.getPointerType(From->getType()),
- VK_RValue, OK_Ordinary, Loc, false, S.CurFPFeatureOverrides());
+ VK_RValue, OK_Ordinary, Loc, false, S.CurFPFeatures);
Expr *To = ToB.build(S, Loc);
- To = UnaryOperator::Create(
- S.Context, To, UO_AddrOf, S.Context.getPointerType(To->getType()),
- VK_RValue, OK_Ordinary, Loc, false, S.CurFPFeatureOverrides());
+ To = UnaryOperator::Create(S.Context, To, UO_AddrOf,
+ S.Context.getPointerType(To->getType()), VK_RValue,
+ OK_Ordinary, Loc, false, S.CurFPFeatures);
const Type *E = T->getBaseElementTypeUnsafe();
bool NeedsCollectableMemCpy =
@@ -13767,14 +13767,14 @@ buildSingleCopyAssignRecursively(Sema &S, SourceLocation Loc, QualType T,
Expr *Comparison = BinaryOperator::Create(
S.Context, IterationVarRefRVal.build(S, Loc),
IntegerLiteral::Create(S.Context, Upper, SizeType, Loc), BO_NE,
- S.Context.BoolTy, VK_RValue, OK_Ordinary, Loc, S.CurFPFeatureOverrides());
+ S.Context.BoolTy, VK_RValue, OK_Ordinary, Loc, S.CurFPFeatures);
// Create the pre-increment of the iteration variable. We can determine
// whether the increment will overflow based on the value of the array
// bound.
Expr *Increment = UnaryOperator::Create(
S.Context, IterationVarRef.build(S, Loc), UO_PreInc, SizeType, VK_LValue,
- OK_Ordinary, Loc, Upper.isMaxValue(), S.CurFPFeatureOverrides());
+ OK_Ordinary, Loc, Upper.isMaxValue(), S.CurFPFeatures);
// Construct the loop that copies all elements of this array.
return S.ActOnForStmt(
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index e1433d293286..bc0248700517 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13630,7 +13630,7 @@ static ExprResult convertHalfVecBinOp(Sema &S, ExprResult LHS, ExprResult RHS,
BinaryOperatorKind Opc, QualType ResultTy,
ExprValueKind VK, ExprObjectKind OK,
bool IsCompAssign, SourceLocation OpLoc,
- FPOptionsOverride FPFeatures) {
+ FPOptions FPFeatures) {
auto &Context = S.getASTContext();
assert((isVector(ResultTy, Context.HalfTy) ||
isVector(ResultTy, Context.ShortTy)) &&
@@ -13953,9 +13953,9 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
if (CompResultTy.isNull()) {
if (ConvertHalfVec)
return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, false,
- OpLoc, CurFPFeatureOverrides());
+ OpLoc, CurFPFeatures);
return BinaryOperator::Create(Context, LHS.get(), RHS.get(), Opc, ResultTy,
- VK, OK, OpLoc, CurFPFeatureOverrides());
+ VK, OK, OpLoc, CurFPFeatures);
}
// Handle compound assignments.
@@ -13973,11 +13973,11 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
if (ConvertHalfVec)
return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, true,
- OpLoc, CurFPFeatureOverrides());
+ OpLoc, CurFPFeatures);
- return CompoundAssignOperator::Create(
- Context, LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, OpLoc,
- CurFPFeatureOverrides(), CompLHSTy, CompResultTy);
+ return CompoundAssignOperator::Create(Context, LHS.get(), RHS.get(), Opc,
+ ResultTy, VK, OK, OpLoc, CurFPFeatures,
+ CompLHSTy, CompResultTy);
}
/// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison
@@ -14565,9 +14565,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
if (Opc != UO_AddrOf && Opc != UO_Deref)
CheckArrayAccess(Input.get());
- auto *UO =
- UnaryOperator::Create(Context, Input.get(), Opc, resultType, VK, OK,
- OpLoc, CanOverflow, CurFPFeatureOverrides());
+ auto *UO = UnaryOperator::Create(Context, Input.get(), Opc, resultType, VK,
+ OK, OpLoc, CanOverflow, CurFPFeatures);
if (Opc == UO_Deref && UO->getType()->hasAttr(attr::NoDeref) &&
!isa<ArrayType>(UO->getType().getDesugaredType(Context)))
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index 192e4184d144..474aba6a0d44 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -4487,8 +4487,7 @@ Expr *Sema::stripARCUnbridgedCast(Expr *e) {
Expr *sub = stripARCUnbridgedCast(uo->getSubExpr());
return UnaryOperator::Create(Context, sub, UO_Extension, sub->getType(),
sub->getValueKind(), sub->getObjectKind(),
- uo->getOperatorLoc(), false,
- CurFPFeatureOverrides());
+ uo->getOperatorLoc(), false, CurFPFeatures);
} else if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
assert(!gse->isResultDependent());
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 038b814e3aff..e57264dec9a0 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -13041,7 +13041,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
if (Fns.empty())
return UnaryOperator::Create(Context, Input, Opc, Context.DependentTy,
VK_RValue, OK_Ordinary, OpLoc, false,
- CurFPFeatureOverrides());
+ CurFPFeatures);
CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create(
@@ -13049,7 +13049,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
/*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end());
return CXXOperatorCallExpr::Create(Context, Op, Fn, ArgsArray,
Context.DependentTy, VK_RValue, OpLoc,
- CurFPFeatureOverrides());
+ CurFPFeatures);
}
// Build an empty overload set.
@@ -13123,7 +13123,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
Args[0] = Input;
CallExpr *TheCall = CXXOperatorCallExpr::Create(
Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc,
- CurFPFeatureOverrides(), Best->IsADLCandidate);
+ CurFPFeatures, Best->IsADLCandidate);
if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
return ExprError();
@@ -13292,12 +13292,12 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// If there are no functions to store, just build a dependent
// BinaryOperator or CompoundAssignment.
if (Opc <= BO_Assign || Opc > BO_OrAssign)
- return BinaryOperator::Create(
- Context, Args[0], Args[1], Opc, Context.DependentTy, VK_RValue,
- OK_Ordinary, OpLoc, CurFPFeatureOverrides());
+ return BinaryOperator::Create(Context, Args[0], Args[1], Opc,
+ Context.DependentTy, VK_RValue,
+ OK_Ordinary, OpLoc, CurFPFeatures);
return CompoundAssignOperator::Create(
Context, Args[0], Args[1], Opc, Context.DependentTy, VK_LValue,
- OK_Ordinary, OpLoc, CurFPFeatureOverrides(), Context.DependentTy,
+ OK_Ordinary, OpLoc, CurFPFeatures, Context.DependentTy,
Context.DependentTy);
}
@@ -13311,7 +13311,7 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
/*ADL*/ PerformADL, IsOverloaded(Fns), Fns.begin(), Fns.end());
return CXXOperatorCallExpr::Create(Context, Op, Fn, Args,
Context.DependentTy, VK_RValue, OpLoc,
- CurFPFeatureOverrides());
+ CurFPFeatures);
}
// Always do placeholder-like conversions on the RHS.
@@ -13480,7 +13480,7 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(
Context, ChosenOp, FnExpr.get(), Args, ResultTy, VK, OpLoc,
- CurFPFeatureOverrides(), Best->IsADLCandidate);
+ CurFPFeatures, Best->IsADLCandidate);
if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall,
FnDecl))
@@ -13748,7 +13748,7 @@ ExprResult Sema::BuildSynthesizedThreeWayComparison(
Expr *SyntacticForm = BinaryOperator::Create(
Context, OrigLHS, OrigRHS, BO_Cmp, Result.get()->getType(),
Result.get()->getValueKind(), Result.get()->getObjectKind(), OpLoc,
- CurFPFeatureOverrides());
+ CurFPFeatures);
Expr *SemanticForm[] = {LHS, RHS, Result.get()};
return PseudoObjectExpr::Create(Context, SyntacticForm, SemanticForm, 2);
}
@@ -13779,7 +13779,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
return CXXOperatorCallExpr::Create(Context, OO_Subscript, Fn, Args,
Context.DependentTy, VK_RValue, RLoc,
- CurFPFeatureOverrides());
+ CurFPFeatures);
}
// Handle placeholders on both operands.
@@ -13852,9 +13852,9 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
ExprValueKind VK = Expr::getValueKindForType(ResultTy);
ResultTy = ResultTy.getNonLValueExprType(Context);
- CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(
- Context, OO_Subscript, FnExpr.get(), Args, ResultTy, VK, RLoc,
- CurFPFeatureOverrides());
+ CXXOperatorCallExpr *TheCall =
+ CXXOperatorCallExpr::Create(Context, OO_Subscript, FnExpr.get(),
+ Args, ResultTy, VK, RLoc, CurFPFeatures);
if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl))
return ExprError();
@@ -14476,9 +14476,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
ExprValueKind VK = Expr::getValueKindForType(ResultTy);
ResultTy = ResultTy.getNonLValueExprType(Context);
- CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(
- Context, OO_Call, NewFn.get(), MethodArgs, ResultTy, VK, RParenLoc,
- CurFPFeatureOverrides());
+ CXXOperatorCallExpr *TheCall =
+ CXXOperatorCallExpr::Create(Context, OO_Call, NewFn.get(), MethodArgs,
+ ResultTy, VK, RParenLoc, CurFPFeatures);
if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method))
return true;
@@ -14594,9 +14594,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
QualType ResultTy = Method->getReturnType();
ExprValueKind VK = Expr::getValueKindForType(ResultTy);
ResultTy = ResultTy.getNonLValueExprType(Context);
- CXXOperatorCallExpr *TheCall =
- CXXOperatorCallExpr::Create(Context, OO_Arrow, FnExpr.get(), Base,
- ResultTy, VK, OpLoc, CurFPFeatureOverrides());
+ CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create(
+ Context, OO_Arrow, FnExpr.get(), Base, ResultTy, VK, OpLoc, CurFPFeatures);
if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method))
return ExprError();
@@ -14845,7 +14844,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
return UnaryOperator::Create(
Context, SubExpr, UO_AddrOf, MemPtrType, VK_RValue, OK_Ordinary,
- UnOp->getOperatorLoc(), false, CurFPFeatureOverrides());
+ UnOp->getOperatorLoc(), false, CurFPFeatures);
}
}
Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(),
@@ -14853,10 +14852,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
if (SubExpr == UnOp->getSubExpr())
return UnOp;
- return UnaryOperator::Create(Context, SubExpr, UO_AddrOf,
- Context.getPointerType(SubExpr->getType()),
- VK_RValue, OK_Ordinary, UnOp->getOperatorLoc(),
- false, CurFPFeatureOverrides());
+ return UnaryOperator::Create(
+ Context, SubExpr, UO_AddrOf, Context.getPointerType(SubExpr->getType()),
+ VK_RValue, OK_Ordinary, UnOp->getOperatorLoc(), false, CurFPFeatures);
}
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp
index d17599a6ed14..da777201af88 100644
--- a/clang/lib/Sema/SemaPseudoObject.cpp
+++ b/clang/lib/Sema/SemaPseudoObject.cpp
@@ -130,7 +130,7 @@ namespace {
return UnaryOperator::Create(
S.Context, e, uop->getOpcode(), uop->getType(), uop->getValueKind(),
uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow(),
- S.CurFPFeatureOverrides());
+ S.CurFPFeatures);
}
if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
@@ -446,10 +446,9 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc,
ExprResult result;
if (opcode == BO_Assign) {
result = semanticRHS;
- syntactic = BinaryOperator::Create(S.Context, syntacticLHS, capturedRHS,
- opcode, capturedRHS->getType(),
- capturedRHS->getValueKind(), OK_Ordinary,
- opcLoc, S.CurFPFeatureOverrides());
+ syntactic = BinaryOperator::Create(
+ S.Context, syntacticLHS, capturedRHS, opcode, capturedRHS->getType(),
+ capturedRHS->getValueKind(), OK_Ordinary, opcLoc, S.CurFPFeatures);
} else {
ExprResult opLHS = buildGet();
@@ -463,9 +462,8 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc,
syntactic = CompoundAssignOperator::Create(
S.Context, syntacticLHS, capturedRHS, opcode, result.get()->getType(),
- result.get()->getValueKind(), OK_Ordinary, opcLoc,
- S.CurFPFeatureOverrides(), opLHS.get()->getType(),
- result.get()->getType());
+ result.get()->getValueKind(), OK_Ordinary, opcLoc, S.CurFPFeatures,
+ opLHS.get()->getType(), result.get()->getType());
}
// The result of the assignment, if not void, is the value set into
@@ -533,7 +531,7 @@ PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
? S.Context.getTypeSize(resultType) >=
S.Context.getTypeSize(S.Context.IntTy)
: false,
- S.CurFPFeatureOverrides());
+ S.CurFPFeatures);
return complete(syntactic);
}
@@ -1555,7 +1553,7 @@ ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
if (op->isTypeDependent())
return UnaryOperator::Create(Context, op, opcode, Context.DependentTy,
VK_RValue, OK_Ordinary, opcLoc, false,
- CurFPFeatureOverrides());
+ CurFPFeatures);
assert(UnaryOperator::isIncrementDecrementOp(opcode));
Expr *opaqueRef = op->IgnoreParens();
@@ -1586,7 +1584,7 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
if (LHS->isTypeDependent() || RHS->isTypeDependent())
return BinaryOperator::Create(Context, LHS, RHS, opcode,
Context.DependentTy, VK_RValue, OK_Ordinary,
- opcLoc, CurFPFeatureOverrides());
+ opcLoc, CurFPFeatures);
// Filter out non-overload placeholder types in the RHS.
if (RHS->getType()->isNonOverloadPlaceholderType()) {
@@ -1642,7 +1640,7 @@ Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
return UnaryOperator::Create(Context, op, uop->getOpcode(), uop->getType(),
uop->getValueKind(), uop->getObjectKind(),
uop->getOperatorLoc(), uop->canOverflow(),
- CurFPFeatureOverrides());
+ CurFPFeatures);
} else if (CompoundAssignOperator *cop
= dyn_cast<CompoundAssignOperator>(syntax)) {
Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
@@ -1650,7 +1648,7 @@ Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
return CompoundAssignOperator::Create(
Context, lhs, rhs, cop->getOpcode(), cop->getType(),
cop->getValueKind(), cop->getObjectKind(), cop->getOperatorLoc(),
- CurFPFeatureOverrides(), cop->getComputationLHSType(),
+ CurFPFeatures, cop->getComputationLHSType(),
cop->getComputationResultType());
} else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
@@ -1659,7 +1657,7 @@ Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
return BinaryOperator::Create(Context, lhs, rhs, bop->getOpcode(),
bop->getType(), bop->getValueKind(),
bop->getObjectKind(), bop->getOperatorLoc(),
- CurFPFeatureOverrides());
+ CurFPFeatures);
} else if (isa<CallExpr>(syntax)) {
return syntax;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 65d1182cc5d8..ce9c30339617 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -10564,10 +10564,8 @@ TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
return getDerived().RebuildBinaryOperator(
E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
- FPOptionsOverride NewOverrides(E->getFPFeatures(getSema().getLangOpts()));
- getSema().CurFPFeatures =
- NewOverrides.applyOverrides(getSema().getLangOpts());
- getSema().FpPragmaStack.CurrentValue = NewOverrides.getAsOpaqueInt();
+ getSema().CurFPFeatures = E->getFPFeatures(getSema().getLangOpts());
+
return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
LHS.get(), RHS.get());
}
@@ -10621,10 +10619,7 @@ ExprResult
TreeTransform<Derived>::TransformCompoundAssignOperator(
CompoundAssignOperator *E) {
Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
- FPOptionsOverride NewOverrides(E->getFPFeatures(getSema().getLangOpts()));
- getSema().CurFPFeatures =
- NewOverrides.applyOverrides(getSema().getLangOpts());
- getSema().FpPragmaStack.CurrentValue = NewOverrides.getAsOpaqueInt();
+ getSema().CurFPFeatures = E->getFPFeatures(getSema().getLangOpts());
return getDerived().TransformBinaryOperator(E);
}
@@ -11099,10 +11094,7 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
return SemaRef.MaybeBindToTemporary(E);
Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
- FPOptionsOverride NewOverrides(E->getFPFeatures());
- getSema().CurFPFeatures =
- NewOverrides.applyOverrides(getSema().getLangOpts());
- getSema().FpPragmaStack.CurrentValue = NewOverrides.getAsOpaqueInt();
+ getSema().CurFPFeatures = E->getFPFeatures();
return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
E->getOperatorLoc(),
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index ac45d1ec2632..4dd2054d4b07 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7843,9 +7843,7 @@ void ASTReader::InitializeSema(Sema &S) {
// FIXME: What happens if these are changed by a module import?
if (!FPPragmaOptions.empty()) {
assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS");
- FPOptionsOverride NewOverrides(FPPragmaOptions[0]);
- SemaObj->CurFPFeatures =
- NewOverrides.applyOverrides(SemaObj->getLangOpts());
+ SemaObj->CurFPFeatures = FPOptions(FPPragmaOptions[0]);
}
SemaObj->OpenCLFeatures.copy(OpenCLExtensions);
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 9d4a0b6ccafd..0c379839ba83 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -706,7 +706,7 @@ void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) {
E->setOperatorLoc(readSourceLocation());
E->setCanOverflow(Record.readInt());
if (hasFP_Features)
- E->setStoredFPFeatures(FPOptionsOverride(Record.readInt()));
+ E->setStoredFPFeatures(FPOptions(Record.readInt()));
}
void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) {
@@ -1089,7 +1089,7 @@ void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
E->setRHS(Record.readSubExpr());
E->setOperatorLoc(readSourceLocation());
if (hasFP_Features)
- E->setStoredFPFeatures(FPOptionsOverride(Record.readInt()));
+ E->setStoredFPFeatures(FPOptions(Record.readInt()));
}
void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
@@ -1657,8 +1657,8 @@ void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
VisitCallExpr(E);
E->CXXOperatorCallExprBits.OperatorKind = Record.readInt();
+ E->CXXOperatorCallExprBits.FPFeatures = Record.readInt();
E->Range = Record.readSourceRange();
- E->setFPFeatures(FPOptionsOverride(Record.readInt()));
}
void ASTStmtReader::VisitCXXRewrittenBinaryOperator(
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 6f364df80f32..2a17360a67bc 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -3960,7 +3960,7 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
}
/// Write an FP_PRAGMA_OPTIONS block for the given FPOptions.
-void ASTWriter::WriteFPPragmaOptions(const FPOptionsOverride &Opts) {
+void ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) {
RecordData::value_type Record[] = {Opts.getAsOpaqueInt()};
Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record);
}
@@ -4790,7 +4790,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
WriteReferencedSelectorsPool(SemaRef);
WriteLateParsedTemplates(SemaRef);
WriteIdentifierTable(PP, SemaRef.IdResolver, isModule);
- WriteFPPragmaOptions(SemaRef.CurFPFeatureOverrides());
+ WriteFPPragmaOptions(SemaRef.getCurFPFeatures());
WriteOpenCLExtensions(SemaRef);
WriteOpenCLExtensionTypes(SemaRef);
WriteCUDAPragmas(SemaRef);
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index abc6081da502..b13d0df9c376 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1545,8 +1545,8 @@ void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
VisitCallExpr(E);
Record.push_back(E->getOperator());
- Record.AddSourceRange(E->Range);
Record.push_back(E->getFPFeatures().getAsOpaqueInt());
+ Record.AddSourceRange(E->Range);
Code = serialization::EXPR_CXX_OPERATOR_CALL;
}
diff --git a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
index 548809521f7f..7d8843220f44 100644
--- a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
+++ b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
@@ -119,24 +119,6 @@ float fma_test1(float a, float b, float c) {
return x;
}
-#pragma float_control(push)
-#pragma float_control(precise, on)
-struct Distance {};
-Distance operator+(Distance, Distance);
-
-template <class T>
-T add(T lhs, T rhs) {
-#pragma float_control(except, on)
- return lhs + rhs;
-}
-#pragma float_control(pop)
-
-float test_OperatorCall() {
- return add(1.0f, 2.0f);
- //CHECK: llvm.experimental.constrained.fadd{{.*}}fpexcept.strict
-}
-// CHECK-LABEL define float {{.*}}test_OperatorCall{{.*}}
-
#if FENV_ON
// expected-warning at +1{{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}}
#pragma STDC FENV_ACCESS ON
diff --git a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl
index 1f12392d861b..ced15f6a8f3d 100644
--- a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl
+++ b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl
@@ -5,17 +5,6 @@
// RUN: %clang_cc1 %s -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD
// RUN: %clang_cc1 %s -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED
-// Check the fp options are correct with PCH.
-// RUN: %clang_cc1 %s -DGEN_PCH=1 -finclude-default-header -triple spir-unknown-unknown -emit-pch -o %t.pch
-// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -o - | FileCheck %s -check-prefix=NORMAL
-// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-fast-relaxed-math -o - | FileCheck %s -check-prefix=FAST
-// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-finite-math-only -o - | FileCheck %s -check-prefix=FINITE
-// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-unsafe-math-optimizations -o - | FileCheck %s -check-prefix=UNSAFE
-// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-mad-enable -o - | FileCheck %s -check-prefix=MAD
-// RUN: %clang_cc1 %s -include-pch %t.pch -fno-validate-pch -emit-llvm -cl-no-signed-zeros -o - | FileCheck %s -check-prefix=NOSIGNED
-
-#if !GEN_PCH
-
float spscalardiv(float a, float b) {
// CHECK: @spscalardiv(
@@ -64,8 +53,3 @@ float spscalardiv(float a, float b) {
// NOSIGNED: "no-nans-fp-math"="false"
// NOSIGNED: "no-signed-zeros-fp-math"="true"
// NOSIGNED: "unsafe-fp-math"="false"
-
-#else
-// Undefine this to avoid putting it in the PCH.
-#undef GEN_PCH
-#endif
diff --git a/clang/test/PCH/pragma-floatcontrol.c b/clang/test/PCH/pragma-floatcontrol.c
index 8be46dbd1655..a0918dd53597 100644
--- a/clang/test/PCH/pragma-floatcontrol.c
+++ b/clang/test/PCH/pragma-floatcontrol.c
@@ -6,18 +6,6 @@
// Test with pch.
// RUN: %clang_cc1 %s -DSET -emit-pch -o %t
// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s
-// RUN: %clang_cc1 %s -ffp-contract=on -DSET -emit-pch -o %t
-// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s
-// RUN: %clang_cc1 %s -menable-no-nans -DSET -emit-pch -o %t
-// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s
-// RUN: %clang_cc1 %s -frounding-math -DSET -emit-pch -o %t
-// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s
-// RUN: %clang_cc1 %s -ffp-exception-behavior=maytrap -DSET -emit-pch -o %t
-// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s
-// RUN: %clang_cc1 %s -ffp-contract=fast -DSET -emit-pch -o %t
-// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s
-// RUN: %clang_cc1 %s -DSET -emit-pch -o %t
-// RUN: %clang_cc1 %s -ffp-contract=on -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-CONTRACT %s
// RUN: %clang_cc1 %s -DPUSH -emit-pch -o %t
// RUN: %clang_cc1 %s -DPUSH -verify -include-pch %t
// RUN: %clang_cc1 %s -DPUSH_POP -emit-pch -o %t
@@ -48,7 +36,6 @@ float fun(float a, float b) {
// CHECK-LABEL: define float @fun{{.*}}
//CHECK-EBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict
//CHECK-EBSTRICT: llvm.experimental.constrained.fadd{{.*}}tonearest{{.*}}strict
- //CHECK-CONTRACT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict
return a * b + 2;
}
#pragma float_control(pop) // expected-warning {{#pragma float_control(pop, ...) failed: stack empty}}
diff --git a/clang/test/SemaOpenCL/fp-options.cl b/clang/test/SemaOpenCL/fp-options.cl
deleted file mode 100644
index 413afd61819d..000000000000
--- a/clang/test/SemaOpenCL/fp-options.cl
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 %s -finclude-default-header -triple spir-unknown-unknown -emit-pch -o %t.pch
-// RUN: %clang_cc1 %s -finclude-default-header -cl-no-signed-zeros -triple spir-unknown-unknown -include-pch %t.pch -fsyntax-only -verify
-// expected-no-diagnostics
-
More information about the cfe-commits
mailing list