sepavloff updated this revision to Diff 295194.
sepavloff added a comment.
Updated patch
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D88498/new/
https://reviews.llvm.org/D88498
Files:
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseDecl.cpp
clang/test/AST/const-fpfeatures-strict.c
Index: clang/test/AST/const-fpfeatures-strict.c
===================================================================
--- /dev/null
+++ clang/test/AST/const-fpfeatures-strict.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -S -emit-llvm -ffp-exception-behavior=strict -Wno-unknown-pragmas %s -o - | FileCheck %s
+
+// nextUp(1.F) == 0x1.000002p0F
+
+struct S {
+ float f;
+};
+
+static struct S var_01 = {0x1.000001p0};
+struct S *func_01() {
+ return &var_01;
+}
+
+struct S var_02 = {0x1.000001p0};
+
+struct S *func_03() {
+ static struct S var_03 = {0x1.000001p0};
+ return &var_03;
+}
+
+// CHECK: @var_01 = {{.*}} %struct.S { float 1.000000e+00 }
+// CHECK: @var_02 = {{.*}} %struct.S { float 1.000000e+00 }
+// CHECK: @func_03.var_03 = {{.*}} %struct.S { float 1.000000e+00 }
+
+#pragma STDC FENV_ROUND FE_UPWARD
+
+static struct S var_04 = {0x1.000001p0};
+struct S *func_04() {
+ return &var_04;
+}
+
+struct S var_05 = {0x1.000001p0};
+
+struct S *func_06() {
+ static struct S var_06 = {0x1.000001p0};
+ return &var_06;
+}
+
+// CHECK: @var_04 = {{.*}} %struct.S { float 0x3FF0000020000000 }
+// CHECK: @var_05 = {{.*}} %struct.S { float 0x3FF0000020000000 }
+// CHECK: @func_06.var_06 = {{.*}} %struct.S { float 0x3FF0000020000000 }
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -2281,6 +2281,27 @@
}
PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl);
+
+ Sema::FPFeaturesStateRAII FPO(Actions);
+ if (auto VD = dyn_cast_or_null<VarDecl>(ThisDecl))
+ if (!VD->isInvalidDecl()) {
+ // If variable requires constant initialization, set constant
+ // rounding mode.
+ if ((!getLangOpts().CPlusPlus &&
+ (VD->isStaticLocal() || VD->isFileVarDecl())) ||
+ VD->isConstexpr()) {
+ if (Actions.getCurFPFeatures().getRoundingMode() ==
+ llvm::RoundingMode::Dynamic) {
+ // If current rounding mode is 'dynamic', it means that a command
+ // line option line like `-ffpmodel=strict` is in effect. Set
+ // constant rounding to default in this case.
+ FPOptions NewFPO = Actions.getCurFPFeatures();
+ NewFPO.setRoundingMode(llvm::RoundingMode::NearestTiesToEven);
+ Actions.setCurFPFeatures(NewFPO);
+ }
+ }
+ }
+
ExprResult Init = ParseInitializer();
// If this is the only decl in (possibly) range based for statement,
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -589,13 +589,7 @@
// This stack tracks the current state of Sema.CurFPFeatures.
PragmaStack<FPOptionsOverride> FpPragmaStack;
FPOptionsOverride CurFPFeatureOverrides() {
- FPOptionsOverride result;
- if (!FpPragmaStack.hasValue()) {
- result = FPOptionsOverride();
- } else {
- result = FpPragmaStack.CurrentValue;
- }
- return result;
+ return FpPragmaStack.CurrentValue;
}
// RAII object to push / pop sentinel slots for all MS #pragma stacks.
@@ -1429,7 +1423,6 @@
const LangOptions &getLangOpts() const { return LangOpts; }
OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; }
- FPOptions &getCurFPFeatures() { return CurFPFeatures; }
DiagnosticsEngine &getDiagnostics() const { return Diags; }
SourceManager &getSourceManager() const { return SourceMgr; }
@@ -1439,6 +1432,12 @@
ASTMutationListener *getASTMutationListener() const;
ExternalSemaSource* getExternalSource() const { return ExternalSource; }
+ const FPOptions &getCurFPFeatures() const { return CurFPFeatures; }
+ void setCurFPFeatures(FPOptions FPO) {
+ FpPragmaStack.CurrentValue = FPOptionsOverride(FPO, CurFPFeatures);
+ CurFPFeatures = FPO;
+ }
+
///Registers an external source. If an external source already exists,
/// creates a multiplex external source and appends to it.
///
Index: clang/include/clang/Basic/LangOptions.h
===================================================================
--- clang/include/clang/Basic/LangOptions.h
+++ clang/include/clang/Basic/LangOptions.h
@@ -450,6 +450,15 @@
return Opts;
}
+ storage_type getDiffWith(FPOptions FPO) const {
+ storage_type Diff = 0;
+#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
+ if (get##NAME() != FPO.get##NAME()) \
+ Diff |= NAME##Mask;
+#include "clang/Basic/FPOptions.def"
+ return Diff;
+ }
+
// We can define most of the accessors automatically:
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
TYPE get##NAME() const { \
@@ -498,6 +507,8 @@
: Options(LO), OverrideMask(OverrideMaskBits) {}
FPOptionsOverride(FPOptions FPO)
: Options(FPO), OverrideMask(OverrideMaskBits) {}
+ FPOptionsOverride(FPOptions New, FPOptions Old)
+ : Options(New), OverrideMask(New.getDiffWith(Old)) {}
bool requiresTrailingStorage() const { return OverrideMask != 0; }
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits