[clang] d78a7c5 - [ODRHash] Handle `Integral` and `NullPtr` template parameters in `ODRHash`

via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 12 01:25:07 PST 2023


Author: isuckatcs
Date: 2023-01-12T10:24:50+01:00
New Revision: d78a7c5012c7ae6ec9991fb22fcd6d06a42dc1cc

URL: https://github.com/llvm/llvm-project/commit/d78a7c5012c7ae6ec9991fb22fcd6d06a42dc1cc
DIFF: https://github.com/llvm/llvm-project/commit/d78a7c5012c7ae6ec9991fb22fcd6d06a42dc1cc.diff

LOG: [ODRHash] Handle `Integral` and `NullPtr` template parameters in `ODRHash`

Before this patch the parameters mentioned in the title weren't
handled by ODRHash, when a hash was generated for a template
specialization. This patch adds these parameters to the hash,
so that different template specializations will get different
hashes in every case.

Differential Revision: https://reviews.llvm.org/D141224

Added: 
    

Modified: 
    clang/lib/AST/ODRHash.cpp
    clang/test/Modules/odr_hash.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index fee47881a1835..1a24bb24d59f6 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -172,8 +172,14 @@ void ODRHash::AddTemplateArgument(TemplateArgument TA) {
       AddDecl(TA.getAsDecl());
       break;
     case TemplateArgument::NullPtr:
-    case TemplateArgument::Integral:
+      ID.AddPointer(nullptr);
       break;
+    case TemplateArgument::Integral: {
+      // There are integrals (e.g.: _BitInt(128)) that cannot be represented as
+      // any builtin integral type, so we use the hash of APSInt instead.
+      TA.getAsIntegral().Profile(ID);
+      break;
+    }
     case TemplateArgument::Template:
     case TemplateArgument::TemplateExpansion:
       AddTemplateName(TA.getAsTemplateOrTemplatePattern());

diff  --git a/clang/test/Modules/odr_hash.cpp b/clang/test/Modules/odr_hash.cpp
index fb756013bc9bb..fffac5e318f5d 100644
--- a/clang/test/Modules/odr_hash.cpp
+++ b/clang/test/Modules/odr_hash.cpp
@@ -1939,6 +1939,164 @@ S11 s11;
 // expected-note at first.h:* {{but in 'FirstModule' found method 'run' with 2 template arguments}}
 #endif
 
+#if defined(FIRST)
+struct S12 {
+  template <int> void f(){};
+  template <> void f<1>(){};
+};
+#elif defined(SECOND)
+struct S12 {
+  template <int> void f(){};
+  template <> void f<2>(){};
+};
+#else
+S12 s12;
+// expected-error at second.h:* {{'TemplateArgument::S12' has 
diff erent definitions in 
diff erent modules; first 
diff erence is definition in module 'SecondModule' found method 'f' with 2 for 1st template argument}}
+// expected-note at first.h:* {{but in 'FirstModule' found method 'f' with 1 for 1st template argument}}
+#endif
+
+#if defined(FIRST)
+struct S13 {
+  template <int> void f(){};
+  template <> void f<10>(){};
+};
+#elif defined(SECOND)
+struct S13 {
+  template <int> void f(){};
+  template <> void f<10>(){};
+};
+#else
+S13 s13;
+#endif
+
+#if defined(FIRST)
+struct S14 {
+  template <bool, bool> void f(){};
+  template <> void f<true, false>(){};
+};
+#elif defined(SECOND)
+struct S14 {
+  template <bool, bool> void f(){};
+  template <> void f<false, true>(){};
+};
+#else
+S14 s14;
+// expected-error at second.h:* {{'TemplateArgument::S14' has 
diff erent definitions in 
diff erent modules; first 
diff erence is definition in module 'SecondModule' found method 'f' with 0 for 1st template argument}}
+// expected-note at first.h:* {{but in 'FirstModule' found method 'f' with 1 for 1st template argument}}
+#endif
+
+#if defined(FIRST)
+struct S15 {
+  template <bool, bool> void f(){};
+  template <> void f<true, true>(){};
+};
+#elif defined(SECOND)
+struct S15 {
+  template <bool, bool> void f(){};
+  template <> void f<true, true>(){};
+};
+#else
+S15 s15;
+#endif
+
+#if defined(FIRST)
+struct S16 {
+  template <int *> void f(){};
+  template <> void f<nullptr>(){};
+};
+#elif defined(SECOND)
+struct S16 {
+  template <int *> void f(){};
+  template <> void f<nullptr>(){};
+};
+#else
+S16 s16;
+#endif
+
+#if defined(FIRST)
+struct S17 {
+  static int x;
+  template <int *> void f(){};
+  template <> void f<&x>(){};
+};
+#elif defined(SECOND)
+struct S17 {
+  static int x;
+  template <int *> void f(){};
+  template <> void f<nullptr>(){};
+};
+#else
+S17 s17;
+// expected-error at second.h:* {{'TemplateArgument::S17' has 
diff erent definitions in 
diff erent modules; first 
diff erence is definition in module 'SecondModule' found method 'f' with nullptr for 1st template argument}}
+// expected-note at first.h:* {{but in 'FirstModule' found method 'f' with 'x' for 1st template argument}}
+#endif
+
+#if defined(FIRST)
+struct S18 {
+  static int x;
+  template <int *> void f(){};
+  template <> void f<&x>(){};
+};
+#elif defined(SECOND)
+struct S18 {
+  static int x;
+  template <int *> void f(){};
+  template <> void f<&x>(){};
+};
+#else
+S18 s18;
+#endif
+
+#if defined(FIRST)
+struct S19 {
+  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);
+  template <_BitInt(128)> void f(){};
+  template <> void f<x + x>(){};
+};
+#elif defined(SECOND)
+struct S19 {
+  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);
+  template <_BitInt(128)> void f(){};
+  template <> void f<x + x>(){};
+};
+#else
+S19 s19;
+#endif
+
+#if defined(FIRST)
+struct S20 {
+  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);
+  template <_BitInt(128)> void f(){};
+  template <> void f<x + x>(){};
+};
+#elif defined(SECOND)
+struct S20 {
+  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);
+  template <_BitInt(128)> void f(){};
+  template <> void f<x>(){};
+};
+#else
+S20 s20;
+// expected-error at second.h:* {{'TemplateArgument::S20' has 
diff erent definitions in 
diff erent modules; first 
diff erence is definition in module 'SecondModule' found method 'f' with 18446744073709551615 for 1st template argument}}
+// expected-note at first.h:* {{but in 'FirstModule' found method 'f' with 36893488147419103230 for 1st template argument}}
+#endif
+
+#if defined(FIRST)
+struct S21 {
+  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);
+  template <_BitInt(128)> void f(){};
+  template <> void f<x + 0>(){};
+};
+#elif defined(SECOND)
+struct S21 {
+  static constexpr _BitInt(128) x = static_cast<_BitInt(128)>((unsigned long long)-1);
+  template <_BitInt(128)> void f(){};
+  template <> void f<(unsigned long long)-1>(){};
+};
+#else
+S21 s21;
+#endif
+
 #define DECLS                   \
   OneClass<int> a;              \
   OneInt<1> b;                  \


        


More information about the cfe-commits mailing list