From: Hans Wennborg Date: Tue, 20 Mar 2018 08:53:11 +0000 (+0000) Subject: [ms] Parse #pragma optimize and ignore it behind its own flag X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=73fed20ccfe3c439d8568756463c79a032e7c9e0;p=clang [ms] Parse #pragma optimize and ignore it behind its own flag This allows users to turn off warnings about this pragma specifically, while still receiving warnings about other ignored pragmas. Differential Revision: https://reviews.llvm.org/D44630 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@327959 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index c6f98cbade..0a3e56314f 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -515,8 +515,13 @@ def UninitializedStaticSelfInit : DiagGroup<"static-self-init">; def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes, UninitializedStaticSelfInit]>; def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">; +// #pragma optimize is often used to avoid to work around MSVC codegen bugs or +// to disable inlining. It's not completely clear what alternative to suggest +// (#pragma clang optimize, noinline) so suggest nothing for now. +def IgnoredPragmaOptimize : DiagGroup<"ignored-pragma-optimize">; def UnknownPragmas : DiagGroup<"unknown-pragmas">; -def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>; +def IgnoredPragmas : DiagGroup<"ignored-pragmas", + [IgnoredPragmaIntrinsic, IgnoredPragmaOptimize]>; def PragmaClangAttribute : DiagGroup<"pragma-clang-attribute">; def PragmaPackSuspiciousInclude : DiagGroup<"pragma-pack-suspicious-include">; def PragmaPack : DiagGroup<"pragma-pack", [PragmaPackSuspiciousInclude]>; diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 40c84d4afd..e91a787206 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -895,6 +895,12 @@ def warn_pragma_expected_rparen : Warning< "missing ')' after '#pragma %0' - ignoring">, InGroup; def warn_pragma_expected_identifier : Warning< "expected identifier in '#pragma %0' - ignored">, InGroup; +def warn_pragma_expected_string : Warning< + "expected string literal in '#pragma %0' - ignoring">, InGroup; +def warn_pragma_missing_argument : Warning< + "missing argument to '#pragma %0'%select{|; expected %2}1">, InGroup; +def warn_pragma_invalid_argument : Warning< + "unexpected argument '%0' to '#pragma %1'%select{|; expected %3}2">, InGroup; // '#pragma clang section' related errors def err_pragma_expected_clang_section_name : Error< @@ -923,6 +929,8 @@ def warn_pragma_ms_struct : Warning< def warn_pragma_extra_tokens_at_eol : Warning< "extra tokens at end of '#pragma %0' - ignored">, InGroup; +def warn_pragma_expected_comma : Warning< + "expected ',' in '#pragma %0'">, InGroup; def warn_pragma_expected_punc : Warning< "expected ')' or ',' in '#pragma %0'">, InGroup; def warn_pragma_expected_non_wide_string : Warning< @@ -960,6 +968,10 @@ def warn_pragma_pack_malformed : Warning< def warn_pragma_intrinsic_builtin : Warning< "%0 is not a recognized builtin%select{|; consider including to access non-builtin intrinsics}1">, InGroup; +// - #pragma optimize +def warn_pragma_optimize : Warning< + "'#pragma optimize' is not supported">, + InGroup; // - #pragma unused def warn_pragma_unused_expected_var : Warning< "expected '#pragma unused' argument to be a variable name">, diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 3bf3855419..0df9f3f742 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -179,6 +179,7 @@ class Parser : public CodeCompletionHandler { std::unique_ptr MSSection; std::unique_ptr MSRuntimeChecks; std::unique_ptr MSIntrinsic; + std::unique_ptr MSOptimize; std::unique_ptr CUDAForceHostDeviceHandler; std::unique_ptr OptimizeHandler; std::unique_ptr LoopHintHandler; diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index e815ea1355..9e55634cc7 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -220,6 +220,12 @@ struct PragmaMSIntrinsicHandler : public PragmaHandler { Token &FirstToken) override; }; +struct PragmaMSOptimizeHandler : public PragmaHandler { + PragmaMSOptimizeHandler() : PragmaHandler("optimize") {} + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken) override; +}; + struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler { PragmaForceCUDAHostDeviceHandler(Sema &Actions) : PragmaHandler("force_cuda_host_device"), Actions(Actions) {} @@ -324,6 +330,8 @@ void Parser::initializePragmaHandlers() { PP.AddPragmaHandler(MSRuntimeChecks.get()); MSIntrinsic.reset(new PragmaMSIntrinsicHandler()); PP.AddPragmaHandler(MSIntrinsic.get()); + MSOptimize.reset(new PragmaMSOptimizeHandler()); + PP.AddPragmaHandler(MSOptimize.get()); } if (getLangOpts().CUDA) { @@ -410,6 +418,8 @@ void Parser::resetPragmaHandlers() { MSRuntimeChecks.reset(); PP.RemovePragmaHandler(MSIntrinsic.get()); MSIntrinsic.reset(); + PP.RemovePragmaHandler(MSOptimize.get()); + MSOptimize.reset(); } if (getLangOpts().CUDA) { @@ -2949,6 +2959,61 @@ void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP, PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "intrinsic"; } + +// #pragma optimize("gsty", on|off) +void PragmaMSOptimizeHandler::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &Tok) { + SourceLocation StartLoc = Tok.getLocation(); + PP.Lex(Tok); + + if (Tok.isNot(tok::l_paren)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "optimize"; + return; + } + PP.Lex(Tok); + + if (Tok.isNot(tok::string_literal)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_string) << "optimize"; + return; + } + // We could syntax check the string but it's probably not worth the effort. + PP.Lex(Tok); + + if (Tok.isNot(tok::comma)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_comma) << "optimize"; + return; + } + PP.Lex(Tok); + + if (Tok.is(tok::eod) || Tok.is(tok::r_paren)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_missing_argument) + << "optimize" << /*Expected=*/true << "'on' or 'off'"; + return; + } + IdentifierInfo *II = Tok.getIdentifierInfo(); + if (!II || (!II->isStr("on") && !II->isStr("off"))) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument) + << PP.getSpelling(Tok) << "optimize" << /*Expected=*/true + << "'on' or 'off'"; + return; + } + PP.Lex(Tok); + + if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "optimize"; + return; + } + PP.Lex(Tok); + + if (Tok.isNot(tok::eod)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) + << "optimize"; + return; + } + PP.Diag(StartLoc, diag::warn_pragma_optimize); +} + void PragmaForceCUDAHostDeviceHandler::HandlePragma( Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) { Token FirstTok = Tok; diff --git a/test/Preprocessor/pragma_microsoft.c b/test/Preprocessor/pragma_microsoft.c index 5d08943273..4105e41af4 100644 --- a/test/Preprocessor/pragma_microsoft.c +++ b/test/Preprocessor/pragma_microsoft.c @@ -190,3 +190,11 @@ void g() {} #pragma intrinsic(asdf) // no-warning #pragma clang diagnostic pop #pragma intrinsic(asdf) // expected-warning {{'asdf' is not a recognized builtin; consider including }} + +#pragma optimize // expected-warning{{missing '(' after '#pragma optimize'}} +#pragma optimize( // expected-warning{{expected string literal in '#pragma optimize'}} +#pragma optimize(a // expected-warning{{expected string literal in '#pragma optimize'}} +#pragma optimize("g" // expected-warning{{expected ',' in '#pragma optimize'}} +#pragma optimize("g", // expected-warning{{missing argument to '#pragma optimize'; expected 'on' or 'off'}} +#pragma optimize("g",xyz // expected-warning{{unexpected argument 'xyz' to '#pragma optimize'; expected 'on' or 'off'}} +#pragma optimize("g",on) // expected-warning{{#pragma optimize' is not supported}}