sberg created this revision.
sberg added reviewers: doug.gregor, aaron.ballman.
Herald added a project: All.
sberg requested review of this revision.
Herald added a project: clang.

...similar to 068730992cf08d7d7e82e7bb147d85f429fc3ddd "libstdc++ 4.4 uses 
__is_signed as an identifier [...]"

Starting with 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=5329e1a8e1480d536ff96283a6556e51112ba470
 "libstdc++: Make chrono::hh_mm_ss more compact", libstdc++ 13 trunk used 
`__is_signed` as

  static constexpr bool __is_unsigned
    = __and_v<is_integral<typename _Duration::rep>,
              is_unsigned<typename _Duration::rep>>;

in `libstdc++-v3/include/std/chrono`.  Even though that got reverted with 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=cb363fd9f19eb791e1ee1eb0d5c61f5fdf21af32
 "libstdc++: Change names that clash with Win32 or Clang", it might make sense 
to treat `__is_unsigned` the same as `__is_signed` here (and to also make the 
workaround hit for `constexpr` in addition to `const`).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D139847

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


Index: clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp
===================================================================
--- clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp
+++ clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp
@@ -29,6 +29,13 @@
 
 bool check_signed = test_is_signed::__is_signed;
 
+// Another, similar egregious hack for __is_unsigned, which is a type
+// trait in Embarcadero's compiler but is used as an identifier in
+// libstdc++.
+struct test_is_unsigned {
+  static constexpr bool __is_unsigned = true; // expected-warning {{keyword 
'__is_unsigned' will be made available as an identifier}}
+};
+
 template<bool B> struct must_be_true {};
 template<> struct must_be_true<false>;
 
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -3519,6 +3519,7 @@
     }
 
     case tok::kw___is_signed:
+    case tok::kw___is_unsigned:
       // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang
       // typically treats it as a trait. If we see __is_signed as it appears
       // in libstdc++, e.g.,
@@ -3526,8 +3527,15 @@
       //   static const bool __is_signed;
       //
       // then treat __is_signed as an identifier rather than as a keyword.
+      //
+      // Similarly, libstdc++ 13 trunk at one point used __is_unsigned as an
+      // identifier as
+      //
+      //   static constexpr bool __is_unsigned;
+      //
       if (DS.getTypeSpecType() == TST_bool &&
-          DS.getTypeQualifiers() == DeclSpec::TQ_const &&
+          (DS.getTypeQualifiers() == DeclSpec::TQ_const ||
+           DS.getConstexprSpecifier() == ConstexprSpecKind::Constexpr) &&
           DS.getStorageClassSpec() == DeclSpec::SCS_static)
         TryKeywordIdentFallback(true);
 


Index: clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp
===================================================================
--- clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp
+++ clang/test/SemaCXX/libstdcxx_is_pod_hack.cpp
@@ -29,6 +29,13 @@
 
 bool check_signed = test_is_signed::__is_signed;
 
+// Another, similar egregious hack for __is_unsigned, which is a type
+// trait in Embarcadero's compiler but is used as an identifier in
+// libstdc++.
+struct test_is_unsigned {
+  static constexpr bool __is_unsigned = true; // expected-warning {{keyword '__is_unsigned' will be made available as an identifier}}
+};
+
 template<bool B> struct must_be_true {};
 template<> struct must_be_true<false>;
 
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -3519,6 +3519,7 @@
     }
 
     case tok::kw___is_signed:
+    case tok::kw___is_unsigned:
       // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang
       // typically treats it as a trait. If we see __is_signed as it appears
       // in libstdc++, e.g.,
@@ -3526,8 +3527,15 @@
       //   static const bool __is_signed;
       //
       // then treat __is_signed as an identifier rather than as a keyword.
+      //
+      // Similarly, libstdc++ 13 trunk at one point used __is_unsigned as an
+      // identifier as
+      //
+      //   static constexpr bool __is_unsigned;
+      //
       if (DS.getTypeSpecType() == TST_bool &&
-          DS.getTypeQualifiers() == DeclSpec::TQ_const &&
+          (DS.getTypeQualifiers() == DeclSpec::TQ_const ||
+           DS.getConstexprSpecifier() == ConstexprSpecKind::Constexpr) &&
           DS.getStorageClassSpec() == DeclSpec::SCS_static)
         TryKeywordIdentFallback(true);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to