[PATCH] D154324: [C++20] [Modules] [ODRHash] Use CanonicalType for base classes

Richard Smith - zygoloid via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 21 14:05:38 PDT 2023


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



More information about the cfe-commits mailing list