mibintc updated this revision to Diff 295880.
mibintc added a comment.
I patched my workspace with D88498 <https://reviews.llvm.org/D88498> from Sept
29. I fixed some nits and also enabled FENV_ACCESS when the command line option
specifies frounding-math. This corresponds to Microsoft's documentation of
their option /fp:strict
https://docs.microsoft.com/en-us/cpp/preprocessor/fenv-access?view=vs-2019 "The
[/fp:strict] command-line option automatically enables fenv_access." Also if
#pragma to enable fenv_access is seen, RoundingMode is set to Dynamic
I have some questions I'll add them as inline comments
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D87528/new/
https://reviews.llvm.org/D87528
Files:
clang/include/clang/Basic/DiagnosticASTKinds.td
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/ExprConstant.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/CodeGen/CodeGenModule.h
clang/lib/Parse/ParsePragma.cpp
clang/lib/Parse/ParseStmt.cpp
clang/lib/Sema/SemaAttr.cpp
clang/lib/Sema/SemaStmt.cpp
clang/test/CXX/expr/expr.const/p2-0x.cpp
clang/test/CodeGen/fp-floatcontrol-pragma.cpp
clang/test/CodeGen/pragma-fenv_access.c
clang/test/Parser/fp-floatcontrol-syntax.cpp
clang/test/Parser/pragma-fenv_access.c
clang/test/Preprocessor/pragma_unknown.c
Index: clang/test/Preprocessor/pragma_unknown.c
===================================================================
--- clang/test/Preprocessor/pragma_unknown.c
+++ clang/test/Preprocessor/pragma_unknown.c
@@ -16,15 +16,6 @@
// CHECK: {{^}}#pragma STDC FP_CONTRACT DEFAULT{{$}}
// CHECK: {{^}}#pragma STDC FP_CONTRACT IN_BETWEEN{{$}}
-#pragma STDC FENV_ACCESS ON // expected-warning {{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}}
-#pragma STDC FENV_ACCESS OFF
-#pragma STDC FENV_ACCESS DEFAULT
-#pragma STDC FENV_ACCESS IN_BETWEEN // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}}
-// CHECK: {{^}}#pragma STDC FENV_ACCESS ON{{$}}
-// CHECK: {{^}}#pragma STDC FENV_ACCESS OFF{{$}}
-// CHECK: {{^}}#pragma STDC FENV_ACCESS DEFAULT{{$}}
-// CHECK: {{^}}#pragma STDC FENV_ACCESS IN_BETWEEN{{$}}
-
#pragma STDC CX_LIMITED_RANGE ON
#pragma STDC CX_LIMITED_RANGE OFF
#pragma STDC CX_LIMITED_RANGE DEFAULT
Index: clang/test/Parser/pragma-fenv_access.c
===================================================================
--- /dev/null
+++ clang/test/Parser/pragma-fenv_access.c
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -ffp-exception-behavior=strict -DSTRICT -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c++ -DCPP -DSTRICT -ffp-exception-behavior=strict -fsyntax-only -verify %s
+#ifdef CPP
+#define CONST constexpr
+#else
+#define CONST const
+#endif
+
+#pragma STDC FENV_ACCESS IN_BETWEEN // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}}
+
+#pragma STDC FENV_ACCESS OFF
+
+float func_04(int x, float y) {
+ if (x)
+ return y + 2;
+ #pragma STDC FENV_ACCESS ON // expected-error{{'#pragma STDC FENV_ACCESS' can only appear at file scope or at the start of a compound statement}}
+ return x + y;
+}
+
+int main() {
+ CONST float one = 1.0F ;
+ CONST float three = 3.0F ;
+ CONST float four = 4.0F ;
+ CONST float frac_ok = one/four;
+#if defined(CPP) & defined(STRICT)
+//expected-error@+3 {{constexpr variable 'frac' must be initialized by a constant expression}}
+//expected-note@+2 {{compile time floating point arithmetic suppressed in strict evaluation modes}}
+#endif
+ CONST float frac = one/three; // rounding
+ CONST double d = one;
+ CONST int not_too_big = 255;
+ CONST float fnot_too_big = not_too_big;
+ CONST int too_big = 0x7ffffff0;
+#if defined(CPP) & defined(STRICT)
+//expected-error@+6 {{constexpr variable 'fbig' must be initialized by a constant expression}}
+//expected-note@+5 {{compile time floating point arithmetic suppressed in strict evaluation modes}}
+#endif
+#if defined(CPP)
+//expected-warning@+2{{implicit conversion}}
+#endif
+ CONST float fbig = too_big; // inexact
+ if (one <= four) return 0;
+ return -1;
+}
Index: clang/test/Parser/fp-floatcontrol-syntax.cpp
===================================================================
--- clang/test/Parser/fp-floatcontrol-syntax.cpp
+++ clang/test/Parser/fp-floatcontrol-syntax.cpp
@@ -26,19 +26,14 @@
double a = 0.0;
double b = 1.0;
-//FIXME At some point this warning will be removed, until then
-// document the warning
-#ifdef FAST
-// expected-warning@+1{{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}}
-#pragma STDC FENV_ACCESS ON
-#else
-#pragma STDC FENV_ACCESS ON // expected-warning{{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}}
-#endif
#ifdef STRICT
#pragma float_control(precise, off) // expected-error {{'#pragma float_control(precise, off)' is illegal when except is enabled}}
#else
+#ifndef FAST
// Currently FENV_ACCESS cannot be enabled by pragma, skip error check
-#pragma float_control(precise, off) // not-expected-error {{'#pragma float_control(precise, off)' is illegal when fenv_access is enabled}}
+#pragma STDC FENV_ACCESS ON
+#pragma float_control(precise, off) // expected-error {{'#pragma float_control(precise, off)' is illegal when fenv_access is enabled}}
+#endif
#endif
#pragma float_control(precise, on)
Index: clang/test/CodeGen/pragma-fenv_access.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/pragma-fenv_access.c
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -ffp-exception-behavior=strict -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+
+#pragma STDC FENV_ACCESS ON
+
+float func_01(float x, float y) {
+ return x + y;
+}
+// CHECK-LABEL: @func_01
+// CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
+
+
+float func_02(float x, float y) {
+ #pragma float_control(except, off)
+ #pragma STDC FENV_ACCESS OFF
+ return x + y;
+}
+// CHECK-LABEL: @func_02
+// CHECK: fadd float {{.*}}
+
+
+float func_03(float x, float y) {
+ return x + y;
+}
+// CHECK-LABEL: @func_03
+// CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
+
+
+#pragma STDC FENV_ACCESS OFF
+
+float func_04(float x, float y) {
+ #pragma float_control(except, off)
+ return x + y;
+}
+// CHECK-LABEL: @func_04
+// CHECK: fadd float {{.*}}
+
+
+float func_05(float x, float y) {
+ #pragma STDC FENV_ACCESS ON
+ return x + y;
+}
+// CHECK-LABEL: @func_05
+// CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
+
+
+float func_06(float x, float y) {
+ #pragma float_control(except, off)
+ return x + y;
+}
+// CHECK-LABEL: @func_06
+// CHECK: fadd float {{.*}}
+
+
+float func_07(float x, float y) {
+ x -= y;
+ if (x) {
+ #pragma STDC FENV_ACCESS ON
+ y *= 2;
+ }
+ return y + 4;
+}
+// CHECK-LABEL: @func_07
+// CHECK: call float @llvm.experimental.constrained.fsub.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
+// CHECK: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict")
+// CHECK: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
Index: clang/test/CodeGen/fp-floatcontrol-pragma.cpp
===================================================================
--- clang/test/CodeGen/fp-floatcontrol-pragma.cpp
+++ clang/test/CodeGen/fp-floatcontrol-pragma.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -DEXCEPT=1 -fcxx-exceptions -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-NS %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -verify -DFENV_ON=1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -DFENV_ON=1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-FENV %s
// RUN: %clang_cc1 -triple %itanium_abi_triple -O3 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-O3 %s
// Verify float_control(precise, off) enables fast math flags on fp operations.
@@ -138,7 +138,6 @@
// CHECK-LABEL define float {{.*}}test_OperatorCall{{.*}}
#if FENV_ON
-// expected-warning@+1{{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}}
#pragma STDC FENV_ACCESS ON
#endif
// CHECK-LABEL: define {{.*}}callt{{.*}}
@@ -146,7 +145,21 @@
void callt() {
volatile float z;
z = z * z;
-//CHECK: = fmul float
+ //CHECK-FENV: llvm.experimental.constrained.fmul{{.*}}
+}
+
+// CHECK-LABEL: define {{.*}}myAdd{{.*}}
+float myAdd(int i, float f) {
+ if (i<0)
+ return 1.0 + 2.0;
+ // Check that floating point constant folding doesn't occur if
+ // #pragma STC FENV_ACCESS is enabled.
+ //CHECK-FENV: llvm.experimental.constrained.fadd{{.*}}double 1.0{{.*}}double 2.0{{.*}}
+ //CHECK: store float 3.0{{.*}}retval{{.*}}
+ static double v = 1.0 / 3.0;
+ //CHECK-FENV: llvm.experimental.constrained.fdiv{{.*}}double 1.0{{.*}}double 3.0{{.*}}
+ //CHECK-NOT: fdiv
+ return v;
}
#if EXCEPT
Index: clang/test/CXX/expr/expr.const/p2-0x.cpp
===================================================================
--- clang/test/CXX/expr/expr.const/p2-0x.cpp
+++ clang/test/CXX/expr/expr.const/p2-0x.cpp
@@ -280,6 +280,16 @@
constexpr float f10 = f2 - f2; // expected-error {{constant expression}} expected-note {{produces a NaN}}
constexpr float f11 = f2 + f4; // expected-error {{constant expression}} expected-note {{produces a NaN}}
constexpr float f12 = f2 / f2; // expected-error {{constant expression}} expected-note {{produces a NaN}}
+#pragma float_control(push)
+#pragma float_control(except, on)
+constexpr float pi = 3.14f;
+constexpr unsigned ubig = 0xFFFFFFFF;
+constexpr float ce = 1.0 / 3.0; // expected-error {{constant expression}} expected-note {{floating point arithmetic suppressed in strict evaluation modes}}
+constexpr int ci = (int) pi;
+constexpr float fbig = (float) ubig; // expected-error {{constant expression}} expected-note {{floating point arithmetic suppressed in strict evaluation modes}}
+constexpr float fabspi = __builtin_fabs(pi); // no error expected
+constexpr float negpi = -pi; // expect no error on unary operator
+#pragma float_control(pop)
static_assert(!isinf(f1), "");
static_assert(isinf(f2), "");
static_assert(!isinf(f3), "");
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -389,6 +389,13 @@
PopCompoundScope();
}
+void Sema::ActOnAfterCompoundStatementLeadingPragmas() {
+ if (getCurFPFeatures().getAllowFEnvAccess()) {
+ FunctionDecl *F = getCurFunctionDecl();
+ F->setUsesFPIntrin(true);
+ }
+}
+
sema::CompoundScopeInfo &Sema::getCurCompoundScope() const {
return getCurFunction()->CompoundScopes.back();
}
Index: clang/lib/Sema/SemaAttr.cpp
===================================================================
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -1010,8 +1010,14 @@
if (!isPreciseFPEnabled())
Diag(Loc, diag::err_pragma_fenv_requires_precise);
NewFPFeatures.setAllowFEnvAccessOverride(true);
- } else
+ // Enabling FENV access sets the RoundingMode to Dynamic.
+ NewFPFeatures.setRoundingModeOverride(llvm::RoundingMode::Dynamic);
+ } else {
NewFPFeatures.setAllowFEnvAccessOverride(false);
+ // Resume the default rounding mode.
+ NewFPFeatures.setRoundingModeOverride(
+ llvm::RoundingMode::NearestTiesToEven);
+ }
FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
}
Index: clang/lib/Parse/ParseStmt.cpp
===================================================================
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -366,7 +366,8 @@
case tok::annot_pragma_fenv_access:
ProhibitAttributes(Attrs);
- HandlePragmaFEnvAccess();
+ Diag(Tok, diag::err_pragma_stdc_fenv_access_scope);
+ ConsumeAnnotationToken();
return StmtEmpty();
case tok::annot_pragma_fenv_round:
@@ -1033,9 +1034,9 @@
Tok.getLocation(),
"in compound statement ('{}')");
- // Record the state of the FPFeatures, restore on leaving the
+ // Record the current FPFeatures, restore on leaving the
// compound statement.
- Sema::FPFeaturesStateRAII SaveFPContractState(Actions);
+ Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
InMessageExpressionRAIIObject InMessage(*this, false);
BalancedDelimiterTracker T(*this, tok::l_brace);
@@ -1046,6 +1047,7 @@
// Parse any pragmas at the beginning of the compound statement.
ParseCompoundStatementLeadingPragmas();
+ Actions.ActOnAfterCompoundStatementLeadingPragmas();
StmtVector Stmts;
Index: clang/lib/Parse/ParsePragma.cpp
===================================================================
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -106,10 +106,6 @@
tok::OnOffSwitch OOS;
if (PP.LexOnOffSwitch(OOS))
return;
- if (OOS == tok::OOS_ON) {
- PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
- return;
- }
MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1);
Index: clang/lib/CodeGen/CodeGenModule.h
===================================================================
--- clang/lib/CodeGen/CodeGenModule.h
+++ clang/lib/CodeGen/CodeGenModule.h
@@ -1137,6 +1137,10 @@
/// definition.
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F);
+ /// Set the LLVM function attributes that represent floating point
+ /// environment.
+ void setLLVMFunctionFEnvAttributes(const FunctionDecl *D, llvm::Function *F);
+
/// Return true iff the given type uses 'sret' when used as a return type.
bool ReturnTypeUsesSRet(const CGFunctionInfo &FI);
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -1742,6 +1742,15 @@
}
}
+void CodeGenModule::setLLVMFunctionFEnvAttributes(const FunctionDecl *D,
+ llvm::Function *F) {
+ if (D->usesFPIntrin()) {
+ llvm::AttrBuilder FuncAttrs;
+ FuncAttrs.addAttribute("strictfp");
+ F->addAttributes(llvm::AttributeList::FunctionIndex, FuncAttrs);
+ }
+}
+
void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) {
const Decl *D = GD.getDecl();
if (dyn_cast_or_null<NamedDecl>(D))
@@ -4576,9 +4585,11 @@
MaybeHandleStaticInExternC(D, Fn);
-
maybeSetTrivialComdat(*D, *Fn);
+ // Set CodeGen attributes that represent floating point environment.
+ setLLVMFunctionFEnvAttributes(D, Fn);
+
CodeGenFunction(*this).GenerateCode(GD, Fn, FI);
setNonAliasAttributes(GD, Fn);
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -140,7 +140,8 @@
FMFGuard.emplace(CGF.Builder);
llvm::RoundingMode NewRoundingBehavior =
- static_cast<llvm::RoundingMode>(FPFeatures.getRoundingMode());
+ FPFeatures.getAllowFEnvAccess() ? llvm::RoundingMode::Dynamic :
+ static_cast<llvm::RoundingMode>(FPFeatures.getRoundingMode());
CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
auto NewExceptionBehavior =
ToConstrainedExceptMD(static_cast<LangOptions::FPExceptionModeKind>(
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -2439,6 +2439,12 @@
return false;
}
+ if ((St != APFloat::opOK) && FPO.isFPConstrained() &&
+ Info.Ctx.getLangOpts().CPlusPlus) {
+ Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
+ return false;
+ }
+
if (St & APFloat::opStatus::opInvalidOp) {
// There is no usefully definable result.
Info.FFDiag(E);
@@ -2481,11 +2487,17 @@
}
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E,
+ const FPOptions FPO,
QualType SrcType, const APSInt &Value,
QualType DestType, APFloat &Result) {
Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
- Result.convertFromAPInt(Value, Value.isSigned(),
- APFloat::rmNearestTiesToEven);
+ if (llvm::APFloatBase::opOK != Result.convertFromAPInt(Value,
+ Value.isSigned(),
+ APFloat::rmNearestTiesToEven) &&
+ FPO.isFPConstrained()) {
+ Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
+ return false;
+ }
return true;
}
@@ -2719,7 +2731,7 @@
// mathematically defined [...], the behavior is undefined.
// FIXME: C++ rules require us to not conform to IEEE 754 here.
if (LHS.isNaN()) {
- Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
+ Info.FFDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
return Info.noteUndefinedBehavior();
}
@@ -4192,9 +4204,11 @@
Value = HandleIntToIntCast(Info, E, SubobjType, PromotedLHSType, LHS);
return true;
} else if (RHS.isFloat()) {
+ const FPOptions FPO = E->getFPFeaturesInEffect(
+ Info.Ctx.getLangOpts());
APFloat FValue(0.0);
- return HandleIntToFloatCast(Info, E, SubobjType, Value, PromotedLHSType,
- FValue) &&
+ return HandleIntToFloatCast(Info, E, FPO, SubobjType, Value,
+ PromotedLHSType, FValue) &&
handleFloatFloatBinOp(Info, E, FValue, Opcode, RHS.getFloat()) &&
HandleFloatToIntCast(Info, E, PromotedLHSType, FValue, SubobjType,
Value);
@@ -12282,8 +12296,15 @@
return false;
assert(E->isComparisonOp() && "Invalid binary operator!");
+ llvm::APFloatBase::cmpResult CmpResult = LHS.compare(RHS);
+ if (CmpResult == APFloat::cmpUnordered &&
+ E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()).isFPConstrained()) {
+ // Note: Compares may raise invalid in some cases involving NaN or sNaN.
+ Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
+ return false;
+ }
auto GetCmpRes = [&]() {
- switch (LHS.compare(RHS)) {
+ switch (CmpResult) {
case APFloat::cmpEqual:
return CmpResult::Equal;
case APFloat::cmpLessThan:
@@ -13318,6 +13339,11 @@
case Builtin::BI__builtin_fabsf:
case Builtin::BI__builtin_fabsl:
case Builtin::BI__builtin_fabsf128:
+ // The C standard says "fabs raises no floating-point exceptions,
+ // even if x is a signaling NaN. The returned value is independent of
+ // the current rounding direction mode." Therefore constant folding can
+ // proceed without regard to the floating point settings.
+ // Reference, WG14 N2478 F.10.4.3
if (!EvaluateFloat(E->getArg(0), Result, Info))
return false;
@@ -13376,6 +13402,9 @@
case UO_Plus:
return EvaluateFloat(E->getSubExpr(), Result, Info);
case UO_Minus:
+ // In C standard, WG14 N2478 F.3 p4
+ // "the unary - raises no floating point exceptions,
+ // even if the operand is signalling."
if (!EvaluateFloat(E->getSubExpr(), Result, Info))
return false;
Result.changeSign();
@@ -13409,9 +13438,11 @@
case CK_IntegralToFloating: {
APSInt IntResult;
+ const FPOptions FPO = E->getFPFeaturesInEffect(
+ Info.Ctx.getLangOpts());
return EvaluateInteger(SubExpr, IntResult, Info) &&
- HandleIntToFloatCast(Info, E, SubExpr->getType(), IntResult,
- E->getType(), Result);
+ HandleIntToFloatCast(Info, E, FPO, SubExpr->getType(),
+ IntResult, E->getType(), Result);
}
case CK_FloatingCast: {
@@ -13639,13 +13670,15 @@
if (!Visit(E->getSubExpr()))
return false;
+ const FPOptions FPO = E->getFPFeaturesInEffect(
+ Info.Ctx.getLangOpts());
QualType To = E->getType()->castAs<ComplexType>()->getElementType();
QualType From
= E->getSubExpr()->getType()->castAs<ComplexType>()->getElementType();
Result.makeComplexFloat();
- return HandleIntToFloatCast(Info, E, From, Result.IntReal,
+ return HandleIntToFloatCast(Info, E, FPO, From, Result.IntReal,
To, Result.FloatReal) &&
- HandleIntToFloatCast(Info, E, From, Result.IntImag,
+ HandleIntToFloatCast(Info, E, FPO, From, Result.IntImag,
To, Result.FloatImag);
}
}
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -4343,6 +4343,7 @@
void ActOnFinishOfCompoundStmt();
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
ArrayRef<Stmt *> Elts, bool isStmtExpr);
+ void ActOnAfterCompoundStatementLeadingPragmas();
/// A RAII object to enter scope of a compound statement.
class CompoundScopeRAII {
Index: clang/include/clang/Basic/LangOptions.h
===================================================================
--- clang/include/clang/Basic/LangOptions.h
+++ clang/include/clang/Basic/LangOptions.h
@@ -407,8 +407,9 @@
Value = 0;
setFPContractMode(LO.getDefaultFPContractMode());
setRoundingMode(LO.getFPRoundingMode());
+ // FENV access is true if rounding math is enabled.
+ setAllowFEnvAccess((getRoundingMode() == llvm::RoundingMode::Dynamic));
setFPExceptionMode(LO.getFPExceptionMode());
- setAllowFEnvAccess(LangOptions::FPM_Off);
setAllowFPReassociate(LO.AllowFPReassoc);
setNoHonorNaNs(LO.NoHonorNaNs);
setNoHonorInfs(LO.NoHonorInfs);
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1133,9 +1133,9 @@
// - #pragma stdc unknown
def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
InGroup<UnknownPragmas>;
-def warn_stdc_fenv_access_not_supported :
- Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">,
- InGroup<UnknownPragmas>;
+def err_pragma_stdc_fenv_access_scope : Error<
+ "'#pragma STDC FENV_ACCESS' can only appear at file scope or at the start of a "
+ "compound statement">;
def warn_stdc_fenv_round_not_supported :
Warning<"pragma STDC FENV_ROUND is not supported">,
InGroup<UnknownPragmas>;
Index: clang/include/clang/Basic/DiagnosticASTKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticASTKinds.td
+++ clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -74,6 +74,8 @@
"floating point arithmetic produces %select{an infinity|a NaN}0">;
def note_constexpr_dynamic_rounding : Note<
"cannot evaluate this expression if rounding mode is dynamic">;
+def note_constexpr_float_arithmetic_strict : Note<
+ "compile time floating point arithmetic suppressed in strict evaluation modes">;
def note_constexpr_pointer_subtraction_not_same_array : Note<
"subtracted pointers are not elements of the same array">;
def note_constexpr_pointer_subtraction_zero_size : Note<
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits