Reapply "Add support for #pragma float_control" with buildbot fixes
Add support for #pragma float_control
Reviewers: rjmccall, erichkeane, sepavloff
Differential Revision: https://reviews.llvm.org/D72841
This reverts commit fce82c0ed310174fe48e2402ac731b6340098389.
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 8633581..518ac0f 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -407,6 +407,65 @@
Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD));
}
+void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
+ PragmaMsStackAction Action,
+ PragmaFloatControlKind Value) {
+ auto NewValue = FpPragmaStack.CurrentValue;
+ FPOptions NewFPFeatures(NewValue);
+ if ((Action == PSK_Push_Set || Action == PSK_Push || Action == PSK_Pop) &&
+ !CurContext->isTranslationUnit()) {
+ // Push and pop can only occur at file scope.
+ Diag(Loc, diag::err_pragma_fc_pp_scope);
+ return;
+ }
+ switch (Value) {
+ default:
+ llvm_unreachable("invalid pragma float_control kind");
+ case PFC_Precise:
+ CurFPFeatures.setFPPreciseEnabled(true);
+ NewValue = CurFPFeatures.getAsOpaqueInt();
+ FpPragmaStack.Act(Loc, Action, StringRef(), NewValue);
+ break;
+ case PFC_NoPrecise:
+ if (CurFPFeatures.getExceptionMode() == LangOptions::FPE_Strict)
+ Diag(Loc, diag::err_pragma_fc_noprecise_requires_noexcept);
+ else if (CurFPFeatures.allowFEnvAccess())
+ Diag(Loc, diag::err_pragma_fc_noprecise_requires_nofenv);
+ else
+ 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
+ CurFPFeatures.setExceptionMode(LangOptions::FPE_Strict);
+ NewValue = CurFPFeatures.getAsOpaqueInt();
+ FpPragmaStack.Act(Loc, Action, StringRef(), NewValue);
+ break;
+ case PFC_NoExcept:
+ CurFPFeatures.setExceptionMode(LangOptions::FPE_Ignore);
+ NewValue = CurFPFeatures.getAsOpaqueInt();
+ FpPragmaStack.Act(Loc, Action, StringRef(), NewValue);
+ break;
+ case PFC_Push:
+ Action = Sema::PSK_Push_Set;
+ FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures.getAsOpaqueInt());
+ break;
+ case PFC_Pop:
+ if (FpPragmaStack.Stack.empty()) {
+ Diag(Loc, diag::warn_pragma_pop_failed) << "float_control"
+ << "stack empty";
+ return;
+ }
+ FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures.getAsOpaqueInt());
+ NewValue = FpPragmaStack.CurrentValue;
+ CurFPFeatures.getFromOpaqueInt(NewValue);
+ break;
+ }
+}
+
void Sema::ActOnPragmaMSPointersToMembers(
LangOptions::PragmaMSPointersToMembersKind RepresentationMethod,
SourceLocation PragmaLoc) {
@@ -948,9 +1007,16 @@
CurFPFeatures.setExceptionMode(FPE);
}
-void Sema::ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC) {
+void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc,
+ LangOptions::FEnvAccessModeKind FPC) {
switch (FPC) {
case LangOptions::FEA_On:
+ // Verify Microsoft restriction:
+ // You can't enable fenv_access unless precise semantics are enabled.
+ // Precise semantics can be enabled either by the float_control
+ // pragma, or by using the /fp:precise or /fp:strict compiler options
+ if (!isPreciseFPEnabled())
+ Diag(Loc, diag::err_pragma_fenv_requires_precise);
CurFPFeatures.setAllowFEnvAccess();
break;
case LangOptions::FEA_Off:
@@ -959,7 +1025,6 @@
}
}
-
void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
SourceLocation Loc) {
// Visibility calculations will consider the namespace's visibility.