https://github.com/Endilll created https://github.com/llvm/llvm-project/pull/74243
This patch continues the work started with ea5b1ef016d020c37f903d6c7d4f623be975dab8. See that commit and its corresponding PR for details. >From 49a5323663b8bc56d9720c6d2ebb9c3d686fd362 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Sun, 3 Dec 2023 16:48:22 +0300 Subject: [PATCH] [clang][NFC] Refactor expected directives in C++ DRs 300-399 This patch continues the work started with ea5b1ef016d020c37f903d6c7d4f623be975dab8. See that commit and its corresponding PR for details. --- clang/test/CXX/drs/dr3xx.cpp | 939 ++++++++++++++++++++++------------- 1 file changed, 594 insertions(+), 345 deletions(-) diff --git a/clang/test/CXX/drs/dr3xx.cpp b/clang/test/CXX/drs/dr3xx.cpp index d12e0aea5f5ac..b1fcf709c2273 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 *const (*)[3]')}} (fixed by p0388) s = q2; -#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 'Q2' (aka 'const int *const (*)[3]')}} (fixed by p0388) s = t; // ok, adding const - t = s; // expected-error {{discards qualifiers}} + t = s; + // expected-error@-1 {{assigning to 'T' (aka 'const int *(*)[]') from 'S' (aka 'const int *const (*)[]') discards qualifiers}} (void) const_cast<P>(q); (void) const_cast<P>(q2); (void) const_cast<Q>(p); (void) const_cast<Q2>(p); - (void) const_cast<S>(p); // expected-error {{not allowed}} (for now) - (void) const_cast<P>(s); // expected-error {{not allowed}} (for now) - (void) const_cast<S>(q); // expected-error {{not allowed}} - (void) const_cast<S>(q2); // expected-error {{not allowed}} - (void) const_cast<Q>(s); // expected-error {{not allowed}} - (void) const_cast<Q2>(s); // expected-error {{not allowed}} + (void) const_cast<S>(p); + // expected-error@-1 {{const_cast from 'P' (aka 'int *(*)[3]') to 'S' (aka 'const int *const (*)[]') is not allowed}} (for now) + (void) const_cast<P>(s); + // expected-error@-1 {{const_cast from 'S' (aka 'const int *const (*)[]') to 'P' (aka 'int *(*)[3]') is not allowed}} (for now) + (void) const_cast<S>(q); + // expected-error@-1 {{const_cast from 'Q' (aka 'const int *const (*)[3]') to 'S' (aka 'const int *const (*)[]') is not allowed}} + (void) const_cast<S>(q2); + // expected-error@-1 {{const_cast from 'Q2' (aka 'const int *const (*)[3]') to 'S' (aka 'const int *const (*)[]') is not allowed}} + (void) const_cast<Q>(s); + // expected-error@-1 {{const_cast from 'S' (aka 'const int *const (*)[]') to 'Q' (aka 'const int *const (*)[3]') is not allowed}} + (void) const_cast<Q2>(s); + // expected-error@-1 {{const_cast from 'S' (aka 'const int *const (*)[]') to 'Q2' (aka 'const int *const (*)[3]') is not allowed}} (void) const_cast<T>(s); (void) const_cast<S>(t); - (void) const_cast<T>(q); // expected-error {{not allowed}} - (void) const_cast<Q>(t); // expected-error {{not allowed}} - - (void) reinterpret_cast<P>(q); // expected-error {{casts away qualifiers}} - (void) reinterpret_cast<P>(q2); // expected-error {{casts away qualifiers}} + (void) const_cast<T>(q); + // expected-error@-1 {{const_cast from 'Q' (aka 'const int *const (*)[3]') to 'T' (aka 'const int *(*)[]') is not allowed}} + (void) const_cast<Q>(t); + // expected-error@-1 {{const_cast from 'T' (aka 'const int *(*)[]') to 'Q' (aka 'const int *const (*)[3]') is not allowed}} + + (void) reinterpret_cast<P>(q); + // expected-error@-1 {{reinterpret_cast from 'Q' (aka 'const int *const (*)[3]') to 'P' (aka 'int *(*)[3]') casts away qualifiers}} + (void) reinterpret_cast<P>(q2); + // expected-error@-1 {{reinterpret_cast from 'Q2' (aka 'const int *const (*)[3]') to 'P' (aka 'int *(*)[3]') casts away qualifiers}} (void) reinterpret_cast<Q>(p); (void) reinterpret_cast<Q2>(p); (void) reinterpret_cast<S>(p); - (void) reinterpret_cast<P>(s); // expected-error {{casts away qualifiers}} + (void) reinterpret_cast<P>(s); + // expected-error@-1 {{reinterpret_cast from 'S' (aka 'const int *const (*)[]') to 'P' (aka 'int *(*)[3]') casts away qualifiers}} (void) reinterpret_cast<S>(q); (void) reinterpret_cast<S>(q2); (void) reinterpret_cast<Q>(s); (void) reinterpret_cast<Q2>(s); - (void) reinterpret_cast<T>(s); // expected-error {{casts away qualifiers}} + (void) reinterpret_cast<T>(s); + // expected-error@-1 {{reinterpret_cast from 'S' (aka 'const int *const (*)[]') to 'T' (aka 'const int *(*)[]') casts away qualifiers}} (void) reinterpret_cast<S>(t); - (void) reinterpret_cast<T>(q); // expected-error {{casts away qualifiers}} + (void) reinterpret_cast<T>(q); + // expected-error@-1 {{reinterpret_cast from 'Q' (aka 'const int *const (*)[3]') to 'T' (aka 'const int *(*)[]') casts away qualifiers}} (void) reinterpret_cast<Q>(t); } @@ -450,8 +525,10 @@ namespace dr330 { // dr330: 7 typedef volatile int *(*const B4)[4]; void f(A *a) { (void) reinterpret_cast<B1*>(a); - (void) reinterpret_cast<B2*>(a); // expected-error {{casts away qualifiers}} - (void) reinterpret_cast<B3*>(a); // expected-error {{casts away qualifiers}} + (void) reinterpret_cast<B2*>(a); + // expected-error@-1 {{ISO C++ does not allow reinterpret_cast from 'A *' (aka 'const volatile int (*)[1][2][3]') to 'B2 *' (aka 'int *const dr330::swift_17882::X::***') because it casts away qualifiers, even though the source and destination types are unrelated}} + (void) reinterpret_cast<B3*>(a); + // expected-error@-1 {{ISO C++ does not allow reinterpret_cast from 'A *' (aka 'const volatile int (*)[1][2][3]') to 'B3 *' (aka 'int *dr330::swift_17882::X::*volatile **') because it casts away qualifiers, even though the source and destination types are unrelated}} (void) reinterpret_cast<B4*>(a); } } @@ -459,16 +536,25 @@ namespace dr330 { // dr330: 7 namespace dr331 { // dr331: 11 struct A { - A(volatile A&); // expected-note 2{{candidate}} - } const a, b(a); // expected-error 2{{no matching constructor}} + A(volatile A&); // #dr331-A-ctor + }; + const A a; + // expected-error@-1 {{no matching constructor for initialization of 'const A'}} + // expected-note@#dr331-A-ctor {{candidate constructor not viable: requires 1 argument, but 0 were provided}} + const A b(a); + // expected-error@-1 {{no matching constructor for initialization of 'const A'}} + // expected-note@#dr331-A-ctor {{candidate constructor not viable: 1st argument ('const A') would lose const qualifier}} } namespace dr332 { // dr332: dup 577 - void f(volatile void); // expected-error {{'void' as parameter must not have type qualifiers}} - // cxx20_23-warning@-1 {{volatile-qualified parameter type 'volatile void' is deprecated}} - void g(const void); // expected-error {{'void' as parameter must not have type qualifiers}} - void h(int n, volatile void); // expected-error {{'void' must be the first and only parameter}} - // cxx20_23-warning@-1 {{volatile-qualified parameter type 'volatile void' is deprecated}} + void f(volatile void); + // expected-error@-1 {{'void' as parameter must not have type qualifiers}} + // cxx20-23-warning@-2 {{volatile-qualified parameter type 'volatile void' is deprecated}} + void g(const void); + // expected-error@-1 {{'void' as parameter must not have type qualifiers}} + void h(int n, volatile void); + // expected-error@-1 {{'void' must be the first and only parameter if specified}} + // cxx20-23-warning@-2 {{volatile-qualified parameter type 'volatile void' is deprecated}} } namespace dr333 { // dr333: yes @@ -501,8 +587,10 @@ namespace dr336 { // dr336: yes }; }; template<> template<class X> class A<int>::B {}; - template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {} // expected-error {{does not match}} - template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}} + template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {} + // expected-error@-1 {{out-of-line definition of 'mf1' does not match any declaration in 'dr336::Pre::A<int>::B<double>'}} + template<class Y> template<> void A<Y>::B<double>::mf2() {} + // expected-error@-1 {{nested name specifier 'A<Y>::B<double>::' for declaration does not refer into a class, class template or class template partial specialization}} } namespace Post { template<class T1> class A { @@ -516,7 +604,8 @@ namespace dr336 { // dr336: yes }; template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {} // FIXME: This diagnostic isn't very good. - template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}} + template<class Y> template<> void A<Y>::B<double>::mf2() {} + // expected-error@-1 {{nested name specifier 'A<Y>::B<double>::' for declaration does not refer into a class, class template or class template partial specialization}} } } @@ -531,7 +620,8 @@ namespace dr337 { // dr337: yes // whether an incomplete type is abstract. See DR1640, which will probably // supersede this one and remove this rule. struct B; - int &s = f<B>(0); // expected-error {{of type 'void'}} + int &s = f<B>(0); + // expected-error@-1 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'void'}} struct B { virtual ~B() = 0; }; } @@ -541,12 +631,14 @@ namespace dr339 { // dr339: 2.8 char xxx(int); char (&xxx(float))[2]; - template<class T> A<sizeof(xxx((T)0))> f(T) {} // expected-note {{candidate}} + template<class T> A<sizeof(xxx((T)0))> f(T) {} // #dr339-f void test() { A<1> a = f(0); A<2> b = f(0.0f); - A<3> c = f("foo"); // expected-error {{no matching function}} + A<3> c = f("foo"); + // expected-error@-1 {{no matching function}} + // expected-note@#dr339-f {{candidate}} } @@ -576,23 +668,35 @@ namespace dr340 { // dr340: yes namespace dr341 { // dr341: sup 1708 namespace A { int n; - extern "C" int &dr341_a = n; // expected-note {{previous}} expected-note {{declared with C language linkage here}} + extern "C" int &dr341_a = n; // #dr341_a } namespace B { - extern "C" int &dr341_a = dr341_a; // expected-error {{redefinition}} + extern "C" int &dr341_a = dr341_a; + // expected-error@-1 {{redefinition of 'dr341_a'}} + // expected-note@#dr341_a {{previous definition is here}} } - extern "C" void dr341_b(); // expected-note {{declared with C language linkage here}} + extern "C" void dr341_b(); // #dr341_b } -int dr341_a; // expected-error {{declaration of 'dr341_a' in global scope conflicts with declaration with C language linkage}} -int dr341_b; // expected-error {{declaration of 'dr341_b' in global scope conflicts with declaration with C language linkage}} -int dr341_c; // expected-note {{declared in global scope here}} -int dr341_d; // expected-note {{declared in global scope here}} +int dr341_a; +// expected-error@-1 {{declaration of 'dr341_a' in global scope conflicts with declaration with C language linkage}} +// expected-note@#dr341_a {{declared with C language linkage here}} +int dr341_b; +// expected-error@-1 {{declaration of 'dr341_b' in global scope conflicts with declaration with C language linkage}} +// expected-note@#dr341_b {{declared with C language linkage here}} +int dr341_c; // #dr341_c +int dr341_d; // #dr341_d namespace dr341 { - extern "C" int dr341_c; // expected-error {{declaration of 'dr341_c' with C language linkage conflicts with declaration in global scope}} - extern "C" void dr341_d(); // expected-error {{declaration of 'dr341_d' with C language linkage conflicts with declaration in global scope}} - - namespace A { extern "C" int dr341_e; } // expected-note {{previous}} - namespace B { extern "C" void dr341_e(); } // expected-error {{redefinition of 'dr341_e' as different kind of symbol}} + extern "C" int dr341_c; + // expected-error@-1 {{declaration of 'dr341_c' with C language linkage conflicts with declaration in global scope}} + // expected-note@#dr341_c {{declared in global scope here}} + extern "C" void dr341_d(); + // expected-error@-1 {{declaration of 'dr341_d' with C language linkage conflicts with declaration in global scope}} + // expected-note@#dr341_d {{declared in global scope here}} + + namespace A { extern "C" int dr341_e; } // #dr341_e + namespace B { extern "C" void dr341_e(); } + // expected-error@-1 {{redefinition of 'dr341_e' as different kind of symbol}} + // expected-note@#dr341_e {{previous definition is here}} } // dr342: na @@ -603,8 +707,10 @@ namespace dr343 { // dr343: no template<typename U> struct B {}; }; // FIXME: In these contexts, the 'template' keyword is optional. - template<typename T> struct C : public A<T>::B<T> { // expected-error {{use 'template'}} - C() : A<T>::B<T>() {} // expected-error {{use 'template'}} + template<typename T> struct C : public A<T>::B<T> { + // expected-error@-1 {{use 'template' keyword to treat 'B' as a dependent template name}} + C() : A<T>::B<T>() {} + // expected-error@-1 {{use 'template' keyword to treat 'B' as a dependent template name}} }; } @@ -616,15 +722,18 @@ namespace dr344 { // dr344: dup 1435 namespace dr345 { // dr345: yes struct A { struct X {}; - int X; // expected-note {{here}} + int X; // #dr345-int-X }; struct B { struct X {}; }; - template <class T> void f(T t) { typename T::X x; } // expected-error {{refers to non-type member 'X'}} + template <class T> void f(T t) { typename T::X x; } + // expected-error@-1 {{typename specifier refers to non-type member 'X' in 'dr345::A'}} + // expected-note@#dr345-f-a {{in instantiation of function template specialization 'dr345::f<dr345::A>' requested here}} + // expected-note@#dr345-int-X {{referenced member 'X' is declared here}} void f(A a, B b) { f(b); - f(a); // expected-note {{instantiation}} + f(a); // #dr345-f-a } } @@ -640,10 +749,14 @@ namespace dr347 { // dr347: yes struct derived : base {}; - struct derived::nested {}; // expected-error {{no struct named 'nested'}} - int derived::n; // expected-error {{no member named 'n'}} - void derived::f() {} // expected-error {{does not match any}} - void derived::g() {} // expected-error {{does not match any}} + struct derived::nested {}; + // expected-error@-1 {{no struct named 'nested' in 'dr347::derived'}} + int derived::n; + // expected-error@-1 {{no member named 'n' in 'dr347::derived'}} + void derived::f() {} + // expected-error@-1 {{out-of-line definition of 'f' does not match any declaration in 'dr347::derived'}} + void derived::g() {} + // expected-error@-1 {{out-of-line definition of 'g' does not match any declaration in 'dr347::derived'}} } // dr348: na @@ -652,14 +765,16 @@ namespace dr349 { // dr349: no struct A { template <class T> operator T ***() { int ***p = 0; - return p; // cxx98_20-error {{cannot initialize return object of type 'const int ***' with an lvalue of type 'int ***'}} - // cxx23-error@-1 {{cannot initialize return object of type 'const int ***' with an rvalue of type 'int ***'}} + return p; + // cxx98-20-error@-1 {{cannot initialize return object of type 'const int ***' with an lvalue of type 'int ***'}} + // since-cxx23-error@-2 {{cannot initialize return object of type 'const int ***' with an rvalue of type 'int ***'}} + // expected-note@#dr349-p1 {{in instantiation of function template specialization 'dr349::A::operator const int ***<const int>' requested here}} } }; // FIXME: This is valid. A a; - const int *const *const *p1 = a; // expected-note {{in instantiation of}} + const int *const *const *p1 = a; // #dr349-p1 struct B { template <class T> operator T ***() { @@ -679,23 +794,30 @@ namespace dr352 { // dr352: 2.8 namespace example1 { namespace A { enum E {}; - template<typename R, typename A> void foo(E, R (*)(A)); // expected-note 2{{couldn't infer template argument 'R'}} + template<typename R, typename A> void foo(E, R (*)(A)); // #dr352-foo } template<typename T> void arg(T); - template<typename T> int arg(T) = delete; // expected-note {{here}} expected-error 0-1{{extension}} + template<typename T> int arg(T) = delete; // #dr352-deleted + // cxx98-error@-1 {{deleted function definitions are a C++11 extension}} void f(A::E e) { - foo(e, &arg); // expected-error {{no matching function}} + foo(e, &arg); + // expected-error@-1 {{no matching function for call to 'foo'}} + // expected-note@#dr352-foo {{candidate template ignored: couldn't infer template argument 'R'}} using A::foo; - foo<int, int>(e, &arg); // expected-error {{deleted}} + foo<int, int>(e, &arg); + // expected-error@-1 {{attempt to use a deleted function}} + // expected-note@#dr352-deleted {{'arg<int>' has been explicitly marked deleted here}} } int arg(int); void g(A::E e) { - foo(e, &arg); // expected-error {{no matching function}} + foo(e, &arg); + // expected-error@-1 {{no matching function for call to 'foo'}} + // expected-note@#dr352-foo {{candidate template ignored: couldn't infer template argument 'R'}} using A::foo; foo<int, int>(e, &arg); // ok, uses non-template @@ -704,54 +826,68 @@ namespace dr352 { // dr352: 2.8 namespace contexts { template<int I> void f1(int (&)[I]); - template<int I> void f2(int (&)[I+1]); // expected-note {{couldn't infer}} + template<int I> void f2(int (&)[I+1]); // #dr352-f2 template<int I> void f3(int (&)[I+1], int (&)[I]); void f() { int a[4]; int b[3]; f1(a); - f2(a); // expected-error {{no matching function}} + f2(a); + // expected-error@-1 {{no matching function for call to 'f2'}} + // expected-note@#dr352-f2 {{candidate template ignored: couldn't infer template argument 'I'}} f3(a, b); } template<int I> struct S {}; template<int I> void g1(S<I>); - template<int I> void g2(S<I+1>); // expected-note {{couldn't infer}} + template<int I> void g2(S<I+1>); // #dr352-g2 template<int I> void g3(S<I+1>, S<I>); void g() { S<4> a; S<3> b; g1(a); - g2(a); // expected-error {{no matching function}} + g2(a); + // expected-error@-1 {{no matching function for call to 'g2'}} + // expected-note@#dr352-g2 {{candidate template ignored: couldn't infer template argument 'I'}} g3(a, b); } - template<typename T> void h1(T = 0); // expected-note {{couldn't infer}} + template<typename T> void h1(T = 0); // #dr352-h1 template<typename T> void h2(T, T = 0); void h() { - h1(); // expected-error {{no matching function}} + h1(); + // expected-error@-1 {{no matching function for call to 'h1'}} + // expected-note@#dr352-h1 {{candidate template ignored: couldn't infer template argument 'T'}} h1(0); h1<int>(); h2(0); } template<typename T> int tmpl(T); - template<typename R, typename A> void i1(R (*)(A)); // expected-note 3{{couldn't infer}} - template<typename R, typename A> void i2(R, A, R (*)(A)); // expected-note {{not viable}} + template<typename R, typename A> void i1(R (*)(A)); // #dr352-i1 + template<typename R, typename A> void i2(R, A, R (*)(A)); // #dr352-i2 void i() { extern int single(int); i1(single); i2(0, 0, single); extern int ambig(float), ambig(int); - i1(ambig); // expected-error {{no matching function}} + i1(ambig); + // expected-error@-1 {{no matching function for call to 'i1'}} + // expected-note@#dr352-i1 {{candidate template ignored: couldn't infer template argument 'R'}} i2(0, 0, ambig); extern void no_match(float), no_match(int); - i1(no_match); // expected-error {{no matching function}} - i2(0, 0, no_match); // expected-error {{no matching function}} - - i1(tmpl); // expected-error {{no matching function}} + i1(no_match); + // expected-error@-1 {{no matching function for call to 'i1'}} + // expected-note@#dr352-i1 {{candidate template ignored: couldn't infer template argument 'R'}} + i2(0, 0, no_match); + // expected-error@-1 {{no matching function for call to 'i2'}} + // expected-note@#dr352-i2 {{candidate function [with R = int, A = int] not viable: no overload of 'no_match' matching 'int (*)(int)' for 3rd argument}} + + i1(tmpl); + // expected-error@-1 {{no matching function for call to 'i1'}} + // expected-note@#dr352-i1 {{candidate template ignored: couldn't infer template argument 'R'}} i2(0, 0, tmpl); } } @@ -782,10 +918,12 @@ namespace dr352 { // dr352: 2.8 namespace example5 { template<int I> class A {}; - template<int I> void g(A<I+1>); // expected-note {{couldn't infer}} + template<int I> void g(A<I+1>); // #dr352-g template<int I> void f(A<I>, A<I+1>); void h(A<1> a1, A<2> a2) { - g(a1); // expected-error {{no matching function}} + g(a1); + // expected-error@-1 {{no matching function for call to 'g'}} + // expected-note@#dr352-g {{candidate template ignored: couldn't infer template argument 'I'}} g<0>(a1); f(a1, a2); } @@ -798,77 +936,80 @@ namespace dr354 { // dr354: yes c++11 // FIXME: Should we allow this in C++98 too? struct S {}; - template<int*> struct ptr {}; // expected-note 0-4{{here}} - ptr<0> p0; + template<int*> struct ptr {}; // #dr354-ptr + ptr<0> p0; // #dr354-p0 + // cxx98-error@#dr354-p0 {{non-type template argument does not refer to any declaration}} + // cxx98-note@#dr354-ptr {{template parameter is declared here}} + // cxx11-14-error@#dr354-p0 {{null non-type template argument must be cast to template parameter type 'int *'}} + // cxx11-14-note@#dr354-ptr {{template parameter is declared here}} + // since-cxx17-error@#dr354-p0 {{conversion from 'int' to 'int *' is not allowed in a converted constant expression}} ptr<(int*)0> p1; - ptr<(float*)0> p2; - ptr<(int S::*)0> p3; -#if __cplusplus < 201103L - // expected-error@-5 {{does not refer to any decl}} - // expected-error@-5 {{does not refer to any decl}} - // expected-error@-5 {{does not refer to any decl}} - // expected-error@-5 {{does not refer to any decl}} -#elif __cplusplus <= 201402L - // expected-error@-10 {{must be cast}} - // ok - // expected-error@-10 {{does not match}} - // expected-error@-10 {{does not match}} -#else - // expected-error@-15 {{conversion from 'int' to 'int *' is not allowed}} - // ok - // expected-error@-15 {{'float *' is not implicitly convertible to 'int *'}} - // expected-error@-15 {{'int dr354::S::*' is not implicitly convertible to 'int *'}} -#endif - - template<int*> int both(); - template<int> int both(); + // cxx98-error@-1 {{non-type template argument does not refer to any declaration}} + // cxx98-note@#dr354-ptr {{template parameter is declared here}} + ptr<(float*)0> p2; // #dr354-p2 + // cxx98-error@#dr354-p2 {{non-type template argument does not refer to any declaration}} + // cxx98-note@#dr354-ptr {{template parameter is declared here}} + // cxx11-14-error@#dr354-p2 {{null non-type template argument of type 'float *' does not match template parameter of type 'int *'}} + // cxx11-14-note@#dr354-ptr {{template parameter is declared here}} + // since-cxx17-error@#dr354-p2 {{value of type 'float *' is not implicitly convertible to 'int *'}} + ptr<(int S::*)0> p3; // #dr354-p3 + // cxx98-error@#dr354-p3 {{non-type template argument does not refer to any declaration}} + // cxx98-note@#dr354-ptr {{template parameter is declared here}} + // cxx11-14-error@#dr354-p3 {{null non-type template argument of type 'int dr354::S::*' does not match template parameter of type 'int *'}} + // cxx11-14-note@#dr354-ptr {{template parameter is declared here}} + // since-cxx17-error@#dr354-p3 {{value of type 'int dr354::S::*' is not implicitly convertible to 'int *'}} + + template<int*> int both(); // #dr354-both-int-ptr + template<int> int both(); // #dr354-both-int int b0 = both<0>(); int b1 = both<(int*)0>(); -#if __cplusplus < 201103L - // expected-error@-2 {{no matching function}} - // expected-note@-6 {{candidate}} - // expected-note@-6 {{candidate}} -#endif - - template<int S::*> struct ptr_mem {}; // expected-note 0-4{{here}} - ptr_mem<0> m0; + // cxx98-error@-1 {{no matching function for call to 'both'}} + // cxx98-note@#dr354-both-int-ptr {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}} + // cxx98-note@#dr354-both-int {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}} + + template<int S::*> struct ptr_mem {}; // #dr354-ptr_mem + ptr_mem<0> m0; // #dr354-m0 + // cxx98-error@#dr354-m0 {{non-type template argument of type 'int' cannot be converted to a value of type 'int dr354::S::*'}} + // cxx98-note@#dr354-ptr_mem {{template parameter is declared here}} + // cxx11-14-error@#dr354-m0 {{null non-type template argument must be cast to template parameter type 'int dr354::S::*'}} + // cxx11-14-note@#dr354-ptr_mem {{template parameter is declared here}} + // since-cxx17-error@#dr354-m0 {{conversion from 'int' to 'int dr354::S::*' is not allowed in a converted constant expression}} ptr_mem<(int S::*)0> m1; - ptr_mem<(float S::*)0> m2; - ptr_mem<(int *)0> m3; -#if __cplusplus < 201103L - // expected-error@-5 {{cannot be converted}} - // expected-error@-5 {{is not a pointer to member constant}} - // expected-error@-5 {{cannot be converted}} - // expected-error@-5 {{cannot be converted}} -#elif __cplusplus <= 201402L - // expected-error@-10 {{must be cast}} - // ok - // expected-error@-10 {{does not match}} - // expected-error@-10 {{does not match}} -#else - // expected-error@-15 {{conversion from 'int' to 'int dr354::S::*' is not allowed}} - // ok - // expected-error@-15 {{'float dr354::S::*' is not implicitly convertible to 'int dr354::S::*'}} - // expected-error@-15 {{'int *' is not implicitly convertible to 'int dr354::S::*'}} -#endif + // cxx98-error@-1 {{non-type template argument is not a pointer to member constant}} + ptr_mem<(float S::*)0> m2; // #dr354-m2 + // cxx98-error@#dr354-m2 {{non-type template argument of type 'float dr354::S::*' cannot be converted to a value of type 'int dr354::S::*'}} + // cxx98-note@#dr354-ptr_mem {{template parameter is declared here}} + // cxx11-14-error@#dr354-m2 {{null non-type template argument of type 'float dr354::S::*' does not match template parameter of type 'int dr354::S::*'}} + // cxx11-14-note@#dr354-ptr_mem {{template parameter is declared here}} + // since-cxx17-error@#dr354-m2 {{value of type 'float dr354::S::*' is not implicitly convertible to 'int dr354::S::*'}} + ptr_mem<(int *)0> m3; // #dr354-m3 + // cxx98-error@#dr354-m3 {{non-type template argument of type 'int *' cannot be converted to a value of type 'int dr354::S::*'}} + // cxx98-note@#dr354-ptr_mem {{template parameter is declared here}} + // cxx11-14-error@#dr354-m3 {{null non-type template argument of type 'int *' does not match template parameter of type 'int dr354::S::*'}} + // cxx11-14-note@#dr354-ptr_mem {{template parameter is declared here}} + // since-cxx17-error@#dr354-m3 {{value of type 'int *' is not implicitly convertible to 'int dr354::S::*'}} } struct dr355_S; // dr355: yes -struct ::dr355_S {}; // expected-warning {{extra qualification}} +struct ::dr355_S {}; +// expected-warning@-1 {{extra qualification on member 'dr355_S'}} namespace dr355 { struct ::dr355_S s; } // dr356: na namespace dr357 { // dr357: yes template<typename T> struct A { - void f() const; // expected-note {{const qualified}} + void f() const; // #dr357-f }; - template<typename T> void A<T>::f() {} // expected-error {{does not match}} + template<typename T> void A<T>::f() {} + // expected-error@-1 {{out-of-line definition of 'f' does not match any declaration in 'A<T>'}} + // expected-note@#dr357-f {{member declaration does not match because it is const qualified}} struct B { template<typename T> void f(); }; - template<typename T> void B::f() const {} // expected-error {{does not match}} + template<typename T> void B::f() const {} + // expected-error@-1 {{out-of-line definition of 'f' does not match any declaration in 'dr357::B'}} } namespace dr358 { // dr358: yes @@ -890,15 +1031,18 @@ namespace dr359 { // dr359: yes } v; union { - struct { // expected-error {{extension}} + struct { + // expected-error@-1 {{anonymous types declared in an anonymous union are an extension}} int x; } s; - struct S { // expected-error {{types cannot be declared in an anonymous union}} + struct S { + // expected-error@-1 {{types cannot be declared in an anonymous union}} int x; } t; - union { // expected-error {{extension}} + union { + // expected-error@-1 {{anonymous types declared in an anonymous union are an extension}} int u; }; }; @@ -916,18 +1060,20 @@ struct A { struct B : A { private: - using A::foo; // #dr360-foo-using-decl + using A::foo; // #dr360-using-foo protected: - using A::bar; // #dr360-bar-using-decl + using A::bar; // #dr360-using-bar public: using A::baz; }; int main() { - int foo = B().foo(); // expected-error {{is a private member}} - // expected-note@#dr360-foo-using-decl {{declared private here}} - int bar = B().bar(); // expected-error {{is a protected member}} - // expected-note@#dr360-bar-using-decl {{declared protected here}} + int foo = B().foo(); + // expected-error@-1 {{'foo' is a private member of 'dr360::B'}} + // expected-note@#dr360-using-foo {{declared private here}} + int bar = B().bar(); + // expected-error@-1 {{'bar' is a protected member of 'dr360::B'}} + // expected-note@#dr360-using-bar {{declared protected here}} int baz = B().baz(); } } // namespace dr360 @@ -942,37 +1088,49 @@ namespace dr364 { // dr364: yes }; void g() { - S::f('a'); // expected-error {{call to non-static}} + S::f('a'); + // expected-error@-1 {{call to non-static member function without an object argument}} S::f(0); } } -#if "foo" // expected-error {{invalid token}} dr366: yes +// dr366: yes +#if "foo" // expected-error {{invalid token at start of a preprocessor expression}} #endif namespace dr367 { // dr367: yes // FIXME: These diagnostics are terrible. Don't diagnose an ill-formed global // array as being a VLA! - int a[true ? throw 0 : 4]; // expected-error 2{{variable length array}} + int a[true ? throw 0 : 4]; + // expected-error@-1 {{variable length arrays in C++ are a Clang extension}} + // expected-error@-2 {{variable length array declaration not allowed at file scope}} int b[true ? 4 : throw 0]; - int c[true ? *new int : 4]; // expected-error 2{{variable length array}} expected-note {{read of uninitialized}} + // cxx98-error@-1 {{variable length arrays in C++ are a Clang extension}} + // cxx98-error@-2 {{variable length array folded to constant array as an extension}} + int c[true ? *new int : 4]; + // expected-error@-1 {{variable length arrays in C++ are a Clang extension}} + // expected-note@-2 {{read of uninitialized object is not allowed in a constant expression}} + // expected-error@-3 {{variable length array declaration not allowed at file scope}} int d[true ? 4 : *new int]; -#if __cplusplus < 201103L - // expected-error@-4 2{{variable length array}} - // expected-error@-3 2{{variable length array}} -#endif + // cxx98-error@-1 {{variable length arrays in C++ are a Clang extension}} + // cxx98-error@-2 {{variable length array folded to constant array as an extension}} } namespace dr368 { // dr368: 3.6 - template<typename T, T> struct S {}; // expected-note {{here}} - template<typename T> int f(S<T, T()> *); // expected-error {{function type}} - template<typename T> int g(S<T, (T())> *); // cxx98_17-note {{type 'X'}} - // cxx20_23-note@-1 {{candidate function [with T = dr368::X]}} - template<typename T> int g(S<T, true ? T() : T()> *); // cxx98_17-note {{type 'X'}} - // cxx20_23-note@-1 {{candidate function [with T = dr368::X]}} + template<typename T, T> struct S {}; // #dr368-S + template<typename T> int f(S<T, T()> *); + // expected-error@-1 {{template argument for non-type template parameter is treated as function type 'T ()'}} + // expected-note@#dr368-S {{template parameter is declared here}} + template<typename T> int g(S<T, (T())> *); // #dr368-g + template<typename T> int g(S<T, true ? T() : T()> *); // #dr368-g-2 struct X {}; - int n = g<X>(0); // cxx98_17-error {{no matching}} - // cxx20_23-error@-1 {{call to 'g' is ambiguous}} + int n = g<X>(0); // #dr368-g-call + // cxx98-17-error@#dr368-g-call {{no matching function for call to 'g'}} + // cxx98-17-note@#dr368-g {{candidate template ignored: substitution failure [with T = X]: a non-type template parameter cannot have type 'X' before C++20}} + // cxx98-17-note@#dr368-g-2 {{candidate template ignored: substitution failure [with T = X]: a non-type template parameter cannot have type 'X' before C++20}} + // cxx20-23-error@#dr368-g-call {{call to 'g' is ambiguous}} + // cxx20-23-note@#dr368-g {{candidate function [with T = dr368::X]}} + // cxx20-23-note@#dr368-g-2 {{candidate function [with T = dr368::X]}} } // dr370: na @@ -981,7 +1139,7 @@ namespace dr372 { // dr372: no namespace example1 { template<typename T> struct X { protected: - typedef T Type; // expected-note 2{{protected}} + typedef T Type; // #dr372-ex1-Type }; template<typename T> struct Y {}; @@ -991,41 +1149,56 @@ namespace dr372 { // dr372: no template<typename> class T1, template<typename> class T2> struct Z1 : T1<T>, - T2<typename T1<T>::Type> {}; // expected-error {{protected}} + T2<typename T1<T>::Type> {}; + // expected-error@-1 {{'Type' is a protected member of 'dr372::example1::X<int>'}} + // expected-note@#dr372-z1 {{in instantiation of template class 'dr372::example1::Z1<int, dr372::example1::X, dr372::example1::Y>' requested here}} + // expected-note@#dr372-ex1-Type {{declared protected here}} template<typename T, template<typename> class T1, template<typename> class T2> struct Z2 : - T2<typename T1<T>::Type>, // expected-error {{protected}} + T2<typename T1<T>::Type>, + // expected-error@-1 {{'Type' is a protected member of 'dr372::example1::X<int>'}} + // expected-note@#dr372-z2 {{in instantiation of template class 'dr372::example1::Z2<int, dr372::example1::X, dr372::example1::Y>' requested here}} + // expected-note@#dr372-ex1-Type {{declared protected here}} T1<T> {}; - Z1<int, X, Y> z1; // expected-note {{instantiation of}} - Z2<int, X, Y> z2; // expected-note {{instantiation of}} + Z1<int, X, Y> z1; // #dr372-z1 + Z2<int, X, Y> z2; // #dr372-z2 } namespace example2 { struct X { private: - typedef int Type; // expected-note {{private}} + typedef int Type; // #dr372-ex2-Type }; template<typename T> struct A { - typename T::Type t; // expected-error {{private}} + typename T::Type t; + // expected-error@-1 {{'Type' is a private member of 'dr372::example2::X'}} + // expected-note@#dr372-ax {{in instantiation of template class 'dr372::example2::A<dr372::example2::X>' requested here}} + // expected-note@#dr372-ex2-Type {{declared private here}} }; - A<X> ax; // expected-note {{instantiation of}} + A<X> ax; // #dr372-ax } namespace example3 { struct A { protected: - typedef int N; // expected-note 2{{protected}} + typedef int N; // #dr372-N }; template<typename T> struct B {}; - template<typename U> struct C : U, B<typename U::N> {}; // expected-error {{protected}} - template<typename U> struct D : B<typename U::N>, U {}; // expected-error {{protected}} - - C<A> x; // expected-note {{instantiation of}} - D<A> y; // expected-note {{instantiation of}} + template<typename U> struct C : U, B<typename U::N> {}; + // expected-error@-1 {{'N' is a protected member of 'dr372::example3::A'}} + // expected-note@#dr372-x {{in instantiation of template class 'dr372::example3::C<dr372::example3::A>' requested here}} + // expected-note@#dr372-N {{declared protected here}} + template<typename U> struct D : B<typename U::N>, U {}; + // expected-error@-1 {{'N' is a protected member of 'dr372::example3::A'}} + // expected-note@#dr372-y {{in instantiation of template class 'dr372::example3::D<dr372::example3::A>' requested here}} + // expected-note@#dr372-N {{declared protected here}} + + C<A> x; // #dr372-x + D<A> y; // #dr372-y } namespace example4 { @@ -1046,37 +1219,46 @@ namespace dr372 { // dr372: no namespace std_example { class A { protected: - struct B {}; // expected-note {{here}} + struct B {}; // #dr372-B-std }; - struct D : A::B, A {}; // expected-error {{protected}} + struct D : A::B, A {}; + // expected-error@-1 {{'B' is a protected member of 'dr372::std_example::A'}} + // expected-note@#dr372-B-std {{declared protected here}} } // FIXME: This is valid: deriving from A::B gives access to A::B! namespace badwolf { class A { protected: - struct B; // expected-note {{here}} + struct B; // #dr372-B }; struct A::B : A {}; - struct C : A::B {}; // expected-error {{protected}} + struct C : A::B {}; + // expected-error@-1 {{'B' is a protected member of 'dr372::badwolf::A'}} + // expected-note@#dr372-B {{declared protected here}} } } namespace dr373 { // dr373: 5 namespace X { int dr373; } - struct dr373 { // expected-note {{here}} + struct dr373 { // #dr373-struct void f() { using namespace dr373::X; - int k = dr373; // expected-error {{does not refer to a value}} - + int k = dr373; + // expected-error@-1 {{'dr373' does not refer to a value}} + // expected-note@#dr373-struct {{declared here}} namespace Y = dr373::X; k = Y::dr373; } }; - struct A { struct B {}; }; // expected-note 2{{here}} - namespace X = A::B; // expected-error {{expected namespace name}} - using namespace A::B; // expected-error {{expected namespace name}} + struct A { struct B {}; }; // #dr373-A + namespace X = A::B; + // expected-error@-1 {{expected namespace name}} + // expected-note@#dr373-A {{'A' declared here}} + using namespace A::B; + // expected-error@-1 {{expected namespace name}} + // expected-note@#dr373-A {{'A' declared here}} } namespace dr374 { // dr374: 7 @@ -1094,9 +1276,13 @@ namespace dr374 { // dr374: 7 // dr376: na namespace dr377 { // dr377: yes - enum E { // expected-error {{enumeration values exceed range of largest integer}} - a = -__LONG_LONG_MAX__ - 1, // expected-error 0-1{{extension}} - b = 2 * (unsigned long long)__LONG_LONG_MAX__ // expected-error 0-2{{extension}} + enum E { + // expected-error@-1 {{enumeration values exceed range of largest integer}} + a = -__LONG_LONG_MAX__ - 1, + // cxx98-error@-1 {{'long long' is a C++11 extension}} + b = 2 * (unsigned long long)__LONG_LONG_MAX__ + // cxx98-error@-1 {{'long long' is a C++11 extension}} + // cxx98-error@-2 {{'long long' is a C++11 extension}} }; } @@ -1114,7 +1300,10 @@ namespace dr381 { // dr381: yes struct F : public A {}; void f() { E e; - e.B::a = 0; // expected-error {{ambiguous conversion}} + e.B::a = 0; + /* expected-error@-1 {{ambiguous conversion from derived class 'E' to base class 'dr381::B': + struct dr381::E -> C -> B + struct dr381::E -> D -> B}} */ F f; f.A::a = 1; } @@ -1124,12 +1313,11 @@ namespace dr382 { // dr382: yes c++11 // FIXME: Should we allow this in C++98 mode? struct A { typedef int T; }; typename A::T t; + // cxx98-error@-1 {{'typename' occurs outside of a template}} typename dr382::A a; -#if __cplusplus < 201103L - // expected-error@-3 {{occurs outside of a template}} - // expected-error@-3 {{occurs outside of a template}} -#endif - typename A b; // expected-error {{expected a qualified name}} + // cxx98-error@-1 {{'typename' occurs outside of a template}} + typename A b; + // expected-error@-1 {{expected a qualified name after 'typename'}} } namespace dr383 { // dr383: yes @@ -1168,23 +1356,32 @@ namespace dr385 { // dr385: 2.8 struct C : A { void g(B b) { b.f(); } }; void h(B b) { b.f(); } - struct D { int n; }; // expected-note {{member}} - struct E : protected D {}; // expected-note {{protected}} + struct D { int n; }; // #dr385-n + struct E : protected D {}; // #dr385-E struct F : E { friend int i(E); }; - int i(E e) { return e.n; } // expected-error {{protected member}} + int i(E e) { return e.n; } + // expected-error@-1 {{'n' is a protected member of 'dr385::D'}} + // expected-note@#dr385-E {{constrained by protected inheritance here}} + // expected-note@#dr385-n {{member is declared here}} } namespace dr387 { // dr387: 2.8 namespace old { template<typename T> class number { - number(int); // expected-note 2{{here}} + number(int); // #dr387-number-ctor friend number gcd(number &x, number &y) {} }; void g() { - number<double> a(3), b(4); // expected-error 2{{private}} + number<double> a(3); + // expected-error@-1 {{calling a private constructor of class 'dr387::old::number<double>'}} + // expected-note@#dr387-number-ctor {{implicitly declared private here}} + number<double> b(4); + // expected-error@-1 {{calling a private constructor of class 'dr387::old::number<double>'}} + // expected-note@#dr387-number-ctor {{implicitly declared private here}} a = gcd(a, b); - b = gcd(3, 4); // expected-error {{undeclared}} + b = gcd(3, 4); + // expected-error@-1 {{use of undeclared identifier 'gcd'}} } } @@ -1198,7 +1395,8 @@ namespace dr387 { // dr387: 2.8 void g() { number<double> a(3), b(4); a = gcd(a, b); - b = gcd(3, 4); // expected-error {{undeclared}} + b = gcd(3, 4); + // expected-error@-1 {{use of undeclared identifier 'gcd'}} } } } @@ -1209,8 +1407,8 @@ namespace dr389 { // dr389: no struct S { typedef struct {} A; typedef enum {} B; - typedef struct {} const C; // expected-note 0-2{{here}} - typedef enum {} const D; // expected-note 0-1{{here}} + typedef struct {} const C; // #dr389-C + typedef enum {} const D; // #dr389-D }; template<typename> struct T {}; @@ -1224,8 +1422,8 @@ namespace dr389 { // dr389: no typedef void (*WithLinkage8)(WithLinkage2 WithLinkage1::*, WithLinkage5 *); typedef T<WithLinkage5> WithLinkage9; - typedef struct {} *WithoutLinkage1; // expected-note 0-1{{here}} - typedef enum {} const WithoutLinkage2; // expected-note 0-1{{here}} + typedef struct {} *WithoutLinkage1; // #dr389-no-link-1 + typedef enum {} const WithoutLinkage2; // #dr389-no-link-2 // These two types don't have linkage even though they are externally visible // and the ODR requires them to be merged across TUs. typedef S::C WithoutLinkage3; @@ -1251,11 +1449,21 @@ namespace dr389 { // dr389: no typedef T<WithLinkage8> GoodArg8; typedef T<WithLinkage9> GoodArg9; - typedef T<WithoutLinkage1> BadArg1; // expected-error{{template argument uses}} - typedef T<WithoutLinkage2> BadArg2; // expected-error{{template argument uses}} - typedef T<WithoutLinkage3> BadArg3; // expected-error{{template argument uses}} - typedef T<WithoutLinkage4> BadArg4; // expected-error{{template argument uses}} - typedef T<WithoutLinkage5> BadArg5; // expected-error{{template argument uses}} + typedef T<WithoutLinkage1> BadArg1; + // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#dr389-no-link-1 {{unnamed type used in template argument was declared here}} + typedef T<WithoutLinkage2> BadArg2; + // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#dr389-no-link-2 {{unnamed type used in template argument was declared here}} + typedef T<WithoutLinkage3> BadArg3; + // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#dr389-C {{unnamed type used in template argument was declared here}} + typedef T<WithoutLinkage4> BadArg4; + // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#dr389-D {{unnamed type used in template argument was declared here}} + typedef T<WithoutLinkage5> BadArg5; + // expected-error@-1 {{template argument uses unnamed type}} + // expected-note@#dr389-C {{unnamed type used in template argument was declared here}} #endif extern WithLinkage1 withLinkage1; @@ -1320,32 +1528,36 @@ namespace dr389 { // dr389: no namespace dr390 { // dr390: 3.3 template<typename T> struct A { - A() { f(); } // expected-warning {{call to pure virt}} - virtual void f() = 0; // expected-note {{here}} + A() { f(); } + // expected-warning@-1 {{call to pure virtual member function 'f' has undefined behavior; overrides of 'f' in subclasses are not available in the constructor of 'dr390::A<int>'}} + // expected-note@#dr390-A-int {{in instantiation of member function 'dr390::A<int>::A' requested here}} + // expected-note@#dr390-f {{'f' declared here}} + virtual void f() = 0; // #dr390-f virtual ~A() = 0; }; - template<typename T> A<T>::~A() { T::error; } // expected-error {{cannot be used prior to}} + template<typename T> A<T>::~A() { T::error; } + // expected-error@-1 {{type 'int' cannot be used prior to '::' because it has no members}} + // expected-note@#dr390-A-int {{in instantiation of member function 'dr390::A<int>::~A' requested here}} template<typename T> void A<T>::f() { T::error; } // ok, not odr-used - struct B : A<int> { // expected-note 2{{in instantiation of}} + struct B : A<int> { // #dr390-A-int void f() {} } b; } namespace dr391 { // dr391: 2.8 c++11 // FIXME: Should this apply to C++98 too? - class A { A(const A&); }; // expected-note 0-1{{here}} + class A { A(const A&); }; // #dr391-A A fa(); const A &a = fa(); -#if __cplusplus < 201103L - // expected-error@-2 {{C++98 requires an accessible copy constructor}} -#endif + // cxx98-error@-1 {{C++98 requires an accessible copy constructor for class 'dr391::A' when binding a reference to a temporary; was private}} + // cxx98-note@#dr391-A {{implicitly declared private here}} - struct B { B(const B&) = delete; }; // expected-error 0-1{{extension}} expected-note 0-1{{here}} + struct B { B(const B&) = delete; }; // #dr391-B + // cxx98-error@-1 {{deleted function definitions are a C++11 extension}} B fb(); const B &b = fb(); -#if __cplusplus < 201103L - // expected-error@-2 {{deleted}} -#endif + // cxx98-error@-1 {{copying variable of type 'B' invokes deleted constructor}} + // cxx98-note@#dr391-B {{'B' has been explicitly marked deleted here}} template<typename T> struct C { @@ -1360,11 +1572,20 @@ namespace dr391 { // dr391: 2.8 c++11 namespace dr395 { // dr395: 3.0 struct S { - template <typename T, int N>(&operator T())[N]; // expected-error {{cannot specify any part of a return type}} - template <typename T, int N> operator(T (&)[N])(); // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error +{{}} + template <typename T, int N>(&operator T())[N]; + // expected-error@-1 {{cannot specify any part of a return type in the declaration of a conversion function}} + template <typename T, int N> operator(T (&)[N])(); + // expected-error@-1 {{expected ')'}} + // expected-note@-2 {{to match this '('}} + // expected-error@-3 {{a type specifier is required for all declarations}} template <typename T> operator T *() const { return 0; } template <typename T, typename U> operator T U::*() const { return 0; } - template <typename T, typename U> operator T (U::*)()() const { return 0; } // expected-error +{{}} + template <typename T, typename U> operator T (U::*)()() const { return 0; } + // expected-error@-1 {{a type specifier is required for all declarations}} + // expected-error@-2 {{conversion function cannot have any parameters}} + // expected-error@-3 {{cannot specify any part of a return type in the declaration of a conversion function}} + // expected-error@-4 {{conversion function cannot convert to a function type}} + }; struct null1_t { @@ -1373,13 +1594,16 @@ namespace dr395 { // dr395: 3.0 }; template <class T, class U> - operator typename ptr_mem_fun_t<T, U>::type() const { // expected-note {{couldn't infer}} + operator typename ptr_mem_fun_t<T, U>::type() const { // #dr395-conv-func return 0; } } null1; - int (S::*p)() = null1; // expected-error {{no viable conversion}} + int (S::*p)() = null1; + // expected-error@-1 {{no viable conversion from 'struct null1_t' to 'int (dr395::S::*)()'}} + // expected-note@#dr395-conv-func {{candidate template ignored: couldn't infer template argument 'T'}} - template <typename T> using id = T; // expected-error 0-1{{extension}} + template <typename T> using id = T; + // cxx98-error@-1 {{alias declarations are a C++11 extension}} struct T { template <typename T, int N> operator id<T[N]> &(); @@ -1387,7 +1611,8 @@ namespace dr395 { // dr395: 3.0 }; struct null2_t { - template<class T, class U> using ptr_mem_fun_t = T (U::*)(); // expected-error 0-1{{extension}} + template<class T, class U> using ptr_mem_fun_t = T (U::*)(); + // cxx98-error@-1 {{alias declarations are a C++11 extension}} template<class T, class U> operator ptr_mem_fun_t<T, U>() const { return 0; }; } null2; int (S::*q)() = null2; @@ -1395,12 +1620,14 @@ namespace dr395 { // dr395: 3.0 namespace dr396 { // dr396: yes void f() { - auto int a(); // expected-error {{storage class on function}} - int (i); // expected-note {{previous}} - auto int (i); // expected-error {{redefinition}} -#if __cplusplus >= 201103L - // expected-error@-4 {{'auto' storage class}} expected-error@-2 {{'auto' storage class}} -#endif + auto int a(); + // since-cxx11-error@-1 {{'auto' storage class specifier is not permitted in C++11, and will not be supported in future releases}} + // expected-error@-2 {{illegal storage class on function}} + int (i); // #dr396-i + auto int (i); + // since-cxx11-error@-1 {{'auto' storage class specifier is not permitted in C++11, and will not be supported in future releases}} + // expected-error@-2 {{redefinition of 'i'}} + // expected-note@#dr396-i {{previous definition is here}} } } @@ -1420,9 +1647,9 @@ namespace dr398 { // dr398: yes namespace example2 { template <int I> struct X {}; template <template <class T> class> struct Z {}; - template <class T> void f(typename T::Y *) {} // expected-note 2{{substitution failure}} - template <class T> void g(X<T::N> *) {} // expected-note {{substitution failure}} - template <class T> void h(Z<T::template TT> *) {} // expected-note {{substitution failure}} + template <class T> void f(typename T::Y *) {} // #dr398-f + template <class T> void g(X<T::N> *) {} // #dr398-g + template <class T> void h(Z<T::template TT> *) {} // #dr398-h struct A {}; struct B { int Y; @@ -1435,17 +1662,25 @@ namespace dr398 { // dr398: yes }; void test() { - f<A>(0); // expected-error {{no matching function}} - f<B>(0); // expected-error {{no matching function}} - g<C>(0); // expected-error {{no matching function}} - h<D>(0); // expected-error {{no matching function}} + f<A>(0); + // expected-error@-1 {{no matching function for call to 'f'}} + // expected-note@#dr398-f {{candidate template ignored: substitution failure [with T = A]: no type named 'Y' in 'dr398::example2::A'}} + f<B>(0); + // expected-error@-1 {{no matching function for call to 'f'}} + // expected-note@#dr398-f {{candidate template ignored: substitution failure [with T = B]: typename specifier refers to non-type member 'Y' in 'dr398::example2::B'}} + g<C>(0); + // expected-error@-1 {{no matching function for call to 'g'}} + // expected-note@#dr398-g {{candidate template ignored: substitution failure [with T = C]: missing 'typename' prior to dependent type name 'C::N'}} + h<D>(0); + // expected-error@-1 {{no matching function for call to 'h'}} + // expected-note@#dr398-h {{candidate template ignored: substitution failure [with T = D]: 'TT' following the 'template' keyword does not refer to a template}} } } } namespace dr399 { // dr399: 11 - // NB: reuse dr244 test - struct B {}; // expected-note {{type 'dr399::B' found by destructor name lookup}} + // NB: reuse dr244 test + struct B {}; // #dr399-B struct D : B {}; D D_object; @@ -1453,15 +1688,19 @@ namespace dr399 { // dr399: 11 B* B_ptr = &D_object; void f() { - D_object.~B(); // expected-error {{does not match the type 'D' of the object being destroyed}} + D_object.~B(); + // expected-error@-1 {{destructor type 'dr399::B' in object destruction expression does not match the type 'D' of the object being destroyed}} + // expected-note@#dr399-B {{type 'dr399::B' found by destructor name lookup}} D_object.B::~B(); D_object.D::~B(); // FIXME: Missing diagnostic for this. B_ptr->~B(); B_ptr->~B_alias(); B_ptr->B_alias::~B(); B_ptr->B_alias::~B_alias(); - B_ptr->dr399::~B(); // expected-error {{refers to a member in namespace}} - B_ptr->dr399::~B_alias(); // expected-error {{refers to a member in namespace}} + B_ptr->dr399::~B(); + // expected-error@-1 {{qualified member access refers to a member in namespace 'dr399'}} + B_ptr->dr399::~B_alias(); + // expected-error@-1 {{qualified member access refers to a member in namespace 'dr399'}} } template<typename T, typename U> @@ -1473,8 +1712,10 @@ namespace dr399 { // dr399: 11 B_ptr->~B_alias(); B_ptr->B_alias::~B(); B_ptr->B_alias::~B_alias(); - B_ptr->dr399::~B(); // expected-error {{does not refer to a type name}} - B_ptr->dr399::~B_alias(); // expected-error {{does not refer to a type name}} + B_ptr->dr399::~B(); + // expected-error@-1 {{'dr399' does not refer to a type name in pseudo-destructor expression; expected the name of type 'T'}} + B_ptr->dr399::~B_alias(); + // expected-error@-1 {{'dr399' does not refer to a type name in pseudo-destructor expression; expected the name of type 'T'}} } template void f<B, D>(B*, D); @@ -1483,21 +1724,26 @@ namespace dr399 { // dr399: 11 typedef E<int> F; } void g(N::F f) { - typedef N::F G; // expected-note {{found by destructor name lookup}} + typedef N::F G; // #dr399-G f.~G(); - f.G::~E(); // expected-error {{ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~'}} - f.G::~F(); // expected-error {{undeclared identifier 'F' in destructor name}} + f.G::~E(); + // expected-error@-1 {{ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~'}} + f.G::~F(); + // expected-error@-1 {{undeclared identifier 'F' in destructor name}} f.G::~G(); // This is technically ill-formed; E is looked up in 'N::' and names the // class template, not the injected-class-name of the class. But that's // probably a bug in the standard. - f.N::F::~E(); // expected-error {{ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~'}} + f.N::F::~E(); + // expected-error@-1 {{ISO C++ requires the name after '::~' to be found in the same scope as the name before '::~'}} // This is valid; we look up the second F in the same scope in which we // found the first one, that is, 'N::'. f.N::F::~F(); // This is technically ill-formed; G is looked up in 'N::' and is not found. // Rejecting this seems correct, but most compilers accept, so we do also. - f.N::F::~G(); // expected-error {{qualified destructor name only found in lexical scope; omit the qualifier to find this type name by unqualified lookup}} + f.N::F::~G(); + // expected-error@-1 {{qualified destructor name only found in lexical scope; omit the qualifier to find this type name by unqualified lookup}} + // expected-note@#dr399-G {{type 'G' (aka 'E<int>') found by destructor name lookup}} } // Bizarrely, compilers perform lookup in the scope for qualified destructor @@ -1509,15 +1755,18 @@ namespace dr399 { // dr399: 11 } template <typename U> void f(typename N::S<U>::Inner *p) { typedef typename N::S<U>::Inner T; - p->::dr399::QualifiedLookupInScope::N::S<U>::Inner::~T(); // expected-error {{no type named 'T' in}} + p->::dr399::QualifiedLookupInScope::N::S<U>::Inner::~T(); + // expected-error@-1 {{no type named 'T' in 'dr399::QualifiedLookupInScope::N::S<int>'}} + // expected-note@#dr399-f {{in instantiation of function template specialization 'dr399::QualifiedLookupInScope::f<int>' requested here}} } - template void f<int>(N::S<int>::Inner *); // expected-note {{instantiation of}} + template void f<int>(N::S<int>::Inner *); // #dr399-f template <typename U> void g(U *p) { typedef U T; p->T::~T(); p->U::~T(); - p->::dr399::QualifiedLookupInScope::N::S<int>::Inner::~T(); // expected-error {{'T' does not refer to a type name}} + p->::dr399::QualifiedLookupInScope::N::S<int>::Inner::~T(); + // expected-error@-1 {{'T' does not refer to a type name in pseudo-destructor expression; expected the name of type 'U'}} } template void g(N::S<int>::Inner *); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits