llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-modules

Author: Maksim Ivanov (emaxx-google)

<details>
<summary>Changes</summary>

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 
https://github.com/llvm/llvm-project/pull/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.

---
Full diff: https://github.com/llvm/llvm-project/pull/144796.diff


3 Files Affected:

- (modified) clang/lib/AST/ODRHash.cpp (+17-1) 
- (modified) clang/test/Modules/odr_hash.cpp (+23) 
- (modified) clang/test/PCH/race-condition.cpp (+6-5) 


``````````diff
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index f8446dfbc6859..84fac90a03e87 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -828,7 +828,23 @@ void ODRHash::AddDecl(const Decl *D) {
     return;
   }
 
-  AddDeclarationName(ND->getDeclName());
+  // For template parameters, use depth+index instead of name, because type
+  // canonicalization can change the name of the template parameter.
+  if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(ND)) {
+    ID.AddInteger(TTPD->getDepth());
+    ID.AddInteger(TTPD->getIndex());
+    AddBoolean(TTPD->isParameterPack());
+  } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(ND)) {
+    ID.AddInteger(NTTPD->getDepth());
+    ID.AddInteger(NTTPD->getIndex());
+    AddBoolean(NTTPD->isParameterPack());
+  } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(ND)) {
+    ID.AddInteger(TTPD->getDepth());
+    ID.AddInteger(TTPD->getIndex());
+    AddBoolean(TTPD->isParameterPack());
+  } else {
+    AddDeclarationName(ND->getDeclName());
+  }
 
   // If this was a specialization we should take into account its template
   // arguments. This helps to reduce collisions coming when visiting template
diff --git a/clang/test/Modules/odr_hash.cpp b/clang/test/Modules/odr_hash.cpp
index da24b1fe8729a..8ef53e32f2e95 100644
--- a/clang/test/Modules/odr_hash.cpp
+++ b/clang/test/Modules/odr_hash.cpp
@@ -5164,6 +5164,29 @@ namespace A {
 A::X x;
 #endif
 
+namespace TemplateDecltypeOperator {
+
+#if defined(FIRST) || defined(SECOND)
+template <class T6>
+T6 func();
+#endif
+
+#if defined(SECOND)
+template <class UnrelatedT>
+using UnrelatedAlias = decltype(func<UnrelatedT>())();
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+class A {
+  template <class T6>
+  operator decltype(func<T6>()) () {}
+};
+#else
+A a;
+#endif
+
+}
+
 // Keep macros contained to one file.
 #ifdef FIRST
 #undef FIRST
diff --git a/clang/test/PCH/race-condition.cpp 
b/clang/test/PCH/race-condition.cpp
index 752b0cc3ff628..666d92ed2ce8b 100644
--- a/clang/test/PCH/race-condition.cpp
+++ b/clang/test/PCH/race-condition.cpp
@@ -31,11 +31,12 @@ constexpr enable_if_t<meta<F>::value == 2, void> 
midpoint(F) {}
 
 #else
 
-// expected-error@27{{'N::midpoint' has different definitions in different 
modules; defined here first difference is 1st parameter with type 'F'}}
-// expected-error@24{{'N::midpoint' has different definitions in different 
modules; defined here first difference is 1st parameter with type 'U'}}
-// expected-note@21{{but in '' found 1st parameter with type 'T'}}
+// FIXME: Change the test to trigger a suitable error: previously the test
+// asserted the ODR error ("'N::midpoint' has different definitions in 
different
+// modules"), which isn't fully correct as there's only one module, and since a
+// change in the ODR hash calculation this error isn't triggered anymore.
+
 int x = N::something;
-// expected-error@37{{no member named 'something' in namespace 'N'}}
-// expected-note@21{{but in '' found 1st parameter with type 'T'}}
+// expected-error@38{{no member named 'something' in namespace 'N'}}
 
 #endif

``````````

</details>


https://github.com/llvm/llvm-project/pull/144796
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to