Skip to content

Commit 2fd016f

Browse files
committed
[clang] ODR hashes depth+index and not name of TemplateTypeParm
Change the ODR hashing logic to use the depth+index indices instead of template parameter names. This prevents spurious ODR errors in header module builds when the type canonicalization picks up different expressions - with different template parameter names (profiling used for canonicalization ignores template parameter names). This fixes #143152. This commit removes test assertions from the regression test of #108866 - the compiler errors asserted by that test stop firing with this commit. It's questionable whether these diagnostics were correct. We add a FIXME to find a better regression test for that fix.
1 parent a5cbd2a commit 2fd016f

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

clang/lib/AST/ODRHash.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,23 @@ void ODRHash::AddDecl(const Decl *D) {
828828
return;
829829
}
830830

831-
AddDeclarationName(ND->getDeclName());
831+
// For template parameters, use depth+index instead of name, because type
832+
// canonicalization can change the name of the template parameter.
833+
if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ND)) {
834+
ID.AddInteger(TTPD->getDepth());
835+
ID.AddInteger(TTPD->getIndex());
836+
AddBoolean(TTPD->isParameterPack());
837+
} else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ND)) {
838+
ID.AddInteger(NTTPD->getDepth());
839+
ID.AddInteger(NTTPD->getIndex());
840+
AddBoolean(NTTPD->isParameterPack());
841+
} else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(ND)) {
842+
ID.AddInteger(TTPD->getDepth());
843+
ID.AddInteger(TTPD->getIndex());
844+
AddBoolean(TTPD->isParameterPack());
845+
} else {
846+
AddDeclarationName(ND->getDeclName());
847+
}
832848

833849
// If this was a specialization we should take into account its template
834850
// arguments. This helps to reduce collisions coming when visiting template

clang/test/Modules/odr_hash.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5164,6 +5164,29 @@ namespace A {
51645164
A::X x;
51655165
#endif
51665166

5167+
namespace TemplateDecltypeOperator {
5168+
5169+
#if defined(FIRST) || defined(SECOND)
5170+
template <class T6>
5171+
T6 func();
5172+
#endif
5173+
5174+
#if defined(SECOND)
5175+
template <class UnrelatedT>
5176+
using UnrelatedAlias = decltype(func<UnrelatedT>())();
5177+
#endif
5178+
5179+
#if defined(FIRST) || defined(SECOND)
5180+
class A {
5181+
template <class T6>
5182+
operator decltype(func<T6>()) () {}
5183+
};
5184+
#else
5185+
A a;
5186+
#endif
5187+
5188+
}
5189+
51675190
// Keep macros contained to one file.
51685191
#ifdef FIRST
51695192
#undef FIRST

clang/test/PCH/race-condition.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ constexpr enable_if_t<meta<F>::value == 2, void> midpoint(F) {}
3131

3232
#else
3333

34-
// expected-error@27{{'N::midpoint' has different definitions in different modules; defined here first difference is 1st parameter with type 'F'}}
35-
// expected-error@24{{'N::midpoint' has different definitions in different modules; defined here first difference is 1st parameter with type 'U'}}
36-
// expected-note@21{{but in '' found 1st parameter with type 'T'}}
34+
// FIXME: Change the test to trigger a suitable error: previously the test
35+
// asserted the ODR error ("'N::midpoint' has different definitions in different
36+
// modules"), which isn't fully correct as there's only one module, and since a
37+
// change in the ODR hash calculation this error isn't triggered anymore.
38+
3739
int x = N::something;
38-
// expected-error@37{{no member named 'something' in namespace 'N'}}
39-
// expected-note@21{{but in '' found 1st parameter with type 'T'}}
40+
// expected-error@38{{no member named 'something' in namespace 'N'}}
4041

4142
#endif

0 commit comments

Comments
 (0)