https://github.com/mizvekov updated 
https://github.com/llvm/llvm-project/pull/190495

>From 156f911690650d4864b783e04a74071525c49e8d Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <[email protected]>
Date: Sat, 4 Apr 2026 20:44:35 -0300
Subject: [PATCH] [clang] implement CWG2064: ignore value dependence for
 decltype

The 'decltype' for a value-dependent (but non-type-dependent) should be known,
so this patch makes them non-opaque instead.

Readds a few test cases from da98651

Fixes #61818
---
 clang/docs/ReleaseNotes.rst                   |  1 +
 clang/include/clang/AST/DependenceFlags.h     |  2 +-
 clang/lib/AST/ASTContext.cpp                  |  9 +++---
 clang/lib/AST/ItaniumMangle.cpp               | 15 +++++++---
 clang/lib/AST/Type.cpp                        | 22 +++++++-------
 clang/test/CXX/drs/cwg20xx.cpp                | 17 +++++++++--
 .../test/CXX/temp/temp.decls/temp.mem/p5.cpp  |  2 +-
 clang/test/CodeGenCXX/GH190495.cpp            | 29 +++++++++++++++++++
 clang/test/CodeGenCXX/mangle-subst.cpp        | 13 ++++++++-
 clang/test/Sema/invalid-bitwidth-expr.mm      |  1 +
 clang/test/SemaCXX/decltype.cpp               | 15 +++++++++-
 clang/test/SemaCXX/source_location.cpp        |  7 ++++-
 clang/test/SemaCXX/typeof.cpp                 |  2 +-
 .../SemaTemplate/concepts-out-of-line-def.cpp |  6 ++--
 clang/test/SemaTemplate/concepts.cpp          |  9 ++++++
 clang/test/SemaTemplate/deduction-guide.cpp   | 23 +++++++--------
 clang/test/SemaTemplate/dependent-expr.cpp    |  8 ++---
 .../SemaTemplate/temp_arg_template_p0522.cpp  | 11 ++++++-
 18 files changed, 145 insertions(+), 47 deletions(-)
 create mode 100644 clang/test/CodeGenCXX/GH190495.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2fe76e60946f5..10996aefcd59b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -423,6 +423,7 @@ Bug Fixes to C++ Support
 - Fixed a crash when pack expansions are used as arguments for non-pack 
