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

>From 34622bb2d0e921d28b09075ca68350daafa08b34 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <[email protected]>
Date: Tue, 26 May 2026 10:19:00 -0300
Subject: [PATCH] [clang] NFC: readd test cases reverted in
 79f4d8f0145d72dff8c33745f35d45c74ecb3fdf

We need some sort of process to stop losing regression tests due to reverts...
---
 .../Inputs/class-template-spec.cpp            |  47 ++++++++
 .../ASTMerge/class-template-spec/test.cpp     |   8 ++
 .../CXX/temp/temp.spec/temp.expl.spec/p7.cpp  | 110 ++++++++++++++++++
 3 files changed, 165 insertions(+)
 create mode 100644 
clang/test/ASTMerge/class-template-spec/Inputs/class-template-spec.cpp
 create mode 100644 clang/test/ASTMerge/class-template-spec/test.cpp

diff --git 
a/clang/test/ASTMerge/class-template-spec/Inputs/class-template-spec.cpp 
b/clang/test/ASTMerge/class-template-spec/Inputs/class-template-spec.cpp
new file mode 100644
index 0000000000000..332bf24d25b29
--- /dev/null
+++ b/clang/test/ASTMerge/class-template-spec/Inputs/class-template-spec.cpp
@@ -0,0 +1,47 @@
+namespace N0 {
+  template<typename T>
+  struct A {
+    template<typename U>
+    friend struct A;
+  };
+
+  template struct A<long>;
+} // namespace N0
+
+namespace N1 {
+  template<typename T>
+  struct A;
+
+  template<typename T>
+  struct A {
+    template<typename U>
+    friend struct A;
+  };
+
+  template struct A<long>;
+} // namespace N1
+
+namespace N2 {
+  template<typename T>
+  struct A {
+    template<typename U>
+    friend struct A;
+  };
+
+  template<typename T>
+  struct A;
+
+  template struct A<long>;
+} // namespace N2
+
+namespace N3 {
+  struct A {
+    template<typename T>
+    friend struct B;
+  };
+
+  template<typename T>
+  struct B { };
+
+  template struct B<long>;
+} // namespace N3
diff --git a/clang/test/ASTMerge/class-template-spec/test.cpp 
b/clang/test/ASTMerge/class-template-spec/test.cpp
new file mode 100644
index 0000000000000..adbce48350327
--- /dev/null
+++ b/clang/test/ASTMerge/class-template-spec/test.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/class-template-spec.cpp
+// RUN: %clang_cc1 -ast-merge %t.1.ast -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+template struct N0::A<short>;
+template struct N1::A<short>;
+template struct N2::A<short>;
+template struct N3::B<short>;
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp 
b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp
index 5bb5de88a6fc2..b93562a60de57 100644
--- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp
@@ -180,6 +180,116 @@ namespace Defined {
   static_assert(A<short>::B<int*>::y == 2);
 } // namespace Defined
 
