<div dir="ltr">I've bisected <a href="https://crbug.com/1161059">https://crbug.com/1161059</a> down to this change. Would you like a reduced repro?<div>clang++: /b/s/w/ir/cache/builder/src/third_party/llvm/clang/lib/AST/ItaniumMangle.cpp:5763: void {anonymous}::CXXNameMangler::addSubstitution(uintptr_t): Assertion `!Substitutions.count(Ptr) && "Substitution already exists!"' failed.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Dec 17, 2020 at 11:23 PM Richard Smith via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Author: Richard Smith<br>
Date: 2020-12-17T23:23:05-08:00<br>
New Revision: 638867afd4bce4a2c56dea041299428af3727d61<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/638867afd4bce4a2c56dea041299428af3727d61" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/638867afd4bce4a2c56dea041299428af3727d61</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/638867afd4bce4a2c56dea041299428af3727d61.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/638867afd4bce4a2c56dea041299428af3727d61.diff</a><br>
<br>
LOG: DR2064: decltype(E) is only a dependent type if E is type-dependent, not<br>
if E is merely instantiation-dependent.<br>
<br>
Added: <br>
<br>
<br>
Modified: <br>
    clang/include/clang/AST/DependenceFlags.h<br>
    clang/lib/AST/ASTContext.cpp<br>
    clang/lib/AST/ItaniumMangle.cpp<br>
    clang/lib/AST/Type.cpp<br>
    clang/test/CXX/drs/dr20xx.cpp<br>
    clang/test/Sema/<a href="http://invalid-bitwidth-expr.mm" rel="noreferrer" target="_blank">invalid-bitwidth-expr.mm</a><br>
    clang/test/SemaCXX/invalid-template-base-specifier.cpp<br>
    clang/test/SemaTemplate/dependent-expr.cpp<br>
    clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp<br>
    clang/www/cxx_dr_status.html<br>
