mibintc updated this revision to Diff 291736.
mibintc added a comment.
This update uses context information from Expr->getFPFeaturesInEffect() to
disable fp constant folding in ExprConstant.cpp
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/DiagnosticParseKinds.td
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/SemaStmt.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,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#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;
+}
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,66 @@
+// xxx: %clang_cc1 -ffp-exception-behavior=strict -frounding-math -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// 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.tonearest", 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.tonearest", 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.tonearest", 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.tonearest", 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) {
+ 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/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/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
@@ -1725,6 +1725,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))
@@ -4554,9 +4563,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
@@ -900,8 +900,10 @@
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
Builder.setIsFPConstrained(FD->usesFPIntrin());
- if (FD->usesFPIntrin())
+ if (FD->usesFPIntrin()) {
Fn->addFnAttr(llvm::Attribute::StrictFP);
+ Builder.setIsFPConstrained(true);
+ }
}
// If a custom alignment is used, force realigning to this alignment on
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -772,6 +772,10 @@
/// not supported by the interpreter, an error is triggered.
bool EnableNewConstInterp;
+ /// Strict floating point is enabled, this inhibits
+ /// floating ponit constant folding.
+ bool isStrictFP;
+
/// BottomFrame - The frame in which evaluation started. This must be
/// initialized after CurrentCall and CallStackDepth.
CallStackFrame BottomFrame;
@@ -923,11 +927,13 @@
return CheckingForUndefinedBehavior;
}
- EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode)
+ EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode,
+ bool SuppressFPFolding)
: Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
CallStackDepth(0), NextCallIndex(1),
StepsLeft(C.getLangOpts().ConstexprStepLimit),
EnableNewConstInterp(C.getLangOpts().EnableNewConstInterp),
+ isStrictFP(SuppressFPFolding),
BottomFrame(*this, SourceLocation(), nullptr, nullptr, nullptr),
EvaluatingDecl((const ValueDecl *)nullptr),
EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),
@@ -13188,6 +13194,8 @@
static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
assert(E->isRValue() && E->getType()->isRealFloatingType());
+ if (Info.isStrictFP)
+ return false;
return FloatExprEvaluator(Info, Result).Visit(E);
}
@@ -14287,6 +14295,14 @@
return true;
}
+static bool isStrictFPEnabled(const ASTContext &Ctx, const Expr *E) {
+ if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(E))
+ return BE->getFPFeaturesInEffect(Ctx.getLangOpts()).isFPConstrained();
+ if (const CallExpr *CE = dyn_cast<CallExpr>(E))
+ return CE->getFPFeaturesInEffect(Ctx.getLangOpts()).isFPConstrained();
+ return false;
+}
+
/// EvaluateAsRValue - Return true if this is a constant which we can fold using
/// any crazy technique (that has nothing to do with language standards) that
/// we want to. If this function returns true, it returns the folded constant
@@ -14296,7 +14312,8 @@
bool InConstantContext) const {
assert(!isValueDependent() &&
"Expression evaluator can't be called on a dependent expression.");
- EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
+ EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects,
+ isStrictFPEnabled(Ctx, this));
Info.InConstantContext = InConstantContext;
return ::EvaluateAsRValue(this, Result, Ctx, Info);
}
@@ -14315,7 +14332,8 @@
bool InConstantContext) const {
assert(!isValueDependent() &&
"Expression evaluator can't be called on a dependent expression.");
- EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
+ EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects,
+ isStrictFPEnabled(Ctx, this));
Info.InConstantContext = InConstantContext;
return ::EvaluateAsInt(this, Result, Ctx, AllowSideEffects, Info);
}
@@ -14325,7 +14343,8 @@
bool InConstantContext) const {
assert(!isValueDependent() &&
"Expression evaluator can't be called on a dependent expression.");
- EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
+ EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects,
+ isStrictFPEnabled(Ctx, this));
Info.InConstantContext = InConstantContext;
return ::EvaluateAsFixedPoint(this, Result, Ctx, AllowSideEffects, Info);
}
@@ -14354,7 +14373,8 @@
assert(!isValueDependent() &&
"Expression evaluator can't be called on a dependent expression.");
- EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
+ EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold,
+ isStrictFPEnabled(Ctx, this));
Info.InConstantContext = InConstantContext;
LValue LV;
CheckedTemporaries CheckedTemps;
@@ -14375,7 +14395,8 @@
"Expression evaluator can't be called on a dependent expression.");
EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
- EvalInfo Info(Ctx, Result, EM);
+ EvalInfo Info(Ctx, Result, EM,
+ isStrictFPEnabled(Ctx, this));
Info.InConstantContext = true;
if (InPlace) {
@@ -14413,7 +14434,8 @@
EvalInfo Info(Ctx, EStatus, VD->isConstexpr()
? EvalInfo::EM_ConstantExpression
- : EvalInfo::EM_ConstantFold);
+ : EvalInfo::EM_ConstantFold,
+ isStrictFPEnabled(Ctx, this));
Info.setEvaluatingDecl(VD, Value);
Info.InConstantContext = true;
@@ -14458,7 +14480,8 @@
else if (!getDefaultInitValue(getType(), DestroyedValue))
return false;
- EvalInfo Info(getASTContext(), EStatus, EvalInfo::EM_ConstantExpression);
+ EvalInfo Info(getASTContext(), EStatus, EvalInfo::EM_ConstantExpression,
+ /* strict fp enabled */ false);
Info.setEvaluatingDecl(this, DestroyedValue,
EvalInfo::EvaluatingDeclKind::Dtor);
Info.InConstantContext = true;
@@ -14498,7 +14521,8 @@
EvalResult EVResult;
EVResult.Diag = Diag;
- EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
+ EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects,
+ isStrictFPEnabled(Ctx, this));
Info.InConstantContext = true;
bool Result = ::EvaluateAsRValue(this, EVResult, Ctx, Info);
@@ -14516,7 +14540,8 @@
EvalResult EVResult;
EVResult.Diag = Diag;
- EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
+ EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects,
+ isStrictFPEnabled(Ctx, this));
Info.InConstantContext = true;
Info.CheckingForUndefinedBehavior = true;
@@ -14535,7 +14560,8 @@
bool IsConst;
EvalResult EVResult;
if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) {
- EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
+ EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects,
+ isStrictFPEnabled(Ctx, this));
Info.CheckingForUndefinedBehavior = true;
(void)::EvaluateAsRValue(Info, this, EVResult.Val);
}
@@ -14591,7 +14617,8 @@
static ICEDiag CheckEvalInICE(const Expr* E, const ASTContext &Ctx) {
Expr::EvalResult EVResult;
Expr::EvalStatus Status;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
+ EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression,
+ isStrictFPEnabled(Ctx, E));
Info.InConstantContext = true;
if (!::EvaluateAsRValue(E, EVResult, Ctx, Info) || EVResult.HasSideEffects ||
@@ -15066,7 +15093,8 @@
// value.
EvalResult ExprResult;
Expr::EvalStatus Status;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects);
+ EvalInfo Info(Ctx, Status, EvalInfo::EM_IgnoreSideEffects,
+ isStrictFPEnabled(Ctx, this));
Info.InConstantContext = true;
if (!::EvaluateAsInt(this, ExprResult, Ctx, SE_AllowSideEffects, Info))
@@ -15095,7 +15123,8 @@
Expr::EvalStatus Status;
SmallVector<PartialDiagnosticAt, 8> Diags;
Status.Diag = &Diags;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
+ EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression,
+ isStrictFPEnabled(Ctx, this));
APValue Scratch;
bool IsConstExpr =
@@ -15123,7 +15152,8 @@
"Expression evaluator can't be called on a dependent expression.");
Expr::EvalStatus Status;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
+ EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated,
+ isStrictFPEnabled(Ctx, this));
Info.InConstantContext = true;
LValue ThisVal;
@@ -15193,7 +15223,8 @@
Expr::EvalStatus Status;
Status.Diag = &Diags;
- EvalInfo Info(FD->getASTContext(), Status, EvalInfo::EM_ConstantExpression);
+ EvalInfo Info(FD->getASTContext(), Status, EvalInfo::EM_ConstantExpression,
+ /* is FP constant folding enabled */ false);
Info.InConstantContext = true;
Info.CheckingPotentialConstantExpression = true;
@@ -15240,7 +15271,8 @@
Status.Diag = &Diags;
EvalInfo Info(FD->getASTContext(), Status,
- EvalInfo::EM_ConstantExpressionUnevaluated);
+ EvalInfo::EM_ConstantExpressionUnevaluated,
+ isStrictFPEnabled(FD->getASTContext(), E));
Info.InConstantContext = true;
Info.CheckingPotentialConstantExpression = true;
@@ -15264,6 +15296,7 @@
return false;
Expr::EvalStatus Status;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
+ EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold,
+ isStrictFPEnabled(Ctx, this));
return tryEvaluateBuiltinObjectSize(this, Type, Info, Result);
}
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -4329,6 +4329,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/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>;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits