rsmith added a comment. OK, I see. The problem is that the canonical version of the type can be spelled in different ways in different translation units, due to us treating some expressions as being equivalent despite them not being the same under the ODR. For example, we consider these function template declarations to be redeclarations:
namespace N { int x; template<typename T> void f(decltype(T(x))); } template<typename T> void f(decltype(T(::N::x))) {} ... but the ODR considers the expressions `x` and `::N::x` to be distinct. That means that the canonical form of the type "`decltype` of `N::x`-cast-to-`<type-template-parameter-0-0>`" has two possible different spellings. So we can't use the approach of mapping to the canonical type before forming an ODR hash -- doing so is not correct. Instead, let's use the other approach that I suggested, and add the spelling of the base class specifier (the type in its `TypeSourceInfo`) to the ODR hash instead of its canonical type. ================ Comment at: clang/lib/AST/ODRHash.cpp:596 for (const auto &Base : Bases) { - AddQualType(Base.getType()); + AddQualType(Base.getType().getCanonicalType()); ID.AddInteger(Base.isVirtual()); ---------------- Let's hash the type-as-written instead of hashing the canonical type. (`Base.getType()` gets the unqualified version of the type, which can partially desugar it, and can lead to different representations in different TUs.) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154324/new/ https://reviews.llvm.org/D154324 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits