[clang] [clang][NFC] Refactor expected directives in C++ DRs 400-499 (PR #74311)

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 4 04:22:27 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 51.63 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74311.diff


1 Files Affected:

- (modified) clang/test/CXX/drs/dr4xx.cpp (+421-238) 


``````````diff
diff --git a/clang/test/CXX/drs/dr4xx.cpp b/clang/test/CXX/drs/dr4xx.cpp
index acb3cbfa52e7f..b7df9decdd4b8 100644
--- a/clang/test/CXX/drs/dr4xx.cpp
+++ b/clang/test/CXX/drs/dr4xx.cpp
@@ -1,9 +1,9 @@
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++98 %s -verify=expected,cxx98-14,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++11 %s -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++14 %s -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++20 %s -verify=expected,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++23 %s -verify=expected,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
 
 // FIXME: __SIZE_TYPE__ expands to 'long long' on some targets.
 __extension__ typedef __SIZE_TYPE__ size_t;
@@ -11,36 +11,55 @@ __extension__ typedef __SIZE_TYPE__ size_t;
 namespace std { struct type_info; }
 
 namespace dr400 { // dr400: yes
-  struct A { int a; struct a {}; }; // expected-note 2{{conflicting}} expected-note {{ambiguous}}
-  struct B { int a; struct a {}; }; // expected-note 2{{target}} expected-note {{ambiguous}}
+  struct A { int a; struct a {}; }; // #dr400-A
+  struct B { int a; struct a {}; }; // #dr400-B
   struct C : A, B { using A::a; struct a b; };
-  struct D : A, B { using A::a; using B::a; struct a b; }; // expected-error 2{{conflicts}}
-  struct E : A, B { struct a b; }; // expected-error {{found in multiple base classes}}
+  struct D : A, B { 
+    using A::a;
+    // FIXME: we should issue a single diagnostic
+    using B::a; // #dr400-using-B-a
+    // expected-error@#dr400-using-B-a {{target of using declaration conflicts with declaration already in scope}}
+    //   expected-note@#dr400-B {{target of using declaration}}
+    //   expected-note@#dr400-A {{conflicting declaration}}
+    // expected-error@#dr400-using-B-a {{target of using declaration conflicts with declaration already in scope}}
+    //   expected-note@#dr400-B {{target of using declaration}}
+    //   expected-note@#dr400-A {{conflicting declaration}}
+    struct a b;
+  };
+  struct E : A, B { struct a b; };
+  // expected-error at -1 {{member 'a' found in multiple base classes of different types}}
+  // expected-note@#dr400-A {{member type 'dr400::A::a' found by ambiguous name lookup}}
+  // expected-note@#dr400-B {{member type 'dr400::B::a' found by ambiguous name lookup}}
 }
 
 namespace dr401 { // dr401: 2.8
-  template<class T, class U = typename T::type> class A : public T {}; // expected-error {{protected}} expected-error 2{{private}}
-
+  template<class T, class U = typename T::type> class A : public T {}; // #dr401-A
+  // expected-error@#dr401-A {{'type' is a private member of 'dr401::C'}}
+  //   expected-note@#dr402-friend-A-C {{in instantiation of default argument for 'A<C>' required here}}
+  //   expected-note@#dr402-C-type {{implicitly declared private here}}
+  // expected-error@#dr401-A {{'type' is a protected member of 'dr401::B'}}
+  //   expected-note@#dr402-b {{in instantiation of default argument for 'A<B>' required here}}
+  //   expected-note@#dr402-B-type {{declared protected here}}
+  // expected-error@#dr401-A {{'type' is a private member of 'dr401::D'}}
+  //   expected-note@#dr402-d {{in instantiation of default argument for 'A<D>' required here}}
+  //   expected-note@#dr402-D-type {{implicitly declared private here}}
   class B {
   protected:
-    typedef int type; // expected-note {{protected}}
-#if __cplusplus == 199711L
-    // expected-note at -2 {{protected}}
-#endif
+    typedef int type; // #dr402-B-type
   };
 
   class C {
-    typedef int type; // expected-note {{private}}
-    friend class A<C>; // expected-note {{default argument}}
+    typedef int type; // #dr402-C-type
+    friend class A<C>; // #dr402-friend-A-C
   };
 
   class D {
-    typedef int type; // expected-note {{private}}
+    typedef int type; // #dr402-D-type
     friend class A<D, int>;
   };
 
-  A<B> *b; // expected-note {{default argument}}
-  A<D> *d; // expected-note {{in instantiation of default argument}}
+  A<B> *b; // #dr402-b
+  A<D> *d; // #dr402-d
 
   struct E {
     template<class T, class U = typename T::type> class A : public T {};
@@ -53,14 +72,15 @@ namespace dr401 { // dr401: 2.8
 
   // FIXME: Why do we get different diagnostics in C++11 onwards here? We seem
   // to not treat the default template argument as a SFINAE context in C++98.
-  template<class T, class U = typename T::type> void f(T) {}
-  void g(B b) { f(b); }
-#if __cplusplus < 201103L
-  // expected-error at -3 0-1{{extension}} expected-error at -3 {{protected}} expected-note at -3 {{instantiation}}
-  // expected-note at -3 {{substituting}}
-#else
-  // expected-error at -5 {{no matching}} expected-note at -6 {{protected}}
-#endif
+  template<class T, class U = typename T::type> void f(T) {} // #dr402-f
+  // cxx98-error at -1 {{default template arguments for a function template are a C++11 extension}}
+  // cxx98-error at -2 {{'type' is a protected member of 'dr401::B'}}
+  //   cxx98-note at -3 {{in instantiation of default argument for 'f<B>' required here}}
+  //   cxx98-note@#dr402-f-b {{while substituting deduced template arguments into function template 'f' [with T = B, U = (no value)]}}
+  //   cxx98-note@#dr402-B-type {{declared protected here}}
+  void g(B b) { f(b); } // #dr402-f-b
+  // since-cxx11-error at -1 {{no matching function for call to 'f'}}
+  // since-cxx11-note@#dr402-f {{candidate template ignored: substitution failure [with T = B, U = typename B::type]: 'type' is a protected member of 'dr401::B'}}
 }
 
 namespace dr403 { // dr403: yes
@@ -93,33 +113,45 @@ namespace dr405 { // dr405: yes
 
   struct C {
     int f;
-    void test1(A::S as) { f(as); } // expected-error {{called object type 'int'}}
-    void test2(A::S as) { void f(); f(as); } // expected-error {{too many arguments}} expected-note {{}}
+    void test1(A::S as) { f(as); }
+    // expected-error at -1 {{called object type 'int' is not a function or function pointer}}
+    void test2(A::S as) { void f(); f(as); }
+    // expected-error at -1 {{too many arguments to function call, expected 0, have 1}}
+    // expected-note at -2 {{'f' declared here}}
     void test3(A::S as) { using A::f; f(as); } // ok
     void test4(A::S as) { using B::f; f(as); } // ok
-    void test5(A::S as) { int f; f(as); } // expected-error {{called object type 'int'}}
-    void test6(A::S as) { struct f {}; (void) f(as); } // expected-error {{no matching conversion}} expected-note +{{}}
+    void test5(A::S as) { int f; f(as); }
+    // expected-error at -1 {{called object type 'int' is not a function or function pointer}}
+    void test6(A::S as) { struct f {}; (void) f(as); }
+    // expected-error at -1 {{no matching conversion for functional-style cast from 'A::S' to 'f'}}
+    // expected-note at -2 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'A::S' to 'const f' for 1st argument}}
+    // since-cxx11-note at -3 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'A::S' to 'f' for 1st argument}}
+    // expected-note at -4 {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
   };
 
   namespace D {
     struct S {};
     struct X { void operator()(S); } f;
   }
-  void testD(D::S ds) { f(ds); } // expected-error {{undeclared identifier}}
+  void testD(D::S ds) { f(ds); }
+  // expected-error at -1 {{use of undeclared identifier 'f'}}
 
   namespace E {
     struct S {};
     struct f { f(S); };
   }
-  void testE(E::S es) { f(es); } // expected-error {{undeclared identifier}}
+  void testE(E::S es) { f(es); }
+  // expected-error at -1 {{use of undeclared identifier 'f'}}
 }
 
 namespace dr406 { // dr406: 2.9
   typedef struct {
-    static int n; // expected-error {{static data member 'n' not allowed in anonymous struct}}
+    static int n;
+    // expected-error at -1 {{static data member 'n' not allowed in anonymous struct}}
   } A;
   typedef union {
-    static int n; // expected-error {{static data member 'n' not allowed in anonymous union}}
+    static int n;
+    // expected-error at -1 {{static data member 'n' not allowed in anonymous union}}
   } B;
 }
 
@@ -130,23 +162,28 @@ namespace dr407 { // dr407: 3.8
   void f() {
     struct S *p;
     {
-      typedef struct S S; // expected-note {{here}}
-      struct S *p; // expected-error {{typedef 'S' cannot be referenced with a struct specifier}}
+      typedef struct S S; // #dr407-typedef-S
+      struct S *p;
+      // expected-error at -1 {{typedef 'S' cannot be referenced with a struct specifier}}
+      // expected-note@#dr407-typedef-S {{declared here}}
     }
   }
   struct S {};
 
   namespace UsingDir {
     namespace A {
-      struct S {}; // expected-note {{found}}
+      struct S {}; // #dr407-A-S
     }
     namespace B {
-      typedef int S; // expected-note {{found}}
+      typedef int S; // #dr407-B-S
     }
     namespace C {
       using namespace A;
       using namespace B;
-      struct S s; // expected-error {{ambiguous}}
+      struct S s;
+      // expected-error at -1 {{ambiguous}}
+      // expected-note@#dr407-A-S {{candidate found by name lookup is 'dr407::UsingDir::A::S'}}
+      // expected-note@#dr407-B-S {{candidate found by name lookup is 'dr407::UsingDir::B::S'}}
     }
     namespace D {
       using A::S;
@@ -214,9 +251,7 @@ namespace dr409 { // dr409: yes
     A::B b2;
     A<T>::B b3;
     A<T*>::B b4;
-#if __cplusplus <= 201703L
-    // expected-error at -2 {{implicit 'typename' is a C++20 extension}}
-#endif
+    // cxx98-17-error at -1 {{missing 'typename' prior to dependent type name A<T *>::B; implicit 'typename' is a C++20 extension}}
   };
 }
 
@@ -233,7 +268,7 @@ namespace dr410 { // dr410: no
       template<class T> void i(T);
       friend void i<>(int);
     private:
-      static void z(); // expected-note {{private}}
+      static void z(); // #dr410-z
     };
 
     template<> void h(int) { A::z(); }
@@ -242,7 +277,9 @@ namespace dr410 { // dr410: no
     template<> void i(int) { A::z(); }
   }
   template<> void f(int) { M::A::z(); }
-  void g(int) { M::A::z(); } // expected-error {{private}}
+  void g(int) { M::A::z(); }
+  // expected-error at -1 {{'z' is a private member of 'dr410::M::A'}}
+  // expected-note@#dr410-z {{declared private here}}
 }
 
 // dr412 is in its own file.
@@ -253,16 +290,19 @@ namespace dr413 { // dr413: yes
     int : 17;
     int b;
   };
-  S s = { 1, 2, 3 }; // expected-error {{excess elements}}
+  S s = { 1, 2, 3 };
+  // expected-error at -1 {{excess elements in struct initializer}}
 
   struct E {};
-  struct T { // expected-note {{here}}
+  struct T { // #dr413-T
     int a;
     E e;
     int b;
   };
   T t1 = { 1, {}, 2 };
-  T t2 = { 1, 2 }; // expected-error {{aggregate with no elements requires explicit braces}}
+  T t2 = { 1, 2 };
+  // expected-error at -1 {{initializer for aggregate with no elements requires explicit braces}}
+  // expected-note@#dr413-T {{'dr413::T' declared here}}
 }
 
 namespace dr414 { // dr414: dup 305
@@ -290,10 +330,12 @@ namespace dr416 { // dr416: yes
 
 namespace dr417 { // dr417: no
   struct A;
-  struct dr417::A {}; // expected-warning {{extra qualification}}
+  struct dr417::A {};
+  // expected-warning at -1 {{extra qualification on member 'A'}}
   struct B { struct X; };
   struct C : B {};
-  struct C::X {}; // expected-error {{no struct named 'X' in 'dr417::C'}}
+  struct C::X {};
+  // expected-error at -1 {{no struct named 'X' in 'dr417::C'}}
   struct B::X { struct Y; };
   struct C::X::Y {}; // ok!
   namespace N {
@@ -304,15 +346,20 @@ namespace dr417 { // dr417: no
   }
   // FIXME: This is ill-formed.
   using N::D;
-  struct dr417::D {}; // expected-warning {{extra qualification}}
+  struct dr417::D {};
+  // expected-warning at -1 {{extra qualification on member 'D'}}
   using namespace N;
-  struct dr417::E {}; // expected-warning {{extra qualification}} expected-error {{no struct named 'E'}}
+  struct dr417::E {};
+  // expected-error at -1 {{no struct named 'E' in namespace 'dr417'}}
+  // expected-warning at -2 {{extra qualification on member 'E'}}
   struct N::F {};
   struct G;
   using N::H;
   namespace M {
-    struct dr417::G {}; // expected-error {{namespace 'M' does not enclose}}
-    struct dr417::H {}; // expected-error {{namespace 'M' does not enclose}}
+    struct dr417::G {};
+    // expected-error at -1 {{cannot define or redeclare 'G' here because namespace 'M' does not enclose namespace 'dr417'}}
+    struct dr417::H {};
+    // expected-error at -1 {{cannot define or redeclare 'H' here because namespace 'M' does not enclose namespace 'dr417'}}
   }
 }
 
@@ -326,7 +373,7 @@ void g() { f1(); }
 
 namespace example2 {
 namespace A {
-void f2(int); // #dr418-f2-decl
+void f2(int); // #dr418-f2
 }
 namespace B {
 using A::f2;
@@ -336,8 +383,9 @@ void f2(int = 3);
 }
 void g2() {
   using B::f2;
-  f2(); // expected-error {{no matching function}}
-  // expected-note@#dr418-f2-decl {{requires 1 argument}}
+  f2();
+  // expected-error at -1 {{no matching function for call to 'f2'}}
+  // expected-note@#dr418-f2 {{candidate function not viable: requires 1 argument, but 0 were provided}}
 }
 } // namespace example2
 
@@ -381,7 +429,8 @@ namespace dr420 { // dr420: 9
   void test2(T p) {
     p->template Y<int>::~Y<int>();
     p->~Y<int>();
-    p->template ~Y<int>(); // expected-error {{'template' keyword not permitted in destructor name}}
+    p->template ~Y<int>();
+    // expected-error at -1 {{'template' keyword not permitted in destructor name}}
   }
   template<typename T> struct Y {};
   template void test2(Y<int>*);
@@ -413,17 +462,22 @@ namespace dr420 { // dr420: 9
 
 namespace dr421 { // dr421: yes
   struct X { X(); int n; int &r; };
-  int *p = &X().n; // expected-error-re {{{{taking the address of a temporary|cannot take the address of an rvalue}}}}
+  int *p = &X().n;
+  // cxx98-error at -1 {{taking the address of a temporary object of type 'int'}}
+  // since-cxx11-error at -2 {{cannot take the address of an rvalue of type 'int'}}
   int *q = &X().r;
 }
 
 namespace dr422 { // dr422: yes
   template<typename T, typename U> void f() {
-    typedef T type; // expected-note {{prev}}
-    typedef U type; // expected-error {{redef}}
+    typedef T type; // #dr422-typedef-T
+    typedef U type;
+    // expected-error at -1 {{typedef redefinition with different types ('char' vs 'int')}}
+    // expected-note@#dr422-f-int-char {{in instantiation of function template specialization 'dr422::f<int, char>' requested here}}
+    // expected-note@#dr422-typedef-T {{previous definition is here}}
   }
   template void f<int, int>();
-  template void f<int, char>(); // expected-note {{instantiation}}
+  template void f<int, char>(); // #dr422-f-int-char
 }
 
 namespace dr423 { // dr423: yes
@@ -433,37 +487,46 @@ namespace dr423 { // dr423: yes
 
 namespace dr424 { // dr424: yes
   struct A {
-    typedef int N; // expected-note {{previous}}
-    typedef int N; // expected-error {{redefinition}}
+    typedef int N; // #dr424-N
+    typedef int N;
+    // expected-error at -1 {{redefinition of 'N'}}
+    // expected-note@#dr424-N {{previous definition is here}}
 
     struct X;
-    typedef X X; // expected-note {{previous}}
+    typedef X X; // #dr424-X
     struct X {};
 
     struct X *p;
     struct A::X *q;
     X *r;
 
-    typedef X X; // expected-error {{redefinition}}
+    typedef X X;
+    // expected-error at -1 {{redefinition of 'X'}}
+    // expected-note@#dr424-X {{previous definition is here}}
   };
   struct B {
-    typedef int N;
+    typedef int M;
   };
   struct C : B {
-    typedef int N; // expected-note {{previous}}
-    typedef int N; // expected-error {{redefinition}}
+    typedef int M; // #dr424-M
+    typedef int M;
+    // expected-error at -1 {{redefinition of 'M'}}
+    // expected-note@#dr424-M {{previous definition is here}}
   };
 }
 
 namespace dr425 { // dr425: yes
   struct A { template<typename T> operator T() const; } a;
-  float f = 1.0f * a; // expected-error {{ambiguous}} expected-note 5+{{built-in candidate}}
+  float f = 1.0f * a;
+  // expected-error at -1 {{use of overloaded operator '*' is ambiguous (with operand types 'float' and 'struct A')}}
+  // expected-note at -2 +{{built-in candidate}}
 
   template<typename T> struct is_float;
   template<> struct is_float<float> { typedef void type; };
 
   struct B {
-    template<typename T, typename U = typename is_float<T>::type> operator T() const; // expected-error 0-1{{extension}}
+    template<typename T, typename U = typename is_float<T>::type> operator T() const;
+    // cxx98-error at -1 {{default template arguments for a function template are a C++11 extension}}
   } b;
   float g = 1.0f * b; // ok
 }
@@ -471,28 +534,42 @@ namespace dr425 { // dr425: yes
 namespace dr427 { // dr427: yes
   struct B {};
   struct D : public B {
-    D(B &) = delete; // expected-error 0-1{{extension}} expected-note {{deleted}}
+    D(B &) = delete; // #dr427-D
+    // cxx98-error at -1 {{deleted function definitions are a C++11 extension}}
   };
 
   extern D d1;
   B &b = d1;
   const D &d2 = static_cast<const D&>(b);
   const D &d3 = (const D&)b;
-  const D &d4(b); // expected-error {{deleted}}
+  const D &d4(b);
+  // expected-error at -1 {{conversion function from 'B' to 'const D' invokes a deleted function}}
+  // expected-note@#dr427-D {{'D' has been explicitly marked deleted here}}
 }
 
 namespace dr428 { // dr428: yes
   template<typename T> T make();
-  extern struct X x; // expected-note 5{{forward declaration}}
+  extern struct X x; // #dr428-X
   void f() {
-    throw void(); // expected-error {{cannot throw}}
+    throw void();
+    // expected-error at -1 {{cannot throw}}
     throw make<void*>();
     throw make<const volatile void*>();
-    throw x; // expected-error {{cannot throw}}
-    throw make<X&>(); // expected-error {{cannot throw}}
-    throw make<X*>(); // expected-error {{cannot throw}}
-    throw make<const volatile X&>(); // expected-error {{cannot throw}}
-    throw make<const volatile X*>(); // expected-error {{cannot throw}}
+    throw x;
+    // expected-error at -1 {{cannot throw}}
+    // expected-note@#dr428-X {{forward declaration of 'dr428::X'}}
+    throw make<X&>();
+    // expected-error at -1 {{cannot throw}}
+    // expected-note@#dr428-X {{forward declaration of 'dr428::X'}}
+    throw make<X*>();
+    // expected-error at -1 {{cannot throw}}
+    // expected-note@#dr428-X {{forward declaration of 'dr428::X'}}
+    throw make<const volatile X&>();
+    // expected-error at -1 {{cannot throw}}
+    // expected-note@#dr428-X {{forward declaration of 'dr428::X'}}
+    throw make<const volatile X*>();
+    // expected-error at -1 {{cannot throw}}
+    // expected-note@#dr428-X {{forward declaration of 'dr428::X'}}
   }
 }
 
@@ -500,12 +577,10 @@ namespace dr429 { // dr429: 2.8 c++11
   // FIXME: This rule is obviously intended to apply to C++98 as well.
   struct A {
     static void *operator new(size_t, size_t);
-    static void operator delete(void*, size_t);
+  ...
[truncated]

``````````

</details>


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


More information about the cfe-commits mailing list