From d8a96a63a331f5486e88ade9f98195b9ef44c954 Mon Sep 17 00:00:00 2001 From: Alp Toker Date: Tue, 26 Nov 2013 01:30:10 +0000 Subject: [PATCH] Unbreak -fms-extensions with GNU libc headers GNU libc uses '__uptr' as a member name in C mode, conflicting with the eponymous MSVC pointer modifier keyword. Detect and mark the token as an identifier when these specific conditions are met. __uptr will continue to work as a keyword for the remainder of the translation unit. Fixes PR17824. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195710 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Parse/Parser.h | 3 ++- lib/Parse/ParseDecl.cpp | 15 ++++++++++++--- test/Sema/Inputs/ms-keyword-system-header.h | 6 ++++++ test/Sema/ms-keyword-system-header.c | 15 +++++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 test/Sema/Inputs/ms-keyword-system-header.h create mode 100644 test/Sema/ms-keyword-system-header.c diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 884ab56fea..8807e3b47b 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -2072,7 +2072,8 @@ private: void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true, bool CXX11AttributesAllowed = true, - bool AtomicAllowed = true); + bool AtomicAllowed = true, + bool IdentifierRequired = false); void ParseDirectDeclarator(Declarator &D); void ParseParenDeclarator(Declarator &D); void ParseFunctionDeclarator(Declarator &D, diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 7185de6fed..784f69ee68 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -4429,7 +4429,8 @@ bool Parser::isConstructorDeclarator() { void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool VendorAttributesAllowed, bool CXX11AttributesAllowed, - bool AtomicAllowed) { + bool AtomicAllowed, + bool IdentifierRequired) { if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed && isCXX11AttributeSpecifier()) { ParsedAttributesWithRange attrs(AttrFactory); @@ -4483,8 +4484,16 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, ParseOpenCLQualifiers(DS); break; - case tok::kw___sptr: case tok::kw___uptr: + // 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; + } + case tok::kw___sptr: case tok::kw___w64: case tok::kw___ptr64: case tok::kw___ptr32: @@ -4640,7 +4649,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D, DeclSpec DS(AttrFactory); // FIXME: GNU attributes are not allowed here in a new-type-id. - ParseTypeQualifierListOpt(DS); + ParseTypeQualifierListOpt(DS, true, true, true, !D.mayOmitIdentifier()); D.ExtendWithDeclSpec(DS); // Recursively parse the declarator. diff --git a/test/Sema/Inputs/ms-keyword-system-header.h b/test/Sema/Inputs/ms-keyword-system-header.h new file mode 100644 index 0000000000..13cfe3a6ea --- /dev/null +++ b/test/Sema/Inputs/ms-keyword-system-header.h @@ -0,0 +1,6 @@ +/* "System header" for testing GNU libc keyword conflict workarounds */ + +typedef union { + union w *__uptr; + int *__iptr; +} WS __attribute__((__transparent_union__)); diff --git a/test/Sema/ms-keyword-system-header.c b/test/Sema/ms-keyword-system-header.c new file mode 100644 index 0000000000..bf7a9f4c8e --- /dev/null +++ b/test/Sema/ms-keyword-system-header.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fms-extensions -D MS -isystem %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 +#include + +void fn() { + WS ws; + ws.__uptr = 0; +#ifdef MS + // expected-error@-2 {{expected identifier}} +#else + // expected-no-diagnostics +#endif +} -- 2.40.0