[clang] [clang][NFC] Refactor expected directives in C++ DRs 700-1999 (PR #74767)

via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 7 13:42:47 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Vlad Serebrennikov (Endilll)

<details>
<summary>Changes</summary>

This patch continues the work started with ea5b1ef016d020c37f903d6c7d4f623be975dab8. See that commit and its corresponding PR for details.

---

Patch is 210.38 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74767.diff


14 Files Affected:

- (modified) clang/test/CXX/drs/dr10xx.cpp (+28-17) 
- (modified) clang/test/CXX/drs/dr11xx.cpp (+17-15) 
- (modified) clang/test/CXX/drs/dr12xx.cpp (+47-32) 
- (modified) clang/test/CXX/drs/dr13xx.cpp (+282-149) 
- (modified) clang/test/CXX/drs/dr14xx.cpp (+256-126) 
- (modified) clang/test/CXX/drs/dr15xx.cpp (+274-132) 
- (modified) clang/test/CXX/drs/dr16xx.cpp (+245-151) 
- (modified) clang/test/CXX/drs/dr17xx.cpp (+32-20) 
- (modified) clang/test/CXX/drs/dr18xx.cpp (+64-46) 
- (modified) clang/test/CXX/drs/dr19xx.cpp (+73-47) 
- (modified) clang/test/CXX/drs/dr412.cpp (+16-7) 
- (modified) clang/test/CXX/drs/dr7xx.cpp (+141-69) 
- (modified) clang/test/CXX/drs/dr8xx.cpp (+17-20) 
- (modified) clang/test/CXX/drs/dr9xx.cpp (+38-28) 


``````````diff
diff --git a/clang/test/CXX/drs/dr10xx.cpp b/clang/test/CXX/drs/dr10xx.cpp
index f30ed1cb3e496..77c59078414c6 100644
--- a/clang/test/CXX/drs/dr10xx.cpp
+++ b/clang/test/CXX/drs/dr10xx.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
 
 namespace std {
   __extension__ typedef __SIZE_TYPE__ size_t;
@@ -18,30 +18,40 @@ namespace dr1004 { // dr1004: 5
   template<typename> struct A {};
   template<typename> struct B1 {};
   template<template<typename> class> struct B2 {};
-  template<typename X> void f(); // expected-note {{[with X = dr1004::A<int>]}}
-  template<template<typename> class X> void f(); // expected-note {{[with X = dr1004::A]}}
-  template<template<typename> class X> void g(); // expected-note {{[with X = dr1004::A]}}
-  template<typename X> void g(); // expected-note {{[with X = dr1004::A<int>]}}
+  template<typename X> void f(); // #dr1004-f-1
+  template<template<typename> class X> void f(); // #dr1004-f-2
+  template<template<typename> class X> void g(); // #dr1004-g-1
+  template<typename X> void g(); // #dr1004-g-2
   struct C : A<int> {
     B1<A> b1a;
     B2<A> b2a;
     void h() {
-      f<A>(); // expected-error {{ambiguous}}
-      g<A>(); // expected-error {{ambiguous}}
+      f<A>();
+      // expected-error at -1 {{call to 'f' is ambiguous}}
+      //   expected-note@#dr1004-f-1 {{candidate function [with X = dr1004::A<int>]}}
+      //   expected-note@#dr1004-f-2 {{candidate function [with X = dr1004::A]}}
+      g<A>();
+      // expected-error at -1 {{call to 'g' is ambiguous}}
+      //   expected-note@#dr1004-g-1 {{candidate function [with X = dr1004::A]}}
+      //   expected-note@#dr1004-g-2 {{candidate function [with X = dr1004::A<int>]}}
     }
   };
 
   // This example (from the standard) is actually ill-formed, because
   // name lookup of "T::template A" names the constructor.
-  template<class T, template<class> class U = T::template A> struct Third { }; // expected-error {{is a constructor name}}
-  Third<A<int> > t; // expected-note {{in instantiation of default argument}}
+  template<class T, template<class> class U = T::template A> struct Third { };
+  // expected-error at -1 {{is a constructor name}}
+  //   expected-note@#dr1004-t {{in instantiation of default argument}}
+  Third<A<int> > t; // #dr1004-t
 }
 
 namespace dr1042 { // dr1042: 3.5
 #if __cplusplus >= 201402L
   // C++14 added an attribute that we can test the semantics of.
-  using foo [[deprecated]] = int; // expected-note {{'foo' has been explicitly marked deprecated here}}
-  foo f = 12; // expected-warning {{'foo' is deprecated}}
+  using foo [[deprecated]] = int; // #dr1042-using
+  foo f = 12;
+  // since-cxx14-warning at -1 {{'foo' is deprecated}}
+  //   since-cxx14-note@#dr1042-using {{'foo' has been explicitly marked deprecated here}}
 #elif __cplusplus >= 201103L
   // C++11 did not have any attributes that could be applied to an alias
   // declaration, so the best we can test is that we accept an empty attribute
@@ -76,7 +86,8 @@ namespace dr1054 { // dr1054: no
     // which copy-initializes a temporary from 'a'. Therefore this is
     // ill-formed because A does not have a volatile copy constructor.
     // (We might want to track this aspect under dr1383 instead?)
-    a; // expected-warning {{assign into a variable to force a volatile load}}
+    a;
+    // expected-warning at -1 {{expression result unused; assign into a variable to force a volatile load}}
   }
 }
 
diff --git a/clang/test/CXX/drs/dr11xx.cpp b/clang/test/CXX/drs/dr11xx.cpp
index 2e35535a18c4a..86e726ae8c741 100644
--- a/clang/test/CXX/drs/dr11xx.cpp
+++ b/clang/test/CXX/drs/dr11xx.cpp
@@ -1,30 +1,30 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2a %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
 
 namespace dr1111 { // dr1111: 3.2
 namespace example1 {
-template <typename> struct set;
+template <typename> struct set; // #dr1111-struct-set
 
 struct X {
-  template <typename T> void set(const T &value);
+  template <typename T> void set(const T &value); // #dr1111-func-set
 };
 void foo() {
   X x;
-#pragma clang diagnostic push
-#if __cplusplus < 201103L
-#pragma clang diagnostic ignored "-Wambiguous-member-template"
-#endif
+  // FIXME: should we backport C++11 behavior?
   x.set<double>(3.2);
-#pragma clang diagnostic pop
+  // cxx98-error at -1 {{lookup of 'set' in member access expression is ambiguous; using member of 'X'}}
+  //   cxx98-note@#dr1111-func-set {{lookup in the object type 'X' refers here}}
+  //   cxx98-note@#dr1111-struct-set {{lookup from the current scope refers here}}
 }
 
 struct Y {};
 void bar() {
   Y y;
-  y.set<double>(3.2); // expected-error {{no member named 'set' in 'dr1111::example1::Y'}}
+  y.set<double>(3.2);
+  // expected-error at -1 {{no member named 'set' in 'dr1111::example1::Y'}}
 }
 } // namespace example1
 
@@ -46,8 +46,10 @@ void baz() {
 
 namespace dr1113 { // dr1113: partial
   namespace named {
-    extern int a; // expected-note {{previous}}
-    static int a; // expected-error {{static declaration of 'a' follows non-static}}
+    extern int a; // #dr1113-a
+    static int a;
+    // expected-error at -1 {{static declaration of 'a' follows non-static}}
+    //   expected-note@#dr1113-a {{previous declaration is here}}
   }
   namespace {
     extern int a;
diff --git a/clang/test/CXX/drs/dr12xx.cpp b/clang/test/CXX/drs/dr12xx.cpp
index 339712be45b38..adf7f56711c45 100644
--- a/clang/test/CXX/drs/dr12xx.cpp
+++ b/clang/test/CXX/drs/dr12xx.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-14,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx98-14,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors
 
 // dr1200: na
 
@@ -40,28 +40,33 @@ struct S {
   S* operator()();
   int N;
   int M;
-#if __cplusplus > 202002L
+#if __cplusplus >= 202302L
   template <typename T>
   static constexpr auto V = 0;
   void f(char);
   void f(int);
   void mem(S s) {
-    auto(s)()->M; //expected-warning {{expression result unused}}
-    auto(s)()->V<int>; //expected-warning {{expression result unused}}
+    auto(s)()->M;
+    // since-cxx23-warning at -1 {{expression result unused}}
+    auto(s)()->V<int>;
+    // since-cxx23-warning at -1 {{expression result unused}}
     auto(s)()->f(0);
   }
 #endif
 };
 void f(S s) {
   {
-#if __cplusplus > 202002L
-    auto(s)()->N; //expected-warning {{expression result unused}}
+#if __cplusplus >= 202302L
+    auto(s)()->N;
+    //since-cxx23-warning at -1 {{expression result unused}}
 #endif
     auto(s)()->M;
   }
   {
-    S(s)()->N; //expected-warning {{expression result unused}}
-    S(s)()->M; //expected-warning {{expression result unused}}
+    S(s)()->N;
+    // since-cxx11-warning at -1 {{expression result unused}}
+    S(s)()->M;
+    // since-cxx11-warning at -1 {{expression result unused}}
   }
 }
 
@@ -74,7 +79,8 @@ void g() {
     A a(B ()->C);
     A b(auto ()->C);
     static_assert(sizeof(B ()->C[1] == sizeof(int)), "");
-    sizeof(auto () -> C[1]); // expected-error{{function cannot return array type 'C[1]'}}
+    sizeof(auto () -> C[1]);
+    // since-cxx11-error at -1 {{function cannot return array type 'C[1]' (aka 'dr1223::BB[1]')}}
 }
 
 }
@@ -82,15 +88,18 @@ void g() {
 
 #if __cplusplus >= 201103L
 namespace dr1227 { // dr1227: 3.0
-template <class T> struct A { using X = typename T::X; }; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
+template <class T> struct A { using X = typename T::X; };
+// since-cxx11-error at -1 {{type 'int' cannot be used prior to '::' because it has no members}}
+//   since-cxx11-note@#dr1227-g {{in instantiation of template class 'dr1227::A<int>' requested here}}
+//   since-cxx11-note@#dr1227-g-int {{while substituting explicitly-specified template arguments into function template 'g'}}
 template <class T> typename T::X f(typename A<T>::X);
 template <class T> void f(...) { }
-template <class T> auto g(typename A<T>::X) -> typename T::X; // expected-note {{in instantiation of template class 'dr1227::A<int>' requested here}}
+template <class T> auto g(typename A<T>::X) -> typename T::X; // #dr1227-g
 template <class T> void g(...) { }
 
 void h() {
   f<int>(0); // OK, substituting return type causes deduction to fail
-  g<int>(0); // expected-note {{while substituting explicitly-specified template arguments into function template 'g'}}
+  g<int>(0); // #dr1227-g-int
 }
 }
 #endif
@@ -109,15 +118,21 @@ struct Derived : Base {
 
 namespace dr1265 { // dr1265: 5
 #if __cplusplus >= 201103L
-  auto a = 0, b() -> int; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
-  auto b() -> int, d = 0; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
-  auto e() -> int, f() -> int; // expected-error {{declaration with trailing return type must be the only declaration in its group}}
+  auto a = 0, b() -> int;
+  // since-cxx11-error at -1 {{declaration with trailing return type must be the only declaration in its group}}
+  auto b() -> int, d = 0;
+  // since-cxx11-error at -1 {{declaration with trailing return type must be the only declaration in its group}}
+  auto e() -> int, f() -> int;
+  // since-cxx11-error at -1 {{declaration with trailing return type must be the only declaration in its group}}
 #endif
 
 #if __cplusplus >= 201402L
-  auto g(), h = 0; // expected-error {{function with deduced return type must be the only declaration in its group}}
-  auto i = 0, j(); // expected-error {{function with deduced return type must be the only declaration in its group}}
-  auto k(), l(); // expected-error {{function with deduced return type must be the only declaration in its group}}
+  auto g(), h = 0;
+  // since-cxx14-error at -1 {{function with deduced return type must be the only declaration in its group}}
+  auto i = 0, j();
+  // since-cxx14-error at -1 {{function with deduced return type must be the only declaration in its group}}
+  auto k(), l();
+  // since-cxx14-error at -1 {{function with deduced return type must be the only declaration in its group}}
 #endif
 }
 
@@ -130,16 +145,16 @@ namespace dr1295 { // dr1295: 4
 
   X x = {1};
 
-  unsigned const &r1 = static_cast<X &&>(x).bitfield; // expected-error 0-1{{C++11}}
-  unsigned const &r2 = static_cast<unsigned &&>(x.bitfield); // expected-error 0-1{{C++11}}
+  unsigned const &r1 = static_cast<X &&>(x).bitfield;
+  // cxx98-error at -1 {{rvalue references are a C++11 extension}}
+  unsigned const &r2 = static_cast<unsigned &&>(x.bitfield);
+  // cxx98-error at -1 {{rvalue references are a C++11 extension}}
 
-  template<unsigned &r> struct Y {};
-  Y<x.bitfield> y;
-#if __cplusplus <= 201402L
-  // expected-error at -2 {{does not refer to any declaration}} expected-note at -3 {{here}}
-#else
-  // expected-error at -4 {{refers to subobject}}
-#endif
+  template<unsigned &r> struct Y {}; // #dr1295-Y
+  Y<x.bitfield> y; // #dr1295-y
+  // cxx98-14-error at -1 {{non-type template argument does not refer to any declaration}}
+  //   cxx98-14-note@#dr1295-Y {{template parameter is declared here}}
+  // since-cxx17-error@#dr1295-y {{non-type template argument refers to subobject 'x.bitfield'}}
 
 #if __cplusplus >= 201103L
   const unsigned other = 0;
diff --git a/clang/test/CXX/drs/dr13xx.cpp b/clang/test/CXX/drs/dr13xx.cpp
index abee100961602..359c04b3e0f3d 100644
--- a/clang/test/CXX/drs/dr13xx.cpp
+++ b/clang/test/CXX/drs/dr13xx.cpp
@@ -1,7 +1,10 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-14,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-17,cxx11-14,cxx98-14,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx11-17,cxx11-14,since-cxx14,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,cxx11-17,since-cxx14,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
 
 __extension__ typedef __SIZE_TYPE__ size_t;
 
@@ -15,10 +18,12 @@ namespace std {
 
 #if __cplusplus >= 201103L
 namespace dr1305 { // dr1305: 3.0
-struct Incomplete; // expected-note {{forward declaration of 'dr1305::Incomplete'}}
+struct Incomplete; // #dr1305-Incomplete
 struct Complete {};
 
-int incomplete = alignof(Incomplete(&)[]); // expected-error {{invalid application of 'alignof' to an incomplete type 'Incomplete'}}
+int incomplete = alignof(Incomplete(&)[]);
+// since-cxx11-error at -1 {{invalid application of 'alignof' to an incomplete type 'Incomplete'}}
+//   since-cxx11-note@#dr1305-Incomplete {{forward declaration of 'dr1305::Incomplete'}}
 int complete = alignof(Complete(&)[]);
 }
 #endif
@@ -36,9 +41,11 @@ void caller() {
 } // namespace dr1307
 
 namespace dr1310 { // dr1310: 5
-  struct S {} * sp = new S::S; // expected-error {{qualified reference to 'S' is a constructor name}}
+  struct S {} * sp = new S::S;
+  // expected-error at -1 {{qualified reference to 'S' is a constructor name rather than a type in this context}}
   void f() {
-    S::S(a); // expected-error {{qualified reference to 'S' is a constructor name}}
+    S::S(a);
+    // expected-error at -1 {{qualified reference to 'S' is a constructor name rather than a type in this context}}
   }
   struct T { int n; typedef int U; typedef T V; };
   int k = T().T::T::n;
@@ -64,39 +71,67 @@ namespace dr1310 { // dr1310: 5
   template<typename T> struct W : WBase<T> { typedef int X; int n; };
 
   void w_test() {
-    W<int>::W w1a; // expected-error {{qualified reference to 'W' is a constructor name}}
+    W<int>::W w1a;
+    // expected-error at -1 {{qualified reference to 'W' is a constructor name rather than a type in this context}}
     W<int>::W::X w1ax;
-    W<int>::W<int> w1b; // expected-error {{qualified reference to 'W' is a constructor name}}
+    W<int>::W<int> w1b;
+    // expected-error at -1 {{qualified reference to 'W' is a constructor name rather than a template name in this context}}
     W<int>::W<int>::X w1bx;
-    typename W<int>::W w2a; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
-    typename W<int>::W::X w2ax; // expected-error 0-1{{outside of a template}}
-    typename W<int>::W<int> w2b; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
-    typename W<int>::W<int>::X w2bx; // expected-error 0-1{{outside of a template}}
-    W<int>::template W<int> w3; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
-    W<int>::template W<int>::X w3x; // expected-error 0-1{{outside of a template}}
-    typename W<int>::template W<int> w4; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-2{{outside of a template}}
-    typename W<int>::template W<int>::X w4x; // expected-error 0-2{{outside of a template}}
-
-    TT<W<int>::W> tt1; // expected-error {{qualified reference to 'W' is a constructor name}}
-    TTy<W<int>::W> tt1a; // expected-error {{qualified reference to 'W' is a constructor name}}
-    TT<W<int>::template W> tt2; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}
+    typename W<int>::W w2a;
+    // expected-error at -1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a type in this context, despite preceding 'typename' keyword}}
+    // cxx98-error at -2 {{'typename' occurs outside of a template}}
+    typename W<int>::W::X w2ax;
+    // cxx98-error at -1 {{'typename' occurs outside of a template}}
+    typename W<int>::W<int> w2b;
+    // expected-error at -1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'typename' keyword}}
+    // cxx98-error at -2 {{'typename' occurs outside of a template}}
+    typename W<int>::W<int>::X w2bx;
+    // cxx98-error at -1 {{'typename' occurs outside of a template}}
+    W<int>::template W<int> w3;
+    // expected-error at -1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}}
+    // cxx98-error at -2 {{'template' keyword outside of a template}}
+    W<int>::template W<int>::X w3x;
+    // cxx98-error at -1 {{'template' keyword outside of a template}}
+    typename W<int>::template W<int> w4;
+    // expected-error at -1 {{ISO C++ specifies that qualified reference to 'W' i...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/74767


More information about the cfe-commits mailing list