parameters of built-in templates. (#GH180307)
 - Fixed a bug where captured variables in non-mutable lambdas were incorrectly 
treated as mutable 
   when used inside decltype in the return type. (#GH180460)
+- `decltype(expr)` now ignores value-dependence on the expression. (#GH61818)
 - Fixed a crash when evaluating uninitialized GCC vector/ext_vector_type 
vectors in ``constexpr``. (#GH180044)
 - Fixed a crash when `explicit(bool)` is used with an incomplete enumeration. 
(#GH183887)
 - Fixed a crash on ``typeid`` of incomplete local types during template 
instantiation. (#GH63242), (#GH176397)
diff --git a/clang/include/clang/AST/DependenceFlags.h 
b/clang/include/clang/AST/DependenceFlags.h
index c4395259f0758..2f003af925d79 100644
--- a/clang/include/clang/AST/DependenceFlags.h
+++ b/clang/include/clang/AST/DependenceFlags.h
@@ -194,7 +194,7 @@ class Dependence {
   TypeDependence type() const {
     return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) |
            translate(V, Instantiation, TypeDependence::Instantiation) |
-           translate(V, Dependent, TypeDependence::Dependent) |
+           translate(V, Type, TypeDependence::Dependent) |
            translate(V, Error, TypeDependence::Error) |
            translate(V, VariablyModified, TypeDependence::VariablyModified);
   }
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index ee7f823b014b2..36978548ca171 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -6691,12 +6691,11 @@ QualType ASTContext::getReferenceQualifiedType(const 
Expr *E) const {
 /// expression, and would not give a significant memory saving, since there
 /// is an Expr tree under each such type.
 QualType ASTContext::getDecltypeType(Expr *E, QualType UnderlyingType) const {
-  // C++11 [temp.type]p2:
-  //   If an expression e involves a template parameter, decltype(e) denotes a
-  //   unique dependent type. Two such decltype-specifiers refer to the same
-  //   type only if their expressions are equivalent (14.5.6.1).
+  // C++26 [temp.type]p4: If an expression e is type-dependent, decltype(e)
+  // denotes a unique dependent type. Two such decltype-specifiers refer to the
+  // same type only if their expressions are equivalent ([temp.over.link]).
   QualType CanonType;
-  if (!E->isInstantiationDependent()) {
+  if (!E->isTypeDependent()) {
     CanonType = getCanonicalType(UnderlyingType);
   } else if (!UnderlyingType.isNull()) {
     CanonType = getDecltypeType(E, QualType());
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index d21faaa87558d..54f0993f80186 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3008,6 +3008,11 @@ void CXXNameMangler::mangleType(QualType T) {
         if (!TST->isTypeAlias())
           break;
 
+      // instantiation-dependent decltypes are mangled through their
+      // expressions.
+      if (T->isInstantiationDependentType() && isa<DecltypeType>(T))
+        break;
+
       // FIXME: We presumably shouldn't strip off ElaboratedTypes with
       // instantation-dependent qualifiers. See
       // https://github.com/itanium-cxx-abi/cxx-abi/issues/114.
@@ -7005,8 +7010,9 @@ static bool hasMangledSubstitutionQualifiers(QualType T) {
 
 bool CXXNameMangler::mangleSubstitution(QualType T) {
   if (!hasMangledSubstitutionQualifiers(T)) {
-    if (const auto *RD = T->getAsCXXRecordDecl())
-      return mangleSubstitution(RD);
+    if (const auto *TT = dyn_cast<TagType>(T);
+        isa_and_nonnull<RecordType, InjectedClassNameType>(TT))
+      return mangleSubstitution(TT->getDecl());
   }
 
   uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
@@ -7175,8 +7181,9 @@ bool CXXNameMangler::mangleStandardSubstitution(const 
NamedDecl *ND) {
 
 void CXXNameMangler::addSubstitution(QualType T) {
   if (!hasMangledSubstitutionQualifiers(T)) {
-    if (const auto *RD = T->getAsCXXRecordDecl()) {
-      addSubstitution(RD);
+    if (const auto *TT = dyn_cast<TagType>(T);
+        isa_and_nonnull<RecordType, InjectedClassNameType>(TT)) {
+      addSubstitution(TT->getDecl());
       return;
     }
   }
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 78983fd38410d..b8362f25ec5d2 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -428,9 +428,16 @@ BitIntType::BitIntType(bool IsUnsigned, unsigned NumBits)
       NumBits(NumBits) {}
 
 DependentBitIntType::DependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr)
+    // DependentBitIntType must always be type-dependent.
+    // The expression must be value-dependent, so will also be
+    // instantiation-dependent.
     : Type(DependentBitInt, QualType{},
-           toTypeDependence(NumBitsExpr->getDependence())),
-      ExprAndUnsigned(NumBitsExpr, IsUnsigned) {}
+           toTypeDependence(NumBitsExpr->getDependence()) |
+               TypeDependence::Dependent),
+      ExprAndUnsigned(NumBitsExpr, IsUnsigned) {
+  assert(NumBitsExpr->isValueDependent() &&
+         "NumBitsExpr must be value-dependent");
+}
 
 bool DependentBitIntType::isUnsigned() const {
   return ExprAndUnsigned.getInt();
@@ -4219,15 +4226,10 @@ DecltypeType::DecltypeType(Expr *E, QualType 
underlyingType, QualType can)
     // C++11 [temp.type]p2: "If an expression e involves a template parameter,
     // decltype(e) denotes a unique dependent type." Hence a decltype type is
     // type-dependent even if its expression is only instantiation-dependent.
-    : Type(Decltype, can,
-           toTypeDependence(E->getDependence()) |
-               (E->isInstantiationDependent() ? TypeDependence::Dependent
-                                              : TypeDependence::None) |
-               (E->getType()->getDependence() &
-                TypeDependence::VariablyModified)),
-      E(E), UnderlyingType(underlyingType) {}
+    : Type(Decltype, can, toTypeDependence(E->getDependence())), E(E),
+      UnderlyingType(underlyingType) {}
 
-bool DecltypeType::isSugared() const { return !E->isInstantiationDependent(); }
+bool DecltypeType::isSugared() const { return !E->isTypeDependent(); }
 
 QualType DecltypeType::desugar() const {
   if (isSugared())
diff --git a/clang/test/CXX/drs/cwg20xx.cpp b/clang/test/CXX/drs/cwg20xx.cpp
index 75b4094283db0..f669d460f4d09 100644
--- a/clang/test/CXX/drs/cwg20xx.cpp
+++ b/clang/test/CXX/drs/cwg20xx.cpp
@@ -64,6 +64,19 @@ namespace cwg2061 { // cwg2061: 2.7
 #endif // C++11
 } // namespace cwg2061
 
+namespace cwg2064 { // cwg2064: 23
+#if __cplusplus >= 201103L
+  template<typename T> struct X {
+    template<typename U> struct Y {};
+  };
+  template<typename T> void g() {
+    X<decltype(sizeof(T))>::Y<int> y; // ok
+    return X<decltype(sizeof(T))>::f();
+    // expected-error@-1 {{no member named 'f' in 'cwg2064::X<unsigned long>'}}
+  }
+#endif
+}
+
 namespace cwg2076 { // cwg2076: 13
 #if __cplusplus >= 201103L
   namespace std_example {
@@ -86,7 +99,7 @@ namespace cwg2076 { // cwg2076: 13
     operator string_view() const;
   };
 
-  void foo(const string &); // #cwg2076-foo 
+  void foo(const string &); // #cwg2076-foo
   void bar(string_view); // #cwg2076-bar
 
   void func(const string &arg) {
@@ -369,7 +382,7 @@ int f()
   return 0;
 }
 } // namespace GH42233
-} // namespace cwg2091 
+} // namespace cwg2091
 
 namespace cwg2094 { // cwg2094: 5
   struct A { int n; };
diff --git a/clang/test/CXX/temp/temp.decls/temp.mem/p5.cpp 
b/clang/test/CXX/temp/temp.decls/temp.mem/p5.cpp
index 65d8345ecc3aa..a0c9e931c3298 100644
--- a/clang/test/CXX/temp/temp.decls/temp.mem/p5.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.mem/p5.cpp
@@ -92,7 +92,7 @@ template X0::operator B<0>() const; // expected-error 
{{undefined function templ
 // index expression as non-canonical is extra bad.
 template X0::operator C<int[1]>() const; // expected-error {{undefined 
function template 'operator C<type-parameter-0-0[V]>'}}
 #if __cplusplus >= 201103L
-template X0::operator D<int, 0>() const; // expected-error {{undefined 
function template 'operator D<decltype(value-parameter-0-0), 
value-parameter-0-0>'}}
+template X0::operator D<int, 0>() const; // expected-error {{undefined 
function template 'operator D<int, value-parameter-0-0>'}}
 #endif
 
 void test_X0(X0 x0, const X0 &x0c) {
diff --git a/clang/test/CodeGenCXX/GH190495.cpp 
b/clang/test/CodeGenCXX/GH190495.cpp
new file mode 100644
index 0000000000000..87984f8c34ac1
--- /dev/null
+++ b/clang/test/CodeGenCXX/GH190495.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++26 -emit-llvm %s -o - -triple=x86_64-apple-darwin9
+
+namespace std {
+class partial_ordering {};
+class strong_ordering {
+public:
+  operator partial_ordering();
+};
+using size_t = decltype(sizeof(int));
+template <size_t> struct __priority_tag {};
+namespace __partial_order {
+struct __fn {
+  template <class _Tp, class _Up>
+  constexpr auto __go(_Tp __t, _Up __u, __priority_tag<2>)
+      -> decltype(partial_ordering(partial_order(__t, __u))) {}
+  template <class _Tp, class _Up> auto operator()(_Tp __t, _Up __u) {
+    __go(__t, __u, __priority_tag<2>());
+  }
+};
+}
+auto partial_order = __partial_order::__fn{};
+namespace {
+struct A {};
+strong_ordering partial_order(A, A) {
+  A a;
+  std::partial_order(a, a);
+}
+}
+}
diff --git a/clang/test/CodeGenCXX/mangle-subst.cpp 
b/clang/test/CodeGenCXX/mangle-subst.cpp
index 524e0febe479a..fa59ca2dfb3d0 100644
--- a/clang/test/CodeGenCXX/mangle-subst.cpp
+++ b/clang/test/CodeGenCXX/mangle-subst.cpp
@@ -69,7 +69,7 @@ namespace NS {
 
 namespace NS {
   // CHECK: @_ZN2NS1fERNS_1CE
-  void f(C&) { } 
+  void f(C&) { }
 }
 
 namespace Test1 {
@@ -123,3 +123,14 @@ struct Inst : public A::Impl<A::Wrap> {};
 void Test() { Inst a; }
 
 }
+
+namespace InstantiationDependentDecltype {
+  struct a { a(char); };
+  struct b { a c(); };
+  // FIXME: This mangling is incorrect; the second decltype type should be a
+  // substitution for the first.
+  // CHECK: 
@_ZN30InstantiationDependentDecltype1fINS_1bEEEvDTcvNS_1aEcldtcvT__E1cEEDTcvS2_cldtcvS3__E1cEES3_S3_S2_S2_
+  // FIXME: 
@_ZN30InstantiationDependentDecltype1fINS_1bEEEvDTcvNS_1aEcldtcvT__E1cEES4_S3_S3_S2_S2_
+  template<typename d> void f(decltype(a(d().c())), decltype(a(d().c())), d, 
d, a, a);
+  void g(a a, b b) { f(a, a, b, b, a, a); }
+}
diff --git a/clang/test/Sema/invalid-bitwidth-expr.mm 
b/clang/test/Sema/invalid-bitwidth-expr.mm
index 9e577300eb1c8..25930e5d4ef7e 100644
--- a/clang/test/Sema/invalid-bitwidth-expr.mm
+++ b/clang/test/Sema/invalid-bitwidth-expr.mm
@@ -26,6 +26,7 @@ auto func() {
 auto func() {
   // error-bit should be propagated from TemplateArgument to NestNameSpecifier.
   class Base<decltype(Foo(T()))>::type C; // expected-error {{no matching 
function for call to 'Foo'}}
+  // expected-error@-1 {{no class named 'type' in 'Base<bool>'}}
   return C;
 }
 struct Z {
diff --git a/clang/test/SemaCXX/decltype.cpp b/clang/test/SemaCXX/decltype.cpp
index 45a4c4cf1ac86..a41c8f6437452 100644
--- a/clang/test/SemaCXX/decltype.cpp
+++ b/clang/test/SemaCXX/decltype.cpp
@@ -135,7 +135,7 @@ namespace GH97646 {
   template<bool B>
   void f() {
     decltype(B) x = false;
-    !x;
+    !x; // expected-warning {{expression result unused}}
   }
 }
 
@@ -241,6 +241,19 @@ void test() { (void)C::XBitMask<0>; }
 }
 #endif
 
+namespace value_dependent {
+  template<int V> void f() {
+    decltype(V) x = nullptr;
+    // expected-error@-1 {{cannot initialize a variable of type 'decltype(V)' 
(aka 'int') with an rvalue of type 'std::nullptr_t'}}
+  }
+
+  // FIXME: Should be different overloads
+  template<typename T> decltype(int(T())) f() {}
+  // expected-note@-1 {{previous definition is here}}
+  template<typename T> decltype(int(T(0))) f() {}
+  // expected-error@-1 {{redefinition of 'f'}}
+} // namespace value_dependent
+
 template<typename>
 class conditional {
 };
diff --git a/clang/test/SemaCXX/source_location.cpp 
b/clang/test/SemaCXX/source_location.cpp
index eaa6cb04c5d1c..13846553421ce 100644
--- a/clang/test/SemaCXX/source_location.cpp
+++ b/clang/test/SemaCXX/source_location.cpp
@@ -9,7 +9,9 @@
 // RUN: %clang_cc1 -std=c++2b -fcxx-exceptions -DUSE_CONSTEVAL -DPAREN_INIT 
-fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP -verify %s
 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS 
-fexceptions -fexperimental-new-constant-interpreter -DNEW_INTERP 
-fms-compatibility -verify %s
 // RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS 
-DUSE_CONSTEVAL -fexceptions -fexperimental-new-constant-interpreter 
-DNEW_INTERP -verify -fms-compatibility %s
+#ifndef MS
 // expected-no-diagnostics
+#endif
 
 #define assert(...) ((__VA_ARGS__) ? ((void)0) : throw 42)
 #define CURRENT_FROM_MACRO() SL::current()
@@ -1088,6 +1090,9 @@ namespace GH178324 {
     using e = int;
   };
   void current(const char * = __builtin_FUNCSIG());
-  template <class> void c() { decltype(a(current()))::e; }
+  template <class> void c() {
+    decltype(a(current()))::e;
+    // expected-warning@-1 {{declaration does not declare anything}}
+  }
 } // namespace GH178324
 #endif
diff --git a/clang/test/SemaCXX/typeof.cpp b/clang/test/SemaCXX/typeof.cpp
index 421cfc59f5311..e6d3dbccf7321 100644
--- a/clang/test/SemaCXX/typeof.cpp
+++ b/clang/test/SemaCXX/typeof.cpp
@@ -8,6 +8,6 @@ namespace GH97646 {
   template<bool B>
   void f() {
     __typeof__(B) x = false;
-    !x;
+    !x; // expected-warning {{expression result unused}}
   }
 }
diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp 
b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
index 9811b18f4301b..0939a2a7fbb5f 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -533,12 +533,12 @@ template <class T>
 void X<T>::foo() requires requires { requires is_not_same_v<T, int>; } {} // ok
 
 template <class T>
-void X<T>::bar(decltype(requires { requires something_interesting<T>; })) {}
-// expected-error@-1{{definition of 'bar' does not match any declaration}}
-// expected-note@#defined-here{{defined here}}
+void X<T>::bar(decltype(requires { requires something_interesting<T>; })) {} 
// #GH74314-bar-prev-def-here
 
 template <class T>
 void X<T>::bar(decltype(requires { requires is_not_same_v<T, int>; })) {}
+// expected-error@-1 {{redefinition of 'bar'}}
+// expected-note@#GH74314-bar-prev-def-here {{previous definition is here}}
 } // namespace GH74314
 
 namespace GH56482 {
diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index 429df756c1c4f..4e89c814e20b1 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1824,3 +1824,12 @@ namespace GH176402 {
     recursiveLambda(recursiveLambda, 5);
   }
 }
+
+namespace GH61818 {
+  template <typename T> concept C = true;
+  template <typename T> struct A;
+  template <> struct A<bool> { using type = bool; };
+
+  template <typename T>
+  void f(A<decltype(C<T>)>::type); // OK, no 'typename' needed
+} // namespace GH61818
diff --git a/clang/test/SemaTemplate/deduction-guide.cpp 
b/clang/test/SemaTemplate/deduction-guide.cpp
index 9e5756ffec3fc..29693e1918263 100644
--- a/clang/test/SemaTemplate/deduction-guide.cpp
+++ b/clang/test/SemaTemplate/deduction-guide.cpp
@@ -854,17 +854,17 @@ CC c{};
 
 // CHECK-LABEL: Dumping GH133132::<deduction guide for CC>:
 // CHECK-NEXT:  FunctionTemplateDecl {{.+}} implicit <deduction guide for CC>
-// CHECK-NEXT:  |-NonTypeTemplateParmDecl {{.+}} 'int' depth 0 index 0 N
-// CHECK-NEXT:  | `-TemplateArgument {{.+}} expr '42'
-// CHECK-NEXT:  |   `-IntegerLiteral {{.+}} 'int' 42
-// CHECK-NEXT:  |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
-// CHECK-NEXT:  | `-TemplateArgument type 'A<decltype(N)>'
-// CHECK-NEXT:  |   `-TemplateSpecializationType {{.+}} 'A<decltype(N)>' 
dependent
+// CHECK-NEXT:  |-TemplateTypeParmDecl {{.+}} class depth 0 index 0 U
+// CHECK-NEXT:  | `-TemplateArgument type 'A<decltype(N)>':'GH133132::A<int>'
+// CHECK-NEXT:  |   `-TemplateSpecializationType {{.+}} 'A<decltype(N)>' sugar 
instantiation_dependent
 // CHECK-NEXT:  |     |-name: 'A':'GH133132::A' qualified
 // CHECK-NEXT:  |     | `-ClassTemplateDecl {{.+}} A
-// CHECK-NEXT:  |     `-TemplateArgument type 'decltype(N)'
-// CHECK-NEXT:  |       `-DecltypeType {{.+}} 'decltype(N)' dependent
-// CHECK-NEXT:  |         `-DeclRefExpr {{.+}} 'int' NonTypeTemplateParm 
{{.+}} 'N' 'int'
+// CHECK-NEXT:  |     |-TemplateArgument type 'decltype(N)':'int'
+// CHECK-NEXT:  |     | `-DecltypeType {{.+}} 'decltype(N)' sugar 
instantiation_dependent
+// CHECK-NEXT:  |     |   |-DeclRefExpr {{.+}} 'int' NonTypeTemplateParm 
{{.+}} 'N' 'int'
+// CHECK-NEXT:  |     |   `-BuiltinType {{.+}} 'int'
+// CHECK-NEXT:  |     `-RecordType {{.+}} 'GH133132::A<int>' canonical
+// CHECK-NEXT:  |       `-ClassTemplateSpecialization {{.+}} 'A'
 // CHECK-NEXT:  |-TypeTraitExpr {{.+}} 'bool' __is_deducible
 // CHECK-NEXT:  | |-DeducedTemplateSpecializationType {{.+}} 'GH133132::CC' 
dependent
 // CHECK-NEXT:  | | `-name: 'GH133132::CC'
@@ -872,14 +872,13 @@ CC c{};
 // CHECK-NEXT:  | `-TemplateSpecializationType {{.+}} 'GH133132::A<U>' 
dependent
 // CHECK-NEXT:  |   |-name: 'GH133132::A'
 // CHECK-NEXT:  |   | `-ClassTemplateDecl {{.+}} A
-// CHECK-NEXT:  |   `-TemplateArgument type 'U':'type-parameter-0-1'
+// CHECK-NEXT:  |   `-TemplateArgument type 'U':'type-parameter-0-0'
 // CHECK-NEXT:  |     `-SubstTemplateTypeParmType {{.+}} 'U' sugar dependent 
class depth 0 index 0 _Ty
 // CHECK-NEXT:  |       |-FunctionTemplate {{.+}} '<deduction guide for A>'
-// CHECK-NEXT:  |       `-TemplateTypeParmType {{.+}} 'U' dependent depth 0 
index 1
+// CHECK-NEXT:  |       `-TemplateTypeParmType {{.+}} 'U' dependent depth 0 
index 0
 // CHECK-NEXT:  |         `-TemplateTypeParm {{.+}} 'U'
 // CHECK-NEXT:  |-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for 
CC> 'auto () -> GH133132::A<U>'
 // CHECK-NEXT:  `-CXXDeductionGuideDecl {{.+}} implicit used <deduction guide 
for CC> 'auto () -> GH133132::A<GH133132::A<int>>' implicit_instantiation
-// CHECK-NEXT:    |-TemplateArgument integral '42'
 // CHECK-NEXT:    `-TemplateArgument type 'GH133132::A<int>'
 // CHECK-NEXT:      `-RecordType {{.+}} 'GH133132::A<int>'
 // CHECK-NEXT:        `-ClassTemplateSpecialization {{.+}} 'A'
diff --git a/clang/test/SemaTemplate/dependent-expr.cpp 
b/clang/test/SemaTemplate/dependent-expr.cpp
index ce210d9b74f6d..31ee43ab9501c 100644
--- a/clang/test/SemaTemplate/dependent-expr.cpp
+++ b/clang/test/SemaTemplate/dependent-expr.cpp
@@ -13,12 +13,12 @@ namespace PR6045 {
     static const unsigned int member = r;
     void f();
   };
-  
+
   template<unsigned int r>
   const unsigned int A<r>::member;
-  
+
   template<unsigned int r>
-  void A<r>::f() 
+  void A<r>::f()
   {
     unsigned k;
     (void)(k % member);
@@ -129,7 +129,7 @@ namespace PR45083 {
   template<typename> void f() {
     decltype(({})) x; // expected-error {{incomplete type}}
   }
-  template void f<int>(); // expected-note {{instantiation of}}
+  template void f<int>();
 
   template<typename> auto g() {
     auto c = [](auto, int) -> decltype(({})) {};
diff --git a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp 
b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
index bde811c3bf685..1d97deeb9214a 100644
--- a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
+++ b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
@@ -135,8 +135,17 @@ namespace Auto {
 
   int n;
   template<auto A, decltype(A) B = &n> struct SubstFailure;
-  TInt<SubstFailure> isf; // FIXME: this should be ill-formed
+  // expected-error@-1 {{value of type 'int *' is not implicitly convertible 
to 'decltype(value-parameter-0-0)' (aka 'int')}}
+  // expected-note@#TInt {{while checking a default template argument used 
here}}
+  TInt<SubstFailure> isf;
+  // expected-note@-1 {{template template argument has different template 
parameters than its corresponding template template parameter}}
   TIntPtr<SubstFailure> ipsf;
+
+  template<template<auto A, auto B, decltype(A)> typename C> struct 
TAutoAutoFirst {};
+  template<auto A, auto B, decltype(A)> struct AutoAutoFirst;
+  template<auto A, auto B, decltype(B)> struct AutoAutoSecond;
+  TAutoAutoFirst<AutoAutoFirst> aaf;
+  TAutoAutoFirst<AutoAutoSecond> aas; // FIXME: this should be rejected due to 
parameter mismatch
 }
 
 namespace GH62529 {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to