[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