+namespace Constrained {
+  template<typename T>
+  struct A {
+    // FIXME expected-note@-1 2{{defined here}}
+    template<typename U, bool V> requires V
+    static constexpr int f(); // expected-note {{declared here}}
+    // FIXME expected-note@-1 {{declared here}}
+
+    template<typename U, bool V> requires V
+    static const int x; // expected-note {{declared here}}
+    // FIXME expected-note@-2 2{{previous template declaration is here}}
+    // FIXME expected-note@-2 {{declared here}}
+
+    template<typename U, bool V> requires V
+    static const int x<U*, V>; // expected-note {{declared here}}
+    // FIXME expected-note@-1 {{partial specialization matches}}
+
+    template<typename U, bool V> requires V
+    struct B; // expected-note {{template is declared here}}
+    // FIXME expected-note@-2 2{{previous template declaration is here}}
+    // FIXME expected-note@-2 {{template is declared here}}
+
+    template<typename U, bool V> requires V
+    struct B<U*, V>; // expected-note {{template is declared here}}
+    // FIXME expected-note@-1 {{partial specialization matches}}
+  };
+
+  template<>
+  template<typename U, bool V> requires V
+  constexpr int A<short>::f() {
+    return A<long>::f<U, V>();
+  }
+  // FIXME expected-error@-3 {{out-of-line definition of 'f' does not match 
any declaration in 'Constrained::A<short>'}}
+
+  template<>
+  template<typename U, bool V> requires V
+  constexpr int A<short>::x = A<long>::x<U, V>;
+  // FIXME expected-error@-2 {{requires clause differs in template 
redeclaration}}
+
+  template<>
+  template<typename U, bool V> requires V
+  constexpr int A<short>::x<U*, V> = A<long>::x<U*, V>;
+  // FIXME expected-note@-1 {{partial specialization matches}}
+
+  template<>
+  template<typename U, bool V> requires V
+  struct A<short>::B<U*, V> {
+    static constexpr int y = A<long>::B<U*, V>::y;
+  };
+    // FIXME expected-note@-3 {{partial specialization matches}}
+
+  template<>
+  template<typename U, bool V> requires V
+  struct A<short>::B {
+    static constexpr int y = A<long>::B<U, V>::y;
+  };
+  // FIXME expected-error@-4 {{requires clause differs in template 
redeclaration}}
+
+  template<>
+  template<typename U, bool V> requires V
+  constexpr int A<long>::f() {
+    return 1;
+  }
+  // FIXME expected-error@-3 {{out-of-line definition of 'f' does not match 
any declaration in 'Constrained::A<long>'}}
+
+  template<>
+  template<typename U, bool V> requires V
+  constexpr int A<long>::x = 1;
+  // FIXME expected-error@-2 {{requires clause differs in template 
redeclaration}}
+
+  template<>
+  template<typename U, bool V> requires V
+  constexpr int A<long>::x<U*, V> = 2;
+
+  template<>
+  template<typename U, bool V> requires V
+  struct A<long>::B {
+    static constexpr int y = 1;
+  };
+  // FIXME expected-error@-4 {{requires clause differs in template 
redeclaration}}
+
+  template<>
+  template<typename U, bool V> requires V
+  struct A<long>::B<U*, V> {
+    static constexpr int y = 2;
+  };
+
+  static_assert(A<int>::f<int, true>() == 0); // expected-error {{static 
assertion expression is not an integral constant expression}}
+                                              // expected-note@-1 {{undefined 
function 'f<int, true>' cannot be used in a constant expression}}
+  static_assert(A<int>::x<int, true> == 0); // expected-error {{static 
assertion expression is not an integral constant expression}}
+                                            // expected-note@-1 {{initializer 
of 'x<int, true>' is unknown}}
+  static_assert(A<int>::x<int*, true> == 0); // expected-error {{static 
assertion expression is not an integral constant expression}}
+                                             // expected-note@-1 {{initializer 
of 'x<int *, true>' is unknown}}
+  static_assert(A<int>::B<int, true>::y == 0); // expected-error {{implicit 
instantiation of undefined template 'Constrained::A<int>::B<int, true>'}}
+  static_assert(A<int>::B<int*, true>::y == 0); // expected-error {{implicit 
instantiation of undefined template 'Constrained::A<int>::B<int *, true>'}}
+
+  static_assert(A<short>::f<int, true>() == 1);
+  // FIXME expected-error@-1 {{static assertion expression is not an integral 
constant expression}}
+  // FIXME expected-note@-2 {{undefined function 'f<int, true>' cannot be used 
in a constant expression}}
+  static_assert(A<short>::x<int, true> == 1);
+  // FIXME expected-error@-1 {{static assertion expression is not an integral 
constant expression}}
+  // FIXME expected-note@-2 {{initializer of 'x<int, true>' is unknown}}
+  static_assert(A<short>::x<int*, true> == 2);
+  // FIXME expected-error@-1 {{ambiguous partial specializations of 'x'}}
+  static_assert(A<short>::B<int, true>::y == 1);
+  // FIXME expected-error@-1 {{implicit instantiation of undefined template 
'Constrained::A<short>::B<int, true>'}}
+  static_assert(A<short>::B<int*, true>::y == 2);
+  // FIXME expected-error@-1 {{ambiguous partial specializations of 'B<int *, 
true>'}}
+} // namespace Constrained
+
 namespace Dependent {
   template<int I>
   struct A {

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

Reply via email to