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 47.59 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74373.diff 1 Files Affected: - (modified) clang/test/CXX/drs/dr5xx.cpp (+361-234) ``````````diff diff --git a/clang/test/CXX/drs/dr5xx.cpp b/clang/test/CXX/drs/dr5xx.cpp index 204d07f04f4e5..21a6646d4abcf 100644 --- a/clang/test/CXX/drs/dr5xx.cpp +++ b/clang/test/CXX/drs/dr5xx.cpp @@ -1,20 +1,21 @@ -// 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-11,cxx98-14,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-11,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx23,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors // FIXME: This is included to avoid a diagnostic with no source location // pointing at the implicit operator new. We can't match such a diagnostic // with -verify. __extension__ typedef __SIZE_TYPE__ size_t; -void *operator new(size_t); // expected-error 0-1{{missing exception spec}} expected-note{{candidate}} +void *operator new(size_t); // #dr5xx-global-operator-new +// cxx98-error@-1 {{'operator new' is missing exception specification 'throw(std::bad_alloc)'}} #if __cplusplus > 201402L namespace std { enum class align_val_t : size_t {}; } -void *operator new(size_t, std::align_val_t); // expected-note{{candidate}} +void *operator new(size_t, std::align_val_t); // #dr5xx-global-operator-new-aligned #endif namespace dr500 { // dr500: dup 372 @@ -33,7 +34,8 @@ namespace dr501 { // dr501: yes struct A { friend void f() {} void g() { - void (*p)() = &f; // expected-error {{undeclared identifier}} + void (*p)() = &f; + // expected-error@-1 {{use of undeclared identifier 'f'}} } }; } @@ -45,7 +47,8 @@ namespace dr502 { // dr502: yes void q1() { f(e); } void q2() { Q arr[sizeof(E)]; f(arr); } void q3() { Q arr[e]; f(arr); } - void sanity() { Q arr[1]; f(arr); } // expected-error {{undeclared identifier 'f'}} + void sanity() { Q arr[1]; f(arr); } + // expected-error@-1 {{use of undeclared identifier 'f'}} }; int f(A<int>::E); template<int N> int f(Q (&)[N]); @@ -53,14 +56,22 @@ namespace dr502 { // dr502: yes } namespace dr505 { // dr505: yes - const char *exts = "\e\(\{\[\%"; // expected-error 5{{use of non-standard escape}} - const char *unknown = "\Q"; // expected-error {{unknown escape sequence}} + const char *exts = "\e\(\{\[\%"; + // expected-error@-1 {{use of non-standard escape character '\e'}} + // expected-error@-2 {{use of non-standard escape character '\('}} + // expected-error@-3 {{use of non-standard escape character '\{'}} + // expected-error@-4 {{use of non-standard escape character '\['}} + // expected-error@-5 {{use of non-standard escape character '\%'}} + const char *unknown = "\Q"; + // expected-error@-1 {{unknown escape sequence '\Q'}} } namespace dr506 { // dr506: yes struct NonPod { ~NonPod(); }; void f(...); - void g(NonPod np) { f(np); } // expected-error {{cannot pass}} + void g(NonPod np) { f(np); } + // cxx98-error@-1 {{cannot pass object of non-POD type 'NonPod' through variadic function; call will abort at runtime}} + // since-cxx11-error@-2 {{cannot pass object of non-trivial type 'NonPod' through variadic function; call will abort at runtime}} } // FIXME: Add tests here once DR260 is resolved. @@ -71,15 +82,13 @@ namespace dr506 { // dr506: yes // dr510: na namespace dr512 { // dr512: yes - struct A { - A(int); + struct A { // #dr512-A + A(int); // #dr512-A-ctor }; union U { A a; }; -#if __cplusplus < 201103L - // expected-error@-2 {{has a non-trivial default constructor}} - // expected-note@-6 {{no default constructor}} - // expected-note@-6 {{suppressed by user-declared constructor}} -#endif + // cxx98-error@-1 {{union member 'a' has a non-trivial default constructor}} + // cxx98-note@#dr512-A {{because type 'dr512::A' has no default constructor}} + // cxx98-note@#dr512-A-ctor {{implicit default constructor suppressed by user-declared constructor}} } // dr513: na @@ -101,9 +110,7 @@ namespace dr515 { // dr515: sup 1017 struct A { int a; }; struct B { void f() { int k = sizeof(A::a); } }; -#if __cplusplus < 201103L - // expected-error@-2 {{invalid use of non-static data member}} -#endif + // cxx98-error@-1 {{invalid use of non-static data member 'a'}} } // dr516: na @@ -111,7 +118,8 @@ namespace dr515 { // dr515: sup 1017 namespace dr517 { // dr517: no // This is NDR, but we should diagnose it anyway. template<typename T> struct S {}; - template<typename T> int v = 0; // expected-error 0-1{{extension}} + template<typename T> int v = 0; + // cxx98-11-error@-1 {{variable templates are a C++14 extension}} template struct S<int*>; template int v<int*>; @@ -121,18 +129,16 @@ namespace dr517 { // dr517: no // FIXME: These are both ill-formed. template<typename T> struct S<T*> {}; - template<typename T> int v<T*> = 0; // expected-error 0-1{{extension}} + template<typename T> int v<T*> = 0; // FIXME: These are both ill-formed. template<typename T> struct S<T&> {}; - template<typename T> int v<T&> = 0; // expected-error 0-1{{extension}} + template<typename T> int v<T&> = 0; } namespace dr518 { // dr518: yes c++11 enum E { e, }; -#if __cplusplus < 201103L - // expected-error@-2 {{C++11 extension}} -#endif + // cxx98-error@-1 {{commas at the end of enumerator lists are a C++11 extension}} } namespace dr519 { // dr519: yes @@ -156,7 +162,7 @@ namespace dr522 { // dr522: yes template<typename T> void b2(volatile T * const *); template<typename T> void b2(volatile T * const S::*); template<typename T> void b2(volatile T * const S::* const *); - template<typename T> void b2a(volatile T *S::* const *); // expected-note {{candidate template ignored: deduced type 'volatile int *dr522::S::*const *' of 1st parameter does not match adjusted type 'int *dr522::S::**' of argument}} + template<typename T> void b2a(volatile T *S::* const *); // #dr522-b2a template<typename T> struct Base {}; struct Derived : Base<int> {}; @@ -174,22 +180,27 @@ namespace dr522 { // dr522: yes b2(pm); b2(a); b2(am); - b2a(am); // expected-error {{no matching function}} + b2a(am); + // expected-error@-1 {{no matching function for call to 'b2a'}} + // expected-note@#dr522-b2a {{candidate template ignored: deduced type 'volatile int *dr522::S::*const *' of 1st parameter does not match adjusted type 'int *dr522::S::**' of argument}} b3(d); b3(cd); } } namespace dr524 { // dr524: yes - template<typename T> void f(T a, T b) { operator+(a, b); } // expected-error {{call}} + template<typename T> void f(T a, T b) { operator+(a, b); } + // expected-error@-1 {{call to function 'operator+' that is neither visible in the template definition nor found by argument-dependent lookup}} + // expected-note@#dr524-f-N-S {{in instantiation of function template specialization 'dr524::f<dr524::N::S>' requested here}} + // expected-note@#dr524-operator-plus {{'operator+' should be declared prior to the call site or in namespace 'dr524::N'}} struct S {}; void operator+(S, S); template void f(S, S); namespace N { struct S {}; } - void operator+(N::S, N::S); // expected-note {{should be declared}} - template void f(N::S, N::S); // expected-note {{instantiation}} + void operator+(N::S, N::S); // #dr524-operator-plus + template void f(N::S, N::S); // #dr524-f-N-S } namespace dr525 { // dr525: yes @@ -202,9 +213,11 @@ namespace dr525 { // dr525: yes } } namespace after { - template <class T> struct D { typename T::error e; }; // expected-error {{prior to '::'}} + template <class T> struct D { typename T::error e; }; + // expected-error@-1 {{type 'double' cannot be used prior to '::' because it has no members}} + // expected-note@#dr525-ppp {{in instantiation of template class 'dr525::after::D<double>' requested here}} void g(D<double> *ppp) { - delete ppp; // expected-note {{instantiation of}} + delete ppp; // #dr525-ppp } } } @@ -212,30 +225,36 @@ namespace dr525 { // dr525: yes namespace dr526 { // dr526: yes template<int> struct S {}; template<int N> void f1(S<N> s); - template<int N> void f2(S<(N)> s); // expected-note {{couldn't infer}} - template<int N> void f3(S<+N> s); // expected-note {{couldn't infer}} + template<int N> void f2(S<(N)> s); // #dr526-f2 + template<int N> void f3(S<+N> s); // #dr526-f3 template<int N> void g1(int (&)[N]); - template<int N> void g2(int (&)[(N)]); // expected-note {{couldn't infer}} - template<int N> void g3(int (&)[+N]); // expected-note {{couldn't infer}} + template<int N> void g2(int (&)[(N)]); // #dr526-g2 + template<int N> void g3(int (&)[+N]); // #dr526-g3 void test(int (&a)[3], S<3> s) { f1(s); - f2(s); // expected-error {{no matching}} - f3(s); // expected-error {{no matching}} + f2(s); + // expected-error@-1 {{no matching function for call to 'f2'}} + // expected-note@#dr526-f2 {{candidate template ignored: couldn't infer template argument 'N'}} + f3(s); + // expected-error@-1 {{no matching function for call to 'f3'}} + // expected-note@#dr526-f3 {{candidate template ignored: couldn't infer template argument 'N'}} g1(a); - g2(a); // expected-error {{no matching}} - g3(a); // expected-error {{no matching}} + g2(a); + // expected-error@-1 {{no matching function for call to 'g2'}} + // expected-note@#dr526-g2 {{candidate template ignored: couldn't infer template argument 'N'}} + g3(a); + // expected-error@-1 {{no matching function for call to 'g3'}} + // expected-note@#dr526-g3 {{candidate template ignored: couldn't infer template argument 'N'}} } template<int N> struct X { typedef int type; X<N>::type v1; X<(N)>::type v2; + // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name X<(N)>::type; implicit 'typename' is a C++20 extension}} X<+N>::type v3; -#if __cplusplus <= 201703L - // expected-error@-3 {{implicit 'typename' is a C++20 extension}} - // expected-error@-3 {{implicit 'typename' is a C++20 extension}} -#endif + // cxx98-17-error@-1 {{missing 'typename' prior to dependent type name X<+N>::type; implicit 'typename' is a C++20 extension}} }; } @@ -307,32 +326,48 @@ namespace dr531 { // dr531: partial void f(T) { T::error; } template<typename U> void g(T, U) { T::error; } struct B { typename T::error error; }; - template<typename U> struct C { typename T::error error; }; // expected-note {{here}} + template<typename U> struct C { typename T::error error; }; // #dr531-C static T n; }; template<typename T> T A<T>::n = T::error; - void A<int>::f(int) {} // expected-error {{requires 'template<>'}} - template<typename U> void A<int>::g(int, U) {} // expected-error {{should be empty}} - struct A<int>::B {}; // expected-error {{requires 'template<>'}} - template<typename U> struct A<int>::C {}; // expected-error {{should be empty}} expected-error {{different kind of symbol}} - int A<int>::n = 0; // expected-error {{requires 'template<>'}} - - template<> struct A<char> { // expected-note 2{{here}} + void A<int>::f(int) {} + // expected-error@-1 {{template specialization requires 'template<>'}} + template<typename U> void A<int>::g(int, U) {} + // expected-error@-1 {{template parameter list matching the non-templated nested type 'dr531::bad::A<int>' should be empty}} + struct A<int>::B {}; + // expected-error@-1 {{template specialization requires 'template<>'}} + template<typename U> struct A<int>::C {}; + // expected-error@-1 {{template parameter list matching the non-templated nested type 'dr531::bad::A<int>' should be empty}} + // expected-error@-2 {{redefinition of 'C' as different kind of symbol}} + // expected-note@#dr531-C {{previous definition is here}} + int A<int>::n = 0; + // expected-error@-1 {{template specialization requires 'template<>'}} + + template<> struct A<char> { // #dr531-A-char void f(char); template<typename U> void g(char, U); - struct B; // expected-note {{here}} + struct B; // #dr531-B template<typename U> struct C; static char n; }; - template<> void A<char>::f(char) {} // expected-error {{no function template matches}} + template<> void A<char>::f(char) {} + // expected-error@-1 {{no function template matches function template specialization 'f'}} // FIXME: This is ill-formed; -pedantic-errors should reject. - template<> template<typename U> void A<char>::g(char, U) {} // expected-warning {{extraneous template parameter list}} - template<> struct A<char>::B {}; // expected-error {{extraneous 'template<>'}} expected-error {{does not specialize}} + template<> template<typename U> void A<char>::g(char, U) {} + // expected-warning@-1 {{extraneous template parameter list in template specialization}} + // expected-note@#dr531-A-char {{'template<>' header not required for explicitly-specialized class 'dr531::bad::A<char>' declared here}} + template<> struct A<char>::B {}; + // expected-error@-1 {{extraneous 'template<>' in declaration of struct 'B'}} + // expected-error@-2 {{specialization of member 'dr531::bad::A<char>::B' does not specialize an instantiated member}} + // expected-note@#dr531-B {{attempt to specialize declaration here}} // FIXME: This is ill-formed; -pedantic-errors should reject. - template<> template<typename U> struct A<char>::C {}; // expected-warning {{extraneous template parameter list}} - template<> char A<char>::n = 0; // expected-error {{extraneous 'template<>'}} + template<> template<typename U> struct A<char>::C {}; + // expected-warning@-1 {{extraneous template parameter list in template specialization}} + // expected-note@#dr531-A-char {{'template<>' header not required for explicitly-specialized class 'dr531::bad::A<char>' declared here}} + template<> char A<char>::n = 0; + // expected-error@-1 {{extraneous 'template<>' in declaration of variable 'n'}} } namespace nested { @@ -346,10 +381,12 @@ namespace dr531 { // dr531: partial template<typename V> void i(); }; template<> template<typename U> void A<int>::B<U>::f() {} - template<typename U> void A<int>::B<U>::g() {} // expected-error {{should be empty}} + template<typename U> void A<int>::B<U>::g() {} + // expected-error@-1 {{template parameter list matching the non-templated nested type 'dr531::nested::A<int>' should be empty ('template<>')}} template<> template<typename U> template<typename V> void A<int>::B<U>::h() {} - template<typename U> template<typename V> void A<int>::B<U>::i() {} // expected-error {{should be empty}} + template<typename U> template<typename V> void A<int>::B<U>::i() {} + // expected-error@-1 {{template parameter list matching the non-templated nested type 'dr531::nested::A<int>' should be empty ('template<>')}} #if __cplusplus <= 201703L // FIXME: All of those declarations shouldn't crash in C++20 mode. @@ -357,8 +394,10 @@ namespace dr531 { // dr531: partial template<> template<> template<typename V> void A<int>::B<int>::h() {} template<> template<> template<> void A<int>::B<int>::h<int>() {} - template<> void A<int>::B<char>::f() {} // expected-error {{requires 'template<>'}} - template<> template<typename V> void A<int>::B<char>::h() {} // expected-error {{should be empty}} + template<> void A<int>::B<char>::f() {} + // cxx98-17-error@-1 {{template specialization requires 'template<>'}} + template<> template<typename V> void A<int>::B<char>::h() {} + // cxx98-17-error@-1 {{template parameter list matching the non-templated nested type 'dr531::nested::A<int>::B<char>' should be empty ('template<>')}} #endif } } @@ -384,7 +423,8 @@ namespace dr532 { // dr532: 3.5 namespace dr534 { // dr534: 2.9 struct S {}; template<typename T> void operator+(S, T); - template<typename T> void operator+<T*>(S, T*) {} // expected-error {{function template partial spec}} + template<typename T> void operator+<T*>(S, T*) {} + // expected-error@-1 {{function template partial specialization is not allowed}} } namespace dr535 { // dr535: yes @@ -423,43 +463,70 @@ namespace dr535 { // dr535: yes // dr538: na // dr539: yes -const dr539( // expected-error {{a type specifier is required}} - const a) { // expected-error {{unknown type name 'a'}} - const b; // expected-error {{a type specifier is required}} - new const; // expected-error {{expected a type}} - try {} catch (const n) {} // expected-error {{unknown type name 'n'}} - try {} catch (const) {} // expected-error {{expected a type}} - if (const n = 0) {} // expected-error {{a type specifier is required}} - switch (const n = 0) {} // expected-error {{a type specifier is required}} - while (const n = 0) {} // expected-error {{a type specifier is required}} - for (const n = 0; // expected-error {{a type specifier is required}} - const m = 0; ) {} // expected-error {{a type specifier is required}} - sizeof(const); // expected-error {{a type specifier is required}} +const dr539( +// expected-error@-1 {{a type specifier is required for all declarations}} + const a) { + // expected-error@-1 {{unknown type name 'a'}} + const b; + // expected-error@-1 {{a type specifier is required for all declarations}} + new const; + // expected-error@-1 {{expected a type}} + try {} catch (const n) {} + // expected-error@-1 {{unknown type name 'n'}} + try {} catch (const) {} + // expected-error@-1 {{expected a type}} + if (const n = 0) {} + // expected-error@-1 {{a type specifier is required for all declarations}} + switch (const n = 0) {} + // expected-error@-1 {{a type specifier is required for all declarations}} + while (const n = 0) {} + // expected-error@-1 {{a type specifier is required for all declarations}} + for (const n = 0; + // expected-error@-1 {{a type specifier is required for all declarations}} + const m = 0; ) {} + // expected-error@-1 {{a type specifier is required for all declarations}} + sizeof(const); + // expected-error@-1 {{a type specifier is required for all declarations}} struct S { - const n; // expected-error {{a type specifier is required}} - operator const(); // expected-error {{expected a type}} + const n; + // expected-error@-1 {{a type specifier is required for all declarations}} + operator const(); + // expected-error@-1 {{expected a type}} }; #if __cplusplus >= 201103L int arr[3]; // FIXME: The extra braces here are to avoid the parser getting too // badly confused when recovering here. We should fix this recovery. - { for (const n // expected-error {{unknown type name 'n'}} expected-note {{}} - : arr) ; {} } // expected-error +{{}} - (void) [](const) {}; // expected-error {{a type specifier is required}} - (void) [](const n) {}; // expected-error {{unknown type name 'n'}} - enum E : const {}; // expected-error {{expected a type}} - using T = const; // expected-error {{expected a type}} - auto f() -> const; // expected-error {{expected a type}} + { for (const n + // since-cxx11-error@-1 {{unknown type name 'n'}} + // since-cxx11-note@-2 {{}} + : arr) ; {} } + // since-cxx11-error@-1 +{{}} + (void) [](const) {}; + // since-cxx11-error@-1 {{a type ... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/74373 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits