[PATCH] [PATCH] PR9804 - __is_signed conflicts with libstdc++

Charlie Turner charlie.turner at arm.com
Tue Apr 21 09:47:13 PDT 2015


Extends the hackish recovery in r130399 to deal with the case of `bool` being hidden behind a typedef.

Fixes PR9804

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D9157

Files:
  lib/Parse/ParseDecl.cpp
  test/SemaCXX/libstdcxx_is_pod_hack.cpp
  test/SemaCXX/libstdcxx_is_signed_hack.cpp

Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -2874,14 +2874,22 @@
       //   static const bool __is_signed;
       //
       // 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)
-        TryKeywordIdentFallback(true);
-
-      // We're done with the declaration-specifiers.
-      goto DoneWithDeclSpec;
-
+      switch (DS.getTypeSpecType()) {
+      case TST_typename:
+        {
+          auto SeenType = Sema::GetTypeFromParser(DS.getRepAsType());
+          if (!SeenType->isBooleanType())
+            goto DoneWithDeclSpec;
+          // fall through
+        }
+      case TST_bool:
+        if (DS.getTypeQualifiers() == DeclSpec::TQ_const &&
+            DS.getStorageClassSpec() == DeclSpec::SCS_static)
+          TryKeywordIdentFallback(true);
+        // fall through
+      default:
+        goto DoneWithDeclSpec;
+      }
       // typedef-name
     case tok::kw___super:
     case tok::kw_decltype:
Index: test/SemaCXX/libstdcxx_is_pod_hack.cpp
===================================================================
--- test/SemaCXX/libstdcxx_is_pod_hack.cpp
+++ test/SemaCXX/libstdcxx_is_pod_hack.cpp
@@ -27,6 +27,9 @@
   static const bool __is_signed = true; // expected-warning {{keyword '__is_signed' will be made available as an identifier}}
 };
 
+// The case where `bool` above is hidden behind a typedef is tested
+// in libstdcxx_is_signed_hack.cpp
+
 bool check_signed = test_is_signed::__is_signed;
 
 template<bool B> struct must_be_true {};
Index: test/SemaCXX/libstdcxx_is_signed_hack.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/libstdcxx_is_signed_hack.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// libstdc++ 4.4 uses __is_signed as an identifier, while Clang treats it
+// as a keyword for the __is_signed type trait. Cope with this conflict
+// via some hackish recovery: if we see a declaration of the form
+//
+// static const T __is_signed
+//
+// where T is bool or a typedef that reduces to bool, then we stop treating
+// __is_signed as a keyword and instead treat it as an identifier.
+
+typedef bool BOOL;
+struct test_is_signed_typedef {
+  static const BOOL __is_signed = true; // expected-warning {{keyword '__is_signed' will be made available as an identifier}}
+};

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D9157.24140.patch
Type: text/x-patch
Size: 2593 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150421/e21fbf74/attachment.bin>


More information about the cfe-commits mailing list