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

Reply via email to