diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1147,6 +1147,9 @@ def warn_stdc_unknown_rounding_mode : Warning< "invalid or unsupported rounding mode in '#pragma STDC FENV_ROUND' - ignored">, InGroup; +def warn_pragma_fp_ignored : Warning< + "'#pragma %0' is not supported on this target - ignored">, + InGroup; // - #pragma comment def err_pragma_comment_malformed : Error< "pragma comment requires parenthesized identifier and optional string">; diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -103,6 +103,12 @@ void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) override { + Token PragmaName = Tok; + if (!PP.getTargetInfo().hasStrictFP() && !PP.getLangOpts().ExpStrictFP) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored) + << PragmaName.getIdentifierInfo()->getName(); + return; + } tok::OnOffSwitch OOS; if (PP.LexOnOffSwitch(OOS)) return; @@ -2553,6 +2559,12 @@ Token &Tok) { Sema::PragmaMsStackAction Action = Sema::PSK_Set; SourceLocation FloatControlLoc = Tok.getLocation(); + Token PragmaName = Tok; + if (!PP.getTargetInfo().hasStrictFP() && !PP.getLangOpts().ExpStrictFP) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored) + << PragmaName.getIdentifierInfo()->getName(); + return; + } PP.Lex(Tok); if (Tok.isNot(tok::l_paren)) { PP.Diag(FloatControlLoc, diag::err_expected) << tok::l_paren; @@ -2952,6 +2964,11 @@ Token &Tok) { Token PragmaName = Tok; SmallVector TokenList; + if (!PP.getTargetInfo().hasStrictFP() && !PP.getLangOpts().ExpStrictFP) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored) + << PragmaName.getIdentifierInfo()->getName(); + return; + } PP.Lex(Tok); if (Tok.isNot(tok::identifier)) { diff --git a/clang/test/Parser/pragma-fp-warn.c b/clang/test/Parser/pragma-fp-warn.c new file mode 100644 --- /dev/null +++ b/clang/test/Parser/pragma-fp-warn.c @@ -0,0 +1,19 @@ + +// RUN: %clang_cc1 -triple wasm32 -fsyntax-only -Wno-unknown-pragmas -Wignored-pragmas -verify %s +// RUN: %clang_cc1 -triple thumbv7 -fsyntax-only -Wno-unknown-pragmas -Wignored-pragmas -verify %s +// RUN: %clang_cc1 -triple aarch64 -fsyntax-only -Wno-unknown-pragmas -Wignored-pragmas -verify %s +// RUN: %clang_cc1 -DEXPOK -triple x86_64 -fsyntax-only -Wno-unknown-pragmas -Wignored-pragmas -verify %s +// RUN: %clang_cc1 -DEXPOK -triple systemz -fsyntax-only -Wno-unknown-pragmas -Wignored-pragmas -verify %s +// RUN: %clang_cc1 -DEXPOK -triple powerpc -fsyntax-only -Wno-unknown-pragmas -Wignored-pragmas -verify %s +#ifdef EXPOK +// expected-no-diagnostics +#else +// expected-warning@+4 {{'#pragma float_control' is not supported on this target - ignored}} +// expected-warning@+5 {{'#pragma FENV_ACCESS' is not supported on this target - ignored}} +// expected-warning@+6 {{'#pragma FENV_ROUND' is not supported on this target - ignored}} +#endif +#pragma float_control(precise, on) + +#pragma STDC FENV_ACCESS OFF + +#pragma STDC FENV_ROUND FE_DOWNWARD