<br>
Removed: <br>
<br>
<br>
<br>
################################################################################<br>
diff  --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h<br>
index ca96b65574bd..8c47047a7526 100644<br>
--- a/clang/include/clang/AST/DependenceFlags.h<br>
+++ b/clang/include/clang/AST/DependenceFlags.h<br>
@@ -255,6 +255,12 @@ inline TypeDependence toTypeDependence(TemplateNameDependence D) {<br>
 inline TypeDependence toTypeDependence(TemplateArgumentDependence D) {<br>
   return Dependence(D).type();<br>
 }<br>
+/// Compute the dependence of a type that depends on the type of an expression,<br>
+/// given the dependence of that expression and of its type.<br>
+inline TypeDependence typeToTypeDependence(ExprDependence ED, TypeDependence TD) {<br>
+  return Dependence(ED & ~ExprDependence::Value).type() |<br>
+         (TD & TypeDependence::VariablyModified);<br>
+}<br>
<br>
 inline NestedNameSpecifierDependence<br>
 toNestedNameSpecifierDependendence(TypeDependence D) {<br>
<br>
diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp<br>
index 44545f00b146..0190573fe36e 100644<br>
--- a/clang/lib/AST/ASTContext.cpp<br>
+++ b/clang/lib/AST/ASTContext.cpp<br>
@@ -5383,10 +5383,10 @@ QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {<br>
   DecltypeType *dt;<br>
<br>
   // C++11 [temp.type]p2:<br>
-  //   If an expression e involves a template parameter, decltype(e) denotes a<br>
-  //   unique dependent type. Two such decltype-specifiers refer to the same<br>
-  //   type only if their expressions are equivalent (14.5.6.1).<br>
-  if (e->isInstantiationDependent()) {<br>
+  //   If an expression e is type-dependent, decltype(e) denotes a unique<br>
+  //   dependent type. Two such decltype-specifiers refer to the same type only<br>
+  //   if their expressions are equivalent (14.5.6.1).<br>
+  if (e->isTypeDependent()) {<br>
     llvm::FoldingSetNodeID ID;<br>
     DependentDecltypeType::Profile(ID, *this, e);<br>
<br>
<br>
diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp<br>
index 6c8d5687c64a..01deb598a078 100644<br>
--- a/clang/lib/AST/ItaniumMangle.cpp<br>
+++ b/clang/lib/AST/ItaniumMangle.cpp<br>
@@ -2582,6 +2582,11 @@ void CXXNameMangler::mangleType(QualType T) {<br>
       // instantation-dependent qualifiers. See<br>
       // <a href="https://github.com/itanium-cxx-abi/cxx-abi/issues/114" rel="noreferrer" target="_blank">https://github.com/itanium-cxx-abi/cxx-abi/issues/114</a>.<br>
<br>
+      // Don't desugar instantiation-dependent decltype / typeof types. We need<br>
+      // to mangle the expression as written.<br>
+      if (isa<DecltypeType, TypeOfType>(T))<br>
+        break;<br>
+<br>
       QualType Desugared<br>
         = T.getSingleStepDesugaredType(Context.getASTContext());<br>
       if (Desugared == T)<br>
<br>
diff  --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp<br>
index af39b80ef9e4..e5811dbc44c5 100644<br>
--- a/clang/lib/AST/Type.cpp<br>
+++ b/clang/lib/AST/Type.cpp<br>
@@ -125,8 +125,7 @@ ArrayType::ArrayType(TypeClass tc, QualType et, QualType can,<br>
     //   template<int ...N> int arr[] = {N...};<br>
     : Type(tc, can,<br>
            et->getDependence() |<br>
-               (sz ? toTypeDependence(<br>
-                         turnValueToTypeDependence(sz->getDependence()))<br>
+               (sz ? toTypeDependence(sz->getDependence())<br>
                    : TypeDependence::None) |<br>
                (tc == VariableArray ? TypeDependence::VariablyModified<br>
                                     : TypeDependence::None) |<br>
@@ -3396,9 +3395,8 @@ QualType MacroQualifiedType::getModifiedType() const {<br>
<br>
 TypeOfExprType::TypeOfExprType(Expr *E, QualType can)<br>
     : Type(TypeOfExpr, can,<br>
-           toTypeDependence(E->getDependence()) |<br>
-               (E->getType()->getDependence() &<br>
-                TypeDependence::VariablyModified)),<br>
+           typeToTypeDependence(E->getDependence(),<br>
+                                E->getType()->getDependence())),<br>
       TOExpr(E) {}<br>
<br>
 bool TypeOfExprType::isSugared() const {<br>
@@ -3418,18 +3416,12 @@ void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID,<br>
 }<br>
<br>
 DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)<br>
-    // C++11 [temp.type]p2: "If an expression e involves a template parameter,<br>
-    // decltype(e) denotes a unique dependent type." Hence a decltype type is<br>
-    // type-dependent even if its expression is only instantiation-dependent.<br>
     : Type(Decltype, can,<br>
-           toTypeDependence(E->getDependence()) |<br>
-               (E->isInstantiationDependent() ? TypeDependence::Dependent<br>
-                                              : TypeDependence::None) |<br>
-               (E->getType()->getDependence() &<br>
-                TypeDependence::VariablyModified)),<br>
+           typeToTypeDependence(E->getDependence(),<br>
+                                E->getType()->getDependence())),<br>
       E(E), UnderlyingType(underlyingType) {}<br>
<br>
-bool DecltypeType::isSugared() const { return !E->isInstantiationDependent(); }<br>
+bool DecltypeType::isSugared() const { return !E->isTypeDependent(); }<br>
<br>
 QualType DecltypeType::desugar() const {<br>
   if (isSugared())<br>
<br>
diff  --git a/clang/test/CXX/drs/dr20xx.cpp b/clang/test/CXX/drs/dr20xx.cpp<br>
index 56cc1161a00c..6e1c0505a5ec 100644<br>
--- a/clang/test/CXX/drs/dr20xx.cpp<br>
+++ b/clang/test/CXX/drs/dr20xx.cpp<br>
@@ -49,6 +49,18 @@ namespace dr2026 { // dr2026: 11<br>
   }<br>
 }<br>
<br>
+namespace dr2064 { // dr2064: 12<br>
+#if __cplusplus >= 201103L<br>
+  template<typename T> struct X {<br>
+    template<typename U> struct Y {};<br>
+  };<br>
+  template<typename T> void f() {<br>
+    X<decltype(sizeof(T))>::Y<int> y; // ok<br>
+    return X<decltype(sizeof(T))>::f(); // expected-error {{no member named 'f' in 'dr2064::X<unsigned}}<br>
+  }<br>
+#endif<br>
+}<br>
+<br>
 namespace dr2082 { // dr2082: 11<br>
   void test1(int x, int = sizeof(x)); // ok<br>
 #if __cplusplus >= 201103L<br>
<br>
diff  --git a/clang/test/Sema/<a href="http://invalid-bitwidth-expr.mm" rel="noreferrer" target="_blank">invalid-bitwidth-expr.mm</a> b/clang/test/Sema/<a href="http://invalid-bitwidth-expr.mm" rel="noreferrer" target="_blank">invalid-bitwidth-expr.mm</a><br>
index 41ca9496de4f..8ce498feb4af 100644<br>
--- a/clang/test/Sema/<a href="http://invalid-bitwidth-expr.mm" rel="noreferrer" target="_blank">invalid-bitwidth-expr.mm</a><br>
+++ b/clang/test/Sema/<a href="http://invalid-bitwidth-expr.mm" rel="noreferrer" target="_blank">invalid-bitwidth-expr.mm</a><br>
@@ -26,6 +26,7 @@ auto func() {<br>
 auto func() {<br>
   // error-bit should be propagated from TemplateArgument to NestNameSpecifier.<br>
   class Base<decltype(Foo(T()))>::type C; // expected-error {{no matching function for call to 'Foo'}}<br>
+  // expected-error@-1 {{no class named 'type' in 'Base<bool>'}}<br>
   return C;<br>
 }<br>
 struct Z {<br>
<br>
diff  --git a/clang/test/SemaCXX/invalid-template-base-specifier.cpp b/clang/test/SemaCXX/invalid-template-base-specifier.cpp<br>
index 7a1a7f801c45..77601402a85c 100644<br>
--- a/clang/test/SemaCXX/invalid-template-base-specifier.cpp<br>
+++ b/clang/test/SemaCXX/invalid-template-base-specifier.cpp<br>
@@ -12,11 +12,11 @@ void test() { Crash<int>(); } // expected-note {{in instantiation of template cl<br>
 template <typename T><br>
 using Alias = decltype(Foo(T())); // expected-error {{no matching function for call to 'Foo'}}<br>
 template <typename T><br>
-struct Crash2 : decltype(Alias<T>()) { // expected-note {{in instantiation of template type alias 'Alias' requested here}}<br>
+struct Crash2 : decltype(Alias<T>()) { // expected-note {{in instantiation of template type alias 'Alias' requested here}} expected-error {{base specifier must name a class}}<br>
   Crash2(){};<br>
 };<br>
<br>
-void test2() { Crash2<int>(); } // expected-note {{in instantiation of template class 'Crash2<int>' requested here}}<br>
+void test2() { Crash2<int>(); } // expected-note 2{{in instantiation of template class 'Crash2<int>' requested here}}<br>
<br>
 template <typename T><br>
 class Base {};<br>
<br>
diff  --git a/clang/test/SemaTemplate/dependent-expr.cpp b/clang/test/SemaTemplate/dependent-expr.cpp<br>
index abdb8e9c4a9f..dace7e28788d 100644<br>
--- a/clang/test/SemaTemplate/dependent-expr.cpp<br>
+++ b/clang/test/SemaTemplate/dependent-expr.cpp<br>
@@ -129,7 +129,12 @@ namespace PR45083 {<br>
   template<typename> void f() {<br>
     decltype(({})) x; // expected-error {{incomplete type}}<br>
   }<br>
-  template void f<int>(); // expected-note {{instantiation of}}<br>
+  template void f<int>();<br>
+<br>
+  template<typename T> void f2() {<br>
+    decltype(({T();})) x; // expected-error {{incomplete type}}<br>
+  }<br>
+  template void f2<void>(); // expected-note {{instantiation of}}<br>
<br>
   template<typename> auto g() {<br>
     auto c = [](auto, int) -> decltype(({})) {};<br>
<br>
diff  --git a/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp<br>
index 03ef78f8cf14..b9a1c933560d 100644<br>
--- a/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp<br>
+++ b/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp<br>
@@ -115,6 +115,12 @@ namespace Auto {<br>
<br>
   int n;<br>
   template<auto A, decltype(A) B = &n> struct SubstFailure;<br>
-  TInt<SubstFailure> isf; // FIXME: this should be ill-formed<br>
+  TInt<SubstFailure> isf; // expected-error {{template template argument has <br>
diff erent template parameters than its corresponding template template parameter}}<br>
   TIntPtr<SubstFailure> ipsf;<br>
+<br>
+  template<template<auto A, auto B, decltype(A)> typename C> struct TAutoAutoFirst {};<br>
+  template<auto A, auto B, decltype(A)> struct AutoAutoFirst;<br>
+  template<auto A, auto B, decltype(B)> struct AutoAutoSecond;<br>
+  TAutoAutoFirst<AutoAutoFirst> aaf;<br>
+  TAutoAutoFirst<AutoAutoSecond> aas; // FIXME: this should be rejected due to parameter mismatch<br>
 }<br>
<br>
diff  --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html<br>
index feac3c6dc2d0..b40d2c53bdec 100755<br>
--- a/clang/www/cxx_dr_status.html<br>
+++ b/clang/www/cxx_dr_status.html<br>
@@ -12199,7 +12199,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2><br>
     <td><a href="<a href="https://wg21.link/cwg2064" rel="noreferrer" target="_blank">https://wg21.link/cwg2064</a>">2064</a></td><br>
     <td>CD4</td><br>
     <td>Conflicting specifications for dependent <I>decltype-specifier</I>s</td><br>
-    <td class="none" align="center">Unknown</td><br>
+    <td class="unreleased" align="center">Clang 12</td><br>
   </tr><br>
   <tr class="open" id="2065"><br>
     <td><a href="<a href="https://wg21.link/cwg2065" rel="noreferrer" target="_blank">https://wg21.link/cwg2065</a>">2065</a></td><br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>