[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