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 76.50 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74243.diff 1 Files Affected: - (modified) clang/test/CXX/drs/dr3xx.cpp (+594-345) ``````````diff diff --git a/clang/test/CXX/drs/dr3xx.cpp b/clang/test/CXX/drs/dr3xx.cpp index d12e0aea5f5a..b1fcf709c227 100644 --- a/clang/test/CXX/drs/dr3xx.cpp +++ b/clang/test/CXX/drs/dr3xx.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -std=c++23 -verify=expected,cxx20_23,cxx23 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++20 -verify=expected,cxx98_20,cxx20_23 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++17 -verify=expected,cxx98_17,cxx98_20 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++14 -verify=expected,cxx98_17,cxx98_20 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++11 -verify=expected,cxx98_17,cxx98_20 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++98 -verify=expected,cxx98_17,cxx98_20 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++23 -verify=expected,cxx20-23,cxx23,since-cxx11,since-cxx17,since-cxx23 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++20 -verify=expected,cxx98-20,cxx20-23,since-cxx11,since-cxx17 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++17 -verify=expected,cxx98-17,cxx98-20,since-cxx11,since-cxx17 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 -verify=expected,cxx98-14,cxx98-17,cxx98-20,cxx11-14,since-cxx11 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 -verify=expected,cxx98-14,cxx98-17,cxx98-20,cxx11-14,since-cxx11 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++98 -verify=expected,cxx98-14,cxx98-17,cxx98-20,cxx98 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors namespace dr300 { // dr300: yes template<typename R, typename A> void f(R (&)(A)) {} @@ -18,50 +18,81 @@ namespace dr301 { // dr301: 3.5 void operator-(S, S); void f() { - bool a = (void(*)(S, S))operator+<S> < // expected-warning {{ordered comparison of function pointers}} - (void(*)(S, S))operator+<S>; - bool b = (void(*)(S, S))operator- < // cxx20_23-note {{to match this '<'}} cxx98_17-warning {{ordered comparison of function pointers}} - (void(*)(S, S))operator-; // cxx20_23-error {{expected '>'}} - bool c = (void(*)(S, S))operator+ < // expected-note {{to match this '<'}} - (void(*)(S, S))operator-; // expected-error {{expected '>'}} + bool a = (void(*)(S, S))operator+<S> < (void(*)(S, S))operator+<S>; + // expected-warning@-1 {{ordered comparison of function pointers ('void (*)(S, S)' and 'void (*)(S, S)')}} + bool b = (void(*)(S, S))operator- < (void(*)(S, S))operator-; + // cxx98-17-warning@-1 {{ordered comparison of function pointers ('void (*)(S, S)' and 'void (*)(S, S)')}} + // cxx20-23-error@-2 {{expected '>'}} + // cxx20-23-note@-3 {{to match this '<'}} + bool c = (void(*)(S, S))operator+ < (void(*)(S, S))operator-; + // expected-error@-1 {{expected '>'}} + // expected-note@-2 {{to match this '<'}} } template<typename T> void f() { - typename T::template operator+<int> a; // expected-error {{typename specifier refers to a non-type template}} expected-error +{{}} + // FIXME: We are emitting a lot of bogus diagnostics here. + typename T::template operator+<int> a; + // expected-error@-1 {{typename specifier refers to a non-type template}} + // expected-error@-2 {{'template' keyword not permitted here}} + // expected-error@-3 {{a type specifier is required for all declarations}} + // expected-error@-4 {{'operator+' cannot be the name of a variable or data member}} + // expected-error@-5 {{expected ';' at end of declaration}} // FIXME: This shouldn't say (null). - class T::template operator+<int> b; // expected-error {{identifier followed by '<' indicates a class template specialization but (null) refers to a function template}} - enum T::template operator+<int> c; // expected-error {{expected identifier}} - enum T::template operator+<int>::E d; // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}} expected-error {{forward reference}} + class T::template operator+<int> b; + // expected-error@-1 {{identifier followed by '<' indicates a class template specialization but (null) refers to a function template}} + enum T::template operator+<int> c; + // expected-error@-1 {{expected identifier}} + enum T::template operator+<int>::E d; + // expected-error@-1 {{qualified name refers into a specialization of function template 'T::template operator +'}} + // expected-error@-2 {{ISO C++ forbids forward references to 'enum' types}} enum T::template X<int>::E e; - T::template operator+<int>::foobar(); // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}} + T::template operator+<int>::foobar(); + // expected-error@-1 {{qualified name refers into a specialization of function template 'T::template operator +'}} T::template operator+<int>(0); // ok } - template<typename T> class operator&<T*> {}; // expected-error +{{}} - template<typename T> class T::operator& {}; // expected-error +{{}} - template<typename T> class S::operator&<T*> {}; // expected-error +{{}} + // FIXME: We are emitting a bunch of bogus diagnostics for the next 3 lines. + // All of them do a bad job at explaining that 'class' is not allowed here. + template<typename T> class operator&<T*> {}; + // expected-error@-1 {{declaration of anonymous class must be a definition}} + // expected-error@-2 {{declaration does not declare anything}} + template<typename T> class T::operator& {}; + // expected-error@-1 {{expected identifier}} + // expected-error@-2 {{declaration of anonymous class must be a definition}} + // expected-error@-3 {{declaration does not declare anything}} + template<typename T> class S::operator&<T*> {}; + // expected-error@-1 {{expected identifier}} + // expected-error@-2 {{declaration of anonymous class must be a definition}} + // expected-error@-3 {{declaration does not declare anything}} } namespace dr302 { // dr302: 3.0 struct A { A(); ~A(); }; #if __cplusplus < 201103L - struct B { // expected-error {{implicit default constructor for 'dr302::B' must explicitly initialize the const member 'n'}} - const int n; // expected-note {{declared here}} + struct B { + // expected-error@-1 {{implicit default constructor for 'dr302::B' must explicitly initialize the const member 'n'}} + // expected-note@#dr302-b {{in implicit default constructor for 'dr302::B' first required here}} + // expected-note@#dr302-B-n {{declared here}} + const int n; // #dr302-B-n A a; - } b = B(); // expected-note {{first required here}} + } b = B(); // #dr302-b // Trivial default constructor C::C() is not called here. struct C { const int n; } c = C(); #else struct B { - const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}} + const int n; // #dr302-B-n A a; - } b = B(); // expected-error {{call to implicitly-deleted default constructor}} + } b = B(); + // expected-error@-1 {{call to implicitly-deleted default constructor of 'B'}} + // expected-note@#dr302-B-n {{default constructor of 'B' is implicitly deleted because field 'n' of const-qualified type 'const int' would not be initialized}} // C::C() is called here, because even though it's trivial, it's deleted. struct C { - const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}} - } c = C(); // expected-error {{call to implicitly-deleted default constructor}} + const int n; // #dr302-C-n + } c = C(); + // expected-error@-1 {{call to implicitly-deleted default constructor of 'C'}} + // expected-note@#dr302-C-n {{default constructor of 'C' is implicitly deleted because field 'n' of const-qualified type 'const int' would not be initialized}} struct D { const int n = 0; } d = D(); @@ -72,17 +103,15 @@ namespace dr302 { // dr302: 3.0 namespace dr304 { // dr304: 2.9 typedef int &a; - int n = a(); // expected-error {{requires an initializer}} - - struct S { int &b; }; - int m = S().b; -#if __cplusplus < 201103L - // expected-error@-3 {{requires an initializer}} - // expected-note@-3 {{in value-initialization}} -#else - // expected-error@-5 {{deleted}} - // expected-note@-7 {{reference}} -#endif + int n = a(); + // expected-error@-1 {{reference to type 'int' requires an initializer}} + + struct S { int &b; }; // #dr304-S + // cxx98-error@-1 {{reference to type 'int' requires an initializer}} + // cxx98-note@#dr304-m {{in value-initialization of type 'S' here}} + int m = S().b; // #dr304-m + // since-cxx11-error@-1 {{call to implicitly-deleted default constructor of 'S'}} + // since-cxx11-note@#dr304-S {{default constructor of 'S' is implicitly deleted because field 'b' of reference type 'int &' would not be initialized}} } namespace dr305 { // dr305: no @@ -100,8 +129,10 @@ namespace dr305 { // dr305: no b->~C(); } void h(B *b) { - struct B {}; // expected-note {{type 'B' found by destructor name lookup}} - b->~B(); // expected-error {{does not match}} + struct B {}; // #dr305-h-B + b->~B(); + // expected-error@-1 {{destructor type 'B' in object destruction expression does not match the type 'B' (aka 'dr305::A') of the object being destroyed}} + // expected-note@#dr305-h-B {{type 'B' found by destructor name lookup}} } template<typename T> struct X {}; @@ -109,7 +140,8 @@ namespace dr305 { // dr305: no struct X {}; x->~X<int>(); x->~X(); - x->~X<char>(); // expected-error {{no member named}} + x->~X<char>(); + // expected-error@-1 {{no member named '~X' in 'dr305::X<int>'}} } #if __cplusplus >= 201103L @@ -125,8 +157,10 @@ namespace dr305 { // dr305: no template<typename T> using T2 = T; }; void k(Z *z) { - z->~T1<int>(); // expected-error {{no member named 'T1' in 'dr305::Z'}} - z->~T2<int>(); // expected-error {{no member named '~int'}} + z->~T1<int>(); + // expected-error@-1 {{no member named 'T1' in 'dr305::Z'}} + z->~T2<int>(); + // expected-error@-1 {{no member named '~int' in 'dr305::Z'}} z->~T2<Z>(); } @@ -135,7 +169,8 @@ namespace dr305 { // dr305: no template<typename A> struct R {}; } template<typename A> using R = Q::R<int>; - void qr(Q::R<int> x) { x.~R<char>(); } // expected-error {{no member named}} + void qr(Q::R<int> x) { x.~R<char>(); } + // expected-error@-1 {{no member named '~R' in 'dr305::Q::R<int>'}} #endif } @@ -145,11 +180,14 @@ namespace dr306 { // dr306: dup 39 struct D : A, A::B, C {}; D::B b; - struct X {}; // expected-note {{member type 'dr306::X' found}} - template<typename T> struct Y { typedef T X; }; // expected-note {{member type 'const dr306::X' found}} + struct X {}; // #dr306-X + template<typename T> struct Y { typedef T X; }; // #dr306-typedef-X template<typename T> struct Z : X, Y<T> {}; Z<X>::X zx; - Z<const X>::X zcx; // expected-error {{member 'X' found in multiple base classes of different types}} + Z<const X>::X zcx; + // expected-error@-1 {{member 'X' found in multiple base classes of different types}} + // expected-note@#dr306-X {{member type 'dr306::X' found}} + // expected-note@#dr306-typedef-X {{member type 'const dr306::X' found}} } // dr307: na @@ -172,9 +210,11 @@ namespace dr308 { // dr308: 3.7 // positive rate should be acceptably low. try { throw D(); - } catch (const A&) { // expected-note {{for type 'const A &'}} + } catch (const A&) { // #dr308-catch-A // unreachable - } catch (const B&) { // expected-warning {{exception of type 'const B &' will be caught by earlier handler}} + } catch (const B&) { + // expected-warning@-1 {{exception of type 'const B &' will be caught by earlier handler}} + // expected-note@#dr308-catch-A {{for type 'const A &'}} // get here instead } } @@ -185,27 +225,26 @@ namespace dr308 { // dr308: 3.7 namespace dr311 { // dr311: 3.0 namespace X { namespace Y {} } namespace X::Y {} -#if __cplusplus <= 201402L - // expected-error@-2 {{define each namespace separately}} -#endif + // cxx98-14-error@-1 {{nested namespace definition is a C++17 extension; define each namespace separately}} namespace X { namespace X::Y {} -#if __cplusplus <= 201402L - // expected-error@-2 {{define each namespace separately}} -#endif + // cxx98-14-error@-1 {{nested namespace definition is a C++17 extension; define each namespace separately}} } // FIXME: The diagnostics here are not very good. - namespace ::dr311::X {} // expected-error 2+{{}} // expected-warning {{extra qual}} + namespace ::dr311::X {} + // expected-error@-1 {{expected identifier or '{'}} + // expected-warning@-2 {{extra qualification on member 'X'}} + // expected-error@-3 {{a type specifier is required for all declarations}} + // expected-error@-4 {{expected ';' after top level declarator}} } // dr312: dup 616 namespace dr313 { // dr313: dup 299 c++11 struct A { operator int() const; }; + // FIXME: should this be available in c++98 mode? int *p = new int[A()]; -#if __cplusplus < 201103L - // FIXME: should this be available in c++98 mode? expected-error@-2 {{extension}} -#endif + // cxx98-error@-1 {{implicit conversion from array size expression of type 'A' to integral type 'int' is a C++11 extension}} } namespace dr314 { // dr314: no @@ -227,8 +266,10 @@ template <typename T> struct C2 : public A<T>::B<T> { // dr316: sup 1004 namespace dr317 { // dr317: 3.5 - void f() {} // expected-note {{previous}} - inline void f(); // expected-error {{inline declaration of 'f' follows non-inline definition}} + void f() {} // #dr317-f + inline void f(); + // expected-error@-1 {{inline declaration of 'f' follows non-inline definition}} + // expected-note@#dr317-f {{previous definition is here}} int g(); int n = g(); @@ -236,8 +277,10 @@ namespace dr317 { // dr317: 3.5 int h(); int m = h(); - int h() { return 0; } // expected-note {{previous}} - inline int h(); // expected-error {{inline declaration of 'h' follows non-inline definition}} + int h() { return 0; } // #dr317-h + inline int h(); + // expected-error@-1 {{inline declaration of 'h' follows non-inline definition}} + // expected-note@#dr317-h {{previous definition is here}} } namespace dr318 { // dr318: sup 1310 @@ -268,20 +311,18 @@ namespace dr319 { // dr319: no struct A { int n; }; extern A a; // FIXME: ill-formed X<A> xa; + // cxx98-error@-1 {{template argument uses local type 'A'}} typedef A B; extern B b; // FIXME: ill-formed X<B> xb; + // cxx98-error@-1 {{template argument uses local type 'A'}} const int n = 1; typedef int (*C)[n]; extern C c; // ok X<C> xc; } -#if __cplusplus < 201103L - // expected-error@-12 {{uses local type 'A'}} - // expected-error@-9 {{uses local type 'A'}} -#endif } namespace dr320 { // dr320: yes @@ -328,16 +369,29 @@ namespace dr322 { // dr322: 2.8 // dr323: no namespace dr324 { // dr324: 3.6 - struct S { int n : 1; } s; // expected-note 3{{bit-field is declared here}} - int &a = s.n; // expected-error {{non-const reference cannot bind to bit-field}} - int *b = &s.n; // expected-error {{address of bit-field}} - int &c = (s.n = 0); // expected-error {{non-const reference cannot bind to bit-field}} - int *d = &(s.n = 0); // expected-error {{address of bit-field}} - int &e = true ? s.n : s.n; // expected-error {{non-const reference cannot bind to bit-field}} - int *f = &(true ? s.n : s.n); // expected-error {{address of bit-field}} - int &g = (void(), s.n); // expected-error {{non-const reference cannot bind to bit-field}} - int *h = &(void(), s.n); // expected-error {{address of bit-field}} - int *i = &++s.n; // expected-error {{address of bit-field}} + struct S { int n : 1; } s; // #dr324-n + int &a = s.n; + // expected-error@-1 {{non-const reference cannot bind to bit-field 'n'}} + // expected-note@#dr324-n {{bit-field is declared here}} + int *b = &s.n; + // expected-error@-1 {{address of bit-field requested}} + int &c = (s.n = 0); + // expected-error@-1 {{non-const reference cannot bind to bit-field 'n'}} + // expected-note@#dr324-n {{bit-field is declared here}} + int *d = &(s.n = 0); + // expected-error@-1 {{address of bit-field requested}} + // FIXME: why don't we emit a note here, as for the rest of this type of diagnostic in this test? + int &e = true ? s.n : s.n; + // expected-error@-1 {{non-const reference cannot bind to bit-field}} + int *f = &(true ? s.n : s.n); + // expected-error@-1 {{address of bit-field requested}} + int &g = (void(), s.n); + // expected-error@-1 {{non-const reference cannot bind to bit-field 'n'}} + // expected-note@#dr324-n {{bit-field is declared here}} + int *h = &(void(), s.n); + // expected-error@-1 {{address of bit-field requested}} + int *i = &++s.n; + // expected-error@-1 {{address of bit-field requested}} } namespace dr326 { // dr326: 3.1 @@ -354,24 +408,35 @@ namespace dr327 { // dr327: dup 538 } namespace dr328 { // dr328: yes - struct A; // expected-note 3{{forward declaration}} - struct B { A a; }; // expected-error {{incomplete}} - template<typename> struct C { A a; }; // expected-error {{incomplete}} - A *p = new A[0]; // expected-error {{incomplete}} + struct A; // #dr328-A + struct B { A a; }; + // expected-error@-1 {{field has incomplete type 'A'}} + // expected-note@#dr328-A {{forward declaration of 'dr328::A'}} + template<typename> struct C { A a; }; + // expected-error@-1 {{field has incomplete type 'A'}} + // expected-note@#dr328-A {{forward declaration of 'dr328::A'}} + A *p = new A[0]; + // expected-error@-1 {{allocation of incomplete type 'A'}} + // expected-note@#dr328-A {{forward declaration of 'dr328::A'}} } namespace dr329 { // dr329: 3.5 struct B {}; template<typename T> struct A : B { friend void f(A a) { g(a); } - friend void h(A a) { g(a); } // expected-error {{undeclared}} - friend void i(B b) {} // expected-error {{redefinition}} expected-note {{previous}} + friend void h(A a) { g(a); } + // expected-error@-1 {{use of undeclared identifier 'g'}} + // expected-note@#dr329-h-call {{in instantiation of member function 'dr329::h' requested here}} + friend void i(B b) {} // #dr329-i + // expected-error@-1 {{redefinition of 'i'}} + // expected-note@#dr329-b {{in instantiation of template class 'dr329::A<char>' requested here}} + // expected-note@#dr329-i {{previous definition is here}} }; - A<int> a; - A<char> b; // expected-note {{instantiation}} + A<int> a; + A<char> b; // #dr329-b void test() { - h(a); // expected-note {{instantiation}} + h(a); // #dr329-h-call } } @@ -387,50 +452,60 @@ namespace dr330 { // dr330: 7 void f(P p, Q q, Q2 q2, R r, S s, T t) { q = p; // ok q2 = p; // ok - r = p; // expected-error {{incompatible}} + r = p; + // expected-error@-1 {{incompatible pointer types assigning to 'R' (aka 'const int *const (*)[4]') from 'P' (aka 'int *(*)[3]')}} s = p; -#if __cplusplus < 202002 - // expected-error@-2 {{incompatible}} (fixed by p0388) -#endif - t = p; // expected-error {{incompatible}} + // cxx98-17-error@-1 {{incompatible pointer types assigning to 'S' (aka 'const int *const (*)[]') from 'P' (aka 'int *(*)[3]')}} (fixed by p0388) + t = p; + // expected-error@-1 {{incompatible pointer types assigning to 'T' (aka 'const int *(*)[]') from 'P' (aka 'int *(*)[3]')}} s = q; -#if __cplusplus < 202002 - // expected-error@-2 {{incompatible}} (fixed by p0388) -#endif + // cxx98-17-error@-1 {{incompatible pointer types assigning to 'S' (aka 'const int *const (*)[]') from 'Q' (aka 'const int *cons... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/74243 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits