[llvm-commits] [PATCH] Compatibility with GCC 4.6 #pragma GCC diagnostics
Chris Lattner
clattner at apple.com
Tue Aug 17 08:43:54 PDT 2010
Hi Louis!
Thanks for the patch, please send it to the cfe-commits mailing list, since it is clang related. Thanks!
-Chris
On Aug 16, 2010, at 6:12 PM, Louis Gerbarg wrote:
> GCC 4.6 has apparently added support for #pragma push/pop (see this
> thread for more details
> <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg01163.html>), using the
> exact same identifier and semantics as the existing implementation in
> clang. This patch removes the special clang mode in the diagnostic
> handler, which lets the GCC pragmas fall through to the existing code.
> Overall it is a simplification of the existing code. This patch also
> includes modified test cases to handle altered semantics of the GCC
> mode behaviour.
>
> Passed tests with TOT under Darwin 10.6.3 x86-64. I think this should
> be good, but let me know if any fixes are needed.
>
> Louis
>
> ---
> include/clang/Basic/DiagnosticLexKinds.td | 10 ++----
> lib/Lex/Pragma.cpp | 45 +++++++++--------------------
> test/Preprocessor/pragma_diagnostic.c | 3 +-
> test/Preprocessor/pushable-diagnostics.c | 2 +-
> 4 files changed, 19 insertions(+), 41 deletions(-)
>
> diff --git a/include/clang/Basic/DiagnosticLexKinds.td
> b/include/clang/Basic/DiagnosticLexKinds.td
> index 9b06fa8..76c211e 100644
> --- a/include/clang/Basic/DiagnosticLexKinds.td
> +++ b/include/clang/Basic/DiagnosticLexKinds.td
> @@ -244,15 +244,11 @@ def ext_stdc_pragma_syntax_eom :
> def warn_stdc_fenv_access_not_supported :
> Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">,
> InGroup<UnknownPragmas>;
> -def warn_pragma_diagnostic_gcc_invalid :
> - ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', or"
> - " 'fatal'">,
> - InGroup<UnknownPragmas>;
> -def warn_pragma_diagnostic_clang_invalid :
> - ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal'"
> +def warn_pragma_diagnostic_invalid :
> + ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal',"
> " 'push', or 'pop'">,
> InGroup<UnknownPragmas>;
> -def warn_pragma_diagnostic_clang_cannot_ppp :
> +def warn_pragma_diagnostic_cannot_pop :
> ExtWarn<"pragma diagnostic pop could not pop, no matching push">,
> InGroup<UnknownPragmas>;
> def warn_pragma_diagnostic_invalid_option :
> diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
> index 783900d..a74ff33 100644
> --- a/lib/Lex/Pragma.cpp
> +++ b/lib/Lex/Pragma.cpp
> @@ -588,7 +588,7 @@ struct PragmaDebugHandler : public PragmaHandler {
> Token Tok;
> PP.LexUnexpandedToken(Tok);
> if (Tok.isNot(tok::identifier)) {
> - PP.Diag(Tok, diag::warn_pragma_diagnostic_clang_invalid);
> + PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
> return;
> }
> IdentifierInfo *II = Tok.getIdentifierInfo();
> @@ -610,23 +610,14 @@ struct PragmaDebugHandler : public PragmaHandler {
> };
>
> /// PragmaDiagnosticHandler - e.g. '#pragma GCC diagnostic ignored "-Wformat"'
> -/// Since clang's diagnostic supports extended functionality beyond GCC's
> -/// the constructor takes a clangMode flag to tell it whether or not to allow
> -/// clang's extended functionality, or whether to reject it.
> struct PragmaDiagnosticHandler : public PragmaHandler {
> -private:
> - const bool ClangMode;
> public:
> - explicit PragmaDiagnosticHandler(const bool clangMode)
> - : PragmaHandler("diagnostic"), ClangMode(clangMode) {}
> -
> + explicit PragmaDiagnosticHandler() : PragmaHandler("diagnostic") {}
> virtual void HandlePragma(Preprocessor &PP, Token &DiagToken) {
> Token Tok;
> PP.LexUnexpandedToken(Tok);
> if (Tok.isNot(tok::identifier)) {
> - unsigned Diag = ClangMode ? diag::warn_pragma_diagnostic_clang_invalid
> - : diag::warn_pragma_diagnostic_gcc_invalid;
> - PP.Diag(Tok, Diag);
> + PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
> return;
> }
> IdentifierInfo *II = Tok.getIdentifierInfo();
> @@ -640,22 +631,16 @@ public:
> Map = diag::MAP_IGNORE;
> else if (II->isStr("fatal"))
> Map = diag::MAP_FATAL;
> - else if (ClangMode) {
> - if (II->isStr("pop")) {
> - if (!PP.getDiagnostics().popMappings())
> - PP.Diag(Tok, diag::warn_pragma_diagnostic_clang_cannot_ppp);
> - return;
> - }
> -
> - if (II->isStr("push")) {
> - PP.getDiagnostics().pushMappings();
> - return;
> - }
> -
> - PP.Diag(Tok, diag::warn_pragma_diagnostic_clang_invalid);
> + else if (II->isStr("pop")) {
> + if (!PP.getDiagnostics().popMappings())
> + PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
> +
> + return;
> + } else if (II->isStr("push")) {
> + PP.getDiagnostics().pushMappings();
> return;
> } else {
> - PP.Diag(Tok, diag::warn_pragma_diagnostic_gcc_invalid);
> + PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
> return;
> }
>
> @@ -687,9 +672,7 @@ public:
> if (Literal.hadError)
> return;
> if (Literal.Pascal) {
> - unsigned Diag = ClangMode ? diag::warn_pragma_diagnostic_clang_invalid
> - : diag::warn_pragma_diagnostic_gcc_invalid;
> - PP.Diag(Tok, Diag);
> + PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
> return;
> }
>
> @@ -812,13 +795,13 @@ void Preprocessor::RegisterBuiltinPragmas() {
> AddPragmaHandler("GCC", new PragmaPoisonHandler());
> AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
> AddPragmaHandler("GCC", new PragmaDependencyHandler());
> - AddPragmaHandler("GCC", new PragmaDiagnosticHandler(false));
> + AddPragmaHandler("GCC", new PragmaDiagnosticHandler());
> // #pragma clang ...
> AddPragmaHandler("clang", new PragmaPoisonHandler());
> AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
> AddPragmaHandler("clang", new PragmaDebugHandler());
> AddPragmaHandler("clang", new PragmaDependencyHandler());
> - AddPragmaHandler("clang", new PragmaDiagnosticHandler(true));
> + AddPragmaHandler("clang", new PragmaDiagnosticHandler());
>
> AddPragmaHandler("STDC", new PragmaSTDC_FP_CONTRACTHandler());
> AddPragmaHandler("STDC", new PragmaSTDC_FENV_ACCESSHandler());
> diff --git a/test/Preprocessor/pragma_diagnostic.c
> b/test/Preprocessor/pragma_diagnostic.c
> index d157406..818f02f 100644
> --- a/test/Preprocessor/pragma_diagnostic.c
> +++ b/test/Preprocessor/pragma_diagnostic.c
> @@ -20,9 +20,8 @@
> #endif
>
>
> -
> #define foo error
> -#pragma GCC diagnostic foo "-Wundef" // expected-warning {{pragma
> diagnostic expected 'error', 'warning', 'ignored', or 'fatal'}}
> +#pragma GCC diagnostic foo "-Wundef" // expected-warning {{pragma
> diagnostic expected 'error', 'warning', 'ignored', 'fatal', 'push', or
> 'pop'}}
>
> #pragma GCC diagnostic error 42 // expected-warning {{unexpected
> token in pragma diagnostic}}
>
> diff --git a/test/Preprocessor/pushable-diagnostics.c
> b/test/Preprocessor/pushable-diagnostics.c
> index 6c861a1..567a866 100644
> --- a/test/Preprocessor/pushable-diagnostics.c
> +++ b/test/Preprocessor/pushable-diagnostics.c
> @@ -2,7 +2,7 @@
>
> #pragma clang diagnostic pop // expected-warning{{pragma diagnostic
> pop could not pop, no matching push}}
>
> -#pragma clang diagnostic puhs // expected-warning{{pragma diagnostic
> expected 'error', 'warning', 'ignored', 'fatal' 'push', or 'pop'}}
> +#pragma clang diagnostic puhs // expected-warning {{pragma diagnostic
> expected 'error', 'warning', 'ignored', 'fatal', 'push', or 'pop'}}
>
> char a = 'df'; // expected-warning{{multi-character character constant}}
>
> --
> 1.7.0
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list