Merging r195710:
authorBill Wendling <isanbard@gmail.com>
Tue, 26 Nov 2013 04:10:07 +0000 (04:10 +0000)
committerBill Wendling <isanbard@gmail.com>
Tue, 26 Nov 2013 04:10:07 +0000 (04:10 +0000)
------------------------------------------------------------------------
r195710 | alp | 2013-11-25 17:30:10 -0800 (Mon, 25 Nov 2013) | 10 lines

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/branches/release_34@195721 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Parser.h
lib/Parse/ParseDecl.cpp
test/Sema/Inputs/ms-keyword-system-header.h [new file with mode: 0644]
test/Sema/ms-keyword-system-header.c [new file with mode: 0644]

index 0bf30453ce9119e0b2a4edbac954c3cb62a624ef..637c24974cbfbb6e2880ccbde63303f4ea3e1d85 100644 (file)
@@ -2064,7 +2064,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,
index 602c853d70c9582ab2ca1d4ec18e086f55878aa4..a1c4ccdb6d5092c7ff0cf0f3d1cc06a78c84971a 100644 (file)
@@ -4414,7 +4414,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);
@@ -4468,8 +4469,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:
@@ -4625,7 +4634,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 (file)
index 0000000..13cfe3a
--- /dev/null
@@ -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 (file)
index 0000000..bf7a9f4
--- /dev/null
@@ -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 <ms-keyword-system-header.h>
+
+void fn() {
+  WS ws;
+  ws.__uptr = 0;
+#ifdef MS
+  // expected-error@-2 {{expected identifier}}
+#else
+  // expected-no-diagnostics
+#endif
+}