r196212 - Emit an extension warning when changing system header tokens

Alp Toker alp at nuanti.com
Fri Dec 13 06:27:51 PST 2013


Hi Bill,

Would it be possible to merge this diagnostic into clang 3.4?

I'm aware of the freeze, but getting this warning into a stable release 
will give C++ standard library authors an additional 6 months advanced 
notice about an old compatibility hack we plan to remove a couple of 
years down the line.

Alp.


On 03/12/2013 06:13, Alp Toker wrote:
> Author: alp
> Date: Tue Dec  3 00:13:01 2013
> New Revision: 196212
>
> URL: http://llvm.org/viewvc/llvm-project?rev=196212&view=rev
> Log:
> Emit an extension warning when changing system header tokens
>
> clang converts keywords to identifiers for compatibility with various system
> headers such as GNU libc.
>
> Implement a -Wkeyword-compat extension warning to diagnose those cases. The
> warning is on by default but will generally be ignored in system headers. It
> can however be enabled globally to aid standards conformance testing.
>
> This also changes the __uptr keyword avoidance from r195710 to no longer
> special-case system headers, bringing it in line with other similar workarounds
> in clang.
>
> Implementation returns bool for symmetry with token annotation functions.
>
> Some examples:
>
> warning: keyword '__is_pod' will be treated as an identifier for the remainder of the translation unit [-Wkeyword-compat]
> struct __is_pod
>
> warning: keyword '__uptr' will be treated as an identifier here [-Wkeyword-compat]
> union w *__uptr;
>
> Modified:
>      cfe/trunk/include/clang/Basic/DiagnosticGroups.td
>      cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>      cfe/trunk/include/clang/Parse/Parser.h
>      cfe/trunk/lib/Parse/ParseDecl.cpp
>      cfe/trunk/lib/Parse/ParseDeclCXX.cpp
>      cfe/trunk/lib/Parse/Parser.cpp
>      cfe/trunk/test/PCH/cxx-traits.cpp
>      cfe/trunk/test/PCH/cxx-traits.h
>      cfe/trunk/test/Sema/Inputs/ms-keyword-system-header.h
>      cfe/trunk/test/Sema/ms-keyword-system-header.c
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=196212&r1=196211&r2=196212&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Dec  3 00:13:01 2013
> @@ -50,6 +50,7 @@ def BuiltinRequiresHeader : DiagGroup<"b
>   def C99Compat : DiagGroup<"c99-compat">;
>   def CXXCompat: DiagGroup<"c++-compat">;
>   def ExternCCompat : DiagGroup<"extern-c-compat">;
> +def KeywordCompat : DiagGroup<"keyword-compat">;
>   def GNUCaseRange : DiagGroup<"gnu-case-range">;
>   def CastAlign : DiagGroup<"cast-align">;
>   def : DiagGroup<"cast-qual">;
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=196212&r1=196211&r2=196212&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Dec  3 00:13:01 2013
> @@ -58,6 +58,9 @@ def ext_plain_complex : ExtWarn<
>   def ext_integer_complex : Extension<
>     "complex integer types are a GNU extension">, InGroup<GNUComplexInteger>;
>   def ext_thread_before : Extension<"'__thread' before '%0'">;
> +def ext_keyword_as_ident : ExtWarn<
> +  "keyword '%0' will be treated as an identifier %select{here|for the remainder of the translation unit}1">,
> +  InGroup<KeywordCompat>;
>   
>   def error_empty_enum : Error<"use of empty enum">;
>   def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">;
>
> Modified: cfe/trunk/include/clang/Parse/Parser.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=196212&r1=196211&r2=196212&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Parse/Parser.h (original)
> +++ cfe/trunk/include/clang/Parse/Parser.h Tue Dec  3 00:13:01 2013
> @@ -563,6 +563,13 @@ private:
>                                   const char *&PrevSpec, unsigned &DiagID,
>                                   bool &isInvalid);
>   
> +  /// TryKeywordIdentFallback - For compatibility with system headers using
> +  /// keywords as identifiers, attempt to convert the current token to an
> +  /// identifier and optionally disable the keyword for the remainder of the
> +  /// translation unit. This returns false if the token was not replaced,
> +  /// otherwise emits a diagnostic and returns true.
> +  bool TryKeywordIdentFallback(bool DisableKeyword);
> +
>     /// \brief Get the TemplateIdAnnotation from the token.
>     TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
>   
>
> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=196212&r1=196211&r2=196212&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Dec  3 00:13:01 2013
> @@ -2739,10 +2739,8 @@ void Parser::ParseDeclarationSpecifiers(
>         // then treat __is_signed as an identifier rather than as a keyword.
>         if (DS.getTypeSpecType() == TST_bool &&
>             DS.getTypeQualifiers() == DeclSpec::TQ_const &&
> -          DS.getStorageClassSpec() == DeclSpec::SCS_static) {
> -        Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
> -        Tok.setKind(tok::identifier);
> -      }
> +          DS.getStorageClassSpec() == DeclSpec::SCS_static)
> +        TryKeywordIdentFallback(true);
>   
>         // We're done with the declaration-specifiers.
>         goto DoneWithDeclSpec;
> @@ -4488,10 +4486,9 @@ void Parser::ParseTypeQualifierListOpt(D
>         // GNU libc headers in C mode use '__uptr' as an identifer which conflicts
>         // with the MS modifier keyword.
>         if (VendorAttributesAllowed && !getLangOpts().CPlusPlus &&
> -          IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi) &&
> -          PP.getSourceManager().isInSystemHeader(Loc)) {
> -        Tok.setKind(tok::identifier);
> -        continue;
> +          IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi)) {
> +        if (TryKeywordIdentFallback(false))
> +          continue;
>         }
>       case tok::kw___sptr:
>       case tok::kw___w64:
>
> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=196212&r1=196211&r2=196212&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Dec  3 00:13:01 2013
> @@ -1198,15 +1198,13 @@ void Parser::ParseClassSpecifier(tok::To
>          Tok.is(tok::kw___is_scalar) ||
>          Tok.is(tok::kw___is_signed) ||
>          Tok.is(tok::kw___is_unsigned) ||
> -       Tok.is(tok::kw___is_void))) {
> +       Tok.is(tok::kw___is_void)))
>       // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
>       // name of struct templates, but some are keywords in GCC >= 4.3
>       // and Clang. Therefore, when we see the token sequence "struct
>       // X", make X into a normal identifier rather than a keyword, to
>       // allow libstdc++ 4.2 and libc++ to work properly.
> -    Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
> -    Tok.setKind(tok::identifier);
> -  }
> +    TryKeywordIdentFallback(true);
>   
>     // Parse the (optional) nested-name-specifier.
>     CXXScopeSpec &SS = DS.getTypeSpecScope();
>
> Modified: cfe/trunk/lib/Parse/Parser.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=196212&r1=196211&r2=196212&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/Parser.cpp (original)
> +++ cfe/trunk/lib/Parse/Parser.cpp Tue Dec  3 00:13:01 2013
> @@ -1517,6 +1517,17 @@ Parser::TryAnnotateName(bool IsAddressOf
>     return ANK_Unresolved;
>   }
>   
> +bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
> +  assert(Tok.isNot(tok::identifier));
> +  Diag(Tok, diag::ext_keyword_as_ident)
> +    << PP.getSpelling(Tok)
> +    << DisableKeyword;
> +  if (DisableKeyword)
> +    Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
> +  Tok.setKind(tok::identifier);
> +  return true;
> +}
> +
>   /// TryAnnotateTypeOrScopeToken - If the current token position is on a
>   /// typename (possibly qualified in C++) or a C++ scope specifier not followed
>   /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
>
> Modified: cfe/trunk/test/PCH/cxx-traits.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-traits.cpp?rev=196212&r1=196211&r2=196212&view=diff
> ==============================================================================
> --- cfe/trunk/test/PCH/cxx-traits.cpp (original)
> +++ cfe/trunk/test/PCH/cxx-traits.cpp Tue Dec  3 00:13:01 2013
> @@ -2,9 +2,11 @@
>   // RUN: %clang_cc1 -include %S/cxx-traits.h -std=c++11 -fsyntax-only -verify %s
>   
>   // RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -o %t %S/cxx-traits.h
> -// RUN: %clang_cc1 -std=c++11 -include-pch %t -fsyntax-only -verify %s
> +// RUN: %clang_cc1 -std=c++11 -include-pch %t -DPCH -fsyntax-only -verify %s
>   
> +#ifdef PCH
>   // expected-no-diagnostics
> +#endif
>   
>   bool _Is_pod_comparator = __is_pod<int>::__value;
>   bool _Is_empty_check = __is_empty<int>::__value;
>
> Modified: cfe/trunk/test/PCH/cxx-traits.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-traits.h?rev=196212&r1=196211&r2=196212&view=diff
> ==============================================================================
> --- cfe/trunk/test/PCH/cxx-traits.h (original)
> +++ cfe/trunk/test/PCH/cxx-traits.h Tue Dec  3 00:13:01 2013
> @@ -1,12 +1,12 @@
>   // Header for PCH test cxx-traits.cpp
>   
>   template<typename _Tp>
> -struct __is_pod {
> +struct __is_pod { // expected-warning {{keyword '__is_pod' will be treated as an identifier for the remainder of the translation unit}}
>     enum { __value };
>   };
>   
>   template<typename _Tp>
> -struct __is_empty {
> +struct __is_empty { // expected-warning {{keyword '__is_empty' will be treated as an identifier for the remainder of the translation unit}}
>     enum { __value };
>   };
>   
>
> Modified: cfe/trunk/test/Sema/Inputs/ms-keyword-system-header.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/Inputs/ms-keyword-system-header.h?rev=196212&r1=196211&r2=196212&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/Inputs/ms-keyword-system-header.h (original)
> +++ cfe/trunk/test/Sema/Inputs/ms-keyword-system-header.h Tue Dec  3 00:13:01 2013
> @@ -2,5 +2,8 @@
>   
>   typedef union {
>     union w *__uptr;
> +#if defined(MS) && defined(NOT_SYSTEM)
> +  // expected-warning at -2 {{keyword '__uptr' will be treated as an identifier here}}
> +#endif
>     int *__iptr;
>   } WS __attribute__((__transparent_union__));
>
> Modified: cfe/trunk/test/Sema/ms-keyword-system-header.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ms-keyword-system-header.c?rev=196212&r1=196211&r2=196212&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/ms-keyword-system-header.c (original)
> +++ cfe/trunk/test/Sema/ms-keyword-system-header.c Tue Dec  3 00:13:01 2013
> @@ -1,4 +1,6 @@
>   // RUN: %clang_cc1 -fms-extensions -D MS -isystem %S/Inputs %s -fsyntax-only -verify
> +// RUN: %clang_cc1 -fms-extensions -D MS -Wno-keyword-compat -I %S/Inputs %s -fsyntax-only -verify
> +// RUN: %clang_cc1 -fms-extensions -D MS -D NOT_SYSTEM -I %S/Inputs %s -fsyntax-only -verify
>   // RUN: %clang_cc1 -isystem %S/Inputs %s -fsyntax-only -verify
>   
>   // PR17824: GNU libc uses MS keyword __uptr as an identifier in C mode
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

-- 
http://www.nuanti.com
the browser experts




More information about the cfe-commits mailing list