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@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@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@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@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@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@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@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@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@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; \ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits