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