diff options
| author | Vlad Serebrennikov <serebrennikov.vladislav@gmail.com> | 2026-02-11 01:09:20 +0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-10 21:09:20 +0000 |
| commit | 604e4adef0f09fec00a618f003d3a8108f4c576d (patch) | |
| tree | c7b8d8c241740e1a4d558bebbec7b1eee2e78d92 | |
| parent | 49c052363b4ff1a66dddee5525cdaeb215ccd244 (diff) | |
| download | llvm-604e4adef0f09fec00a618f003d3a8108f4c576d.tar.gz llvm-604e4adef0f09fec00a618f003d3a8108f4c576d.tar.bz2 llvm-604e4adef0f09fec00a618f003d3a8108f4c576d.zip | |
[clang] Non-trivial fixes in C++ DR tests (#179813)
This is a follow-up to #179674, which applies various fixes across C++
DR tests uncovered by `-verify-directives` (#179835
).
Changes here serve double duty. First, they fix actual problems found by
`-verify-directives`, because I've been manually enforcing those rules
manually for quite a while. Second, they show typical problems and
possible solutions when you opt-in a test to use `-verify-directives`.
This PR focuses on interesting cases, as partial diagnostic matches,
which are trivial to fix, are fixed in boring #179674
Changes include:
1. Getting rid of instantiations at the end of TU that emit diagnostics:
either trigger them earlier, or move them to a separate file
2. Reordering of `expected-error` and `expected-note` to match the order
in which corresponding diagnsotics are emitted.
3. Eliminating leftover partial matches of diagnostic text
4. Removing some extension warnings, because C++ DR tests are not
interested in features backported to older language modes.
5. Fix for a hilarious case of CWG413 test, which was checking for a
note from a typo correction that happened in another test.
26 files changed, 712 insertions, 615 deletions
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp index 6d3a3238d4f3..793ef5c7e2fd 100644 --- a/clang/test/CXX/drs/cwg0xx.cpp +++ b/clang/test/CXX/drs/cwg0xx.cpp @@ -484,7 +484,7 @@ namespace cwg33 { // cwg33: 9 template<typename T> void t(X::S); template<typename T, typename U = void> void u(X::S); - // expected-error@-1 0-1 {{default template arguments for a function template are a C++11 extension}} + // cxx98-error@-1 {{default template arguments for a function template are a C++11 extension}} void templ() { f(t<int>); f(u<int>); } // Even though v<int> cannot select the first overload, ADL considers it @@ -1042,16 +1042,16 @@ namespace cwg62 { // cwg62: 2.9 // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} NoNameForLinkagePtr p1 = get<NoNameForLinkagePtr>(); // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@-2 {{while substituting explicitly-specified template arguments into function template 'get'}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} - // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} NoNameForLinkagePtr p2 = get<const NoNameForLinkagePtr>(); // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@-2 {{while substituting explicitly-specified template arguments into function template 'get'}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} - // cxx98-note@-3 {{while substituting explicitly-specified template arguments}} int n1 = take(noNameForLinkagePtr); // cxx98-error@-1 {{template argument uses unnamed type}} + // cxx98-note@-2 {{while substituting deduced template arguments into function template 'take' [with T = NoNameForLinkagePtr]}} // cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}} - // cxx98-note@-3 {{while substituting deduced template arguments}} X<Danger> x4; @@ -1378,9 +1378,10 @@ namespace cwg92 { // cwg92: 4 c++17 // considered in this context. In C++17, we *do* perform an implicit // conversion (which performs initialization), and the exception specification // is part of the type of the parameter, so this is invalid. - template<void() throw()> struct X {}; // since-cxx17-note {{template parameter is declared here}} + template<void() throw()> struct X {}; // #cwg92-X X<&f> xp; // since-cxx17-error@-1 {{value of type 'void (*)() throw(int, float)' is not implicitly convertible to 'void (*)() throw()'}} + // since-cxx17-note@#cwg92-X {{template parameter is declared here}} template<void() throw(int)> struct Y {}; // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}} @@ -1440,33 +1441,7 @@ namespace cwg97 { // cwg97: 2.7 }; } // namespace cwg97 -namespace cwg98 { // cwg98: 2.7 - void test(int n) { - switch (n) { - try { // #cwg98-try - case 0: - // expected-error@-1 {{cannot jump from switch statement to this case label}} - // expected-note@#cwg98-try {{jump bypasses initialization of try block}} - x: - throw n; - } catch (...) { // #cwg98-catch - case 1: - // expected-error@-1 {{cannot jump from switch statement to this case label}} - // expected-note@#cwg98-catch {{jump bypasses initialization of catch block}} - y: - throw n; - } - case 2: - goto x; - // expected-error@-1 {{cannot jump from this goto statement to its label}} - // expected-note@#cwg98-try {{jump bypasses initialization of try block}} - case 3: - goto y; - // expected-error@-1 {{cannot jump from this goto statement to its label}} - // expected-note@#cwg98-catch {{jump bypasses initialization of catch block}} - } - } -} // namespace cwg98 +// cwg98 is in cwg98.cpp namespace cwg99 { // cwg99: sup 214 template<typename T> void f(T&); diff --git a/clang/test/CXX/drs/cwg10xx.cpp b/clang/test/CXX/drs/cwg10xx.cpp index c5b96c4ab8ff..f0aaa174d6c0 100644 --- a/clang/test/CXX/drs/cwg10xx.cpp +++ b/clang/test/CXX/drs/cwg10xx.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors namespace std { __extension__ typedef __SIZE_TYPE__ size_t; @@ -41,8 +41,9 @@ namespace cwg1004 { // cwg1004: 5 // This example (from the standard) is actually ill-formed, because // name lookup of "T::template A" names the constructor. template<class T, template<class> class U = T::template A> struct Third { }; - // expected-error@-1 {{is a constructor name}} - // expected-note@#cwg1004-t {{in instantiation of default argument}} + // expected-error@-1 {{ISO C++ specifies that qualified reference to 'A' is a constructor name rather than a template name in this context, despite preceding 'typename' keyword}} + // cxx98-note@#cwg1004-t {{in instantiation of default argument for 'Third<A<int> >' required here}} + // since-cxx11-note@#cwg1004-t {{in instantiation of default argument for 'Third<A<int>>' required here}} Third<A<int> > t; // #cwg1004-t } // namespace cwg1004 diff --git a/clang/test/CXX/drs/cwg13xx.cpp b/clang/test/CXX/drs/cwg13xx.cpp index 0f97c484becd..29d66ffb9241 100644 --- a/clang/test/CXX/drs/cwg13xx.cpp +++ b/clang/test/CXX/drs/cwg13xx.cpp @@ -79,47 +79,40 @@ namespace cwg1310 { // cwg1310: 5 W<int>::W<int> w1b; // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a template name in this context}} W<int>::W<int>::X w1bx; +#if __cplusplus >= 201103L typename W<int>::W w2a; - // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a type in this context, despite preceding 'typename' keyword}} - // cxx98-error@-2 {{'typename' outside of a template is a C++11 extension}} + // since-cxx11-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a type in this context, despite preceding 'typename' keyword}} typename W<int>::W::X w2ax; - // cxx98-error@-1 {{'typename' outside of a template is a C++11 extension}} typename W<int>::W<int> w2b; - // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'typename' keyword}} - // cxx98-error@-2 {{'typename' outside of a template is a C++11 extension}} + // since-cxx11-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'typename' keyword}} typename W<int>::W<int>::X w2bx; - // cxx98-error@-1 {{'typename' outside of a template is a C++11 extension}} W<int>::template W<int> w3; - // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} - // cxx98-error@-2 {{'template' keyword outside of a template}} + // since-cxx11-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} W<int>::template W<int>::X w3x; - // cxx98-error@-1 {{'template' keyword outside of a template}} typename W<int>::template W<int> w4; - // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} - // cxx98-error@-2 {{'template' keyword outside of a template}} - // cxx98-error@-3 {{'typename' outside of a template is a C++11 extension}} + // since-cxx11-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} typename W<int>::template W<int>::X w4x; - // cxx98-error@-1 {{'template' keyword outside of a template}} - // cxx98-error@-2 {{'typename' outside of a template is a C++11 extension}} +#endif TT<W<int>::W> tt1; // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a type in this context}} TTy<W<int>::W> tt1a; // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a type in this context}} - TT<W<int>::template W> tt2; - // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} - // cxx98-error@-2 {{'template' keyword outside of a template}} TT<W<int>::WBase> tt3; TTy<W<int>::WBase> tt3a; +#if __cplusplus >= 201103L + TT<W<int>::template W> tt2; + // since-cxx11-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}} TT<W<int>::template WBase> tt4; - // cxx98-error@-1 {{'template' keyword outside of a template}} +#endif W<int> w; (void)w.W::W::n; (void)w.W<int>::W::n; (void)w.W<int>::W<int>::n; +#if __cplusplus >= 201103L (void)w.W<int>::template W<int>::n; - // cxx98-error@-1 {{'template' keyword outside of a template}} +#endif } template<typename W> @@ -260,19 +253,18 @@ namespace cwg1330 { // cwg1330: 4 c++11 static_assert(!noexcept(B<Q>().g()), ""); #endif +#if __cplusplus <= 201402L template<typename T> int f() throw(typename T::error) { return 0; } // #cwg1330-f - // expected-error@#cwg1330-f {{type 'int' cannot be used prior to '::' because it has no members}} + // cxx98-14-error@#cwg1330-f {{type 'int' cannot be used prior to '::' because it has no members}} // cxx98-note@#cwg1330-f-int {{in instantiation of function template specialization 'cwg1330::f<int>' requested here}} - // since-cxx11-note@#cwg1330-f-int {{in instantiation of exception specification for 'f<int>' requested here}} + // cxx11-14-note@#cwg1330-f-int {{in instantiation of exception specification for 'f<int>' requested here}} + // cxx11-14-error@#cwg1330-f {{type 'char' cannot be used prior to '::' because it has no members}} + // cxx11-14-note@#cwg1330-f-char {{in instantiation of exception specification for 'f<char>' requested here}} + // cxx11-14-error@#cwg1330-f {{type 'float' cannot be used prior to '::' because it has no members}} + // cxx11-14-note@#cwg1330-f-float {{in instantiation of exception specification for 'f<float>' requested here}} // cxx98-14-error@#cwg1330-f {{type 'short' cannot be used prior to '::' because it has no members}} - // cxx98-14-note@#cwg1330-f-short {{in instantiation of function template specialization 'cwg1330::f<short>' requested here}} // cxx11-14-note@#cwg1330-f {{in instantiation of exception specification for 'f<short>' requested here}} - // since-cxx11-error@#cwg1330-f {{type 'char' cannot be used prior to '::' because it has no members}} - // since-cxx11-note@#cwg1330-f-char {{in instantiation of exception specification for 'f<char>' requested here}} - // since-cxx11-error@#cwg1330-f {{type 'float' cannot be used prior to '::' because it has no members}} - // since-cxx11-note@#cwg1330-f-float {{in instantiation of exception specification for 'f<float>' requested here}} - // since-cxx17-error@#cwg1330-f {{ISO C++17 does not allow dynamic exception specifications}} - // since-cxx17-note@#cwg1330-f {{use 'noexcept(false)' instead}} + // cxx98-14-note@#cwg1330-f-short {{in instantiation of function template specialization 'cwg1330::f<short>' requested here}} // An exception-specification is needed even if the function is only used in // an unevaluated operand. @@ -282,9 +274,7 @@ namespace cwg1330 { // cwg1330: 4 c++11 bool f3 = noexcept(f<float>()); /// #cwg1330-f-float #endif template int f<short>(); // #cwg1330-f-short - // since-cxx17-error@#cwg1330-f {{type 'short' cannot be used prior to '::' because it has no members}} - // since-cxx17-note@#cwg1330-f {{in instantiation of exception specification for 'f<short>' requested here}} - // since-cxx17-note@#cwg1330-f-short {{in instantiation of function template specialization 'cwg1330::f<short>' requested here}} +#endif template<typename T> struct C { C() throw(typename T::type); // #cwg1330-C @@ -358,22 +348,17 @@ namespace cwg1346 { // cwg1346: 3.5 } template void f(); // #cwg1346-f -#if __cplusplus >= 201103L +#if __cplusplus >= 201402L void init_capture() { [a(1)] {} (); - // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}} [b(1, 2)] {} (); - // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}} - // since-cxx11-error@-2 {{initializer for lambda capture 'b' contains multiple expressions}} + // since-cxx14-error@-1 {{initializer for lambda capture 'b' contains multiple expressions}} [c({})] {} (); - // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}} - // since-cxx11-error@-2 {{cannot deduce type for lambda capture 'c' from parenthesized initializer list}} + // since-cxx14-error@-1 {{cannot deduce type for lambda capture 'c' from parenthesized initializer list}} [d({1})] {} (); - // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}} - // since-cxx11-error@-2 {{cannot deduce type for lambda capture 'd' from parenthesized initializer list}} + // since-cxx14-error@-1 {{cannot deduce type for lambda capture 'd' from parenthesized initializer list}} [e({1, 2})] {} (); - // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}} - // since-cxx11-error@-2 {{cannot deduce type for lambda capture 'e' from parenthesized initializer list}} + // since-cxx14-error@-1 {{cannot deduce type for lambda capture 'e' from parenthesized initializer list}} } #endif } // namespace cwg1346 diff --git a/clang/test/CXX/drs/cwg15xx.cpp b/clang/test/CXX/drs/cwg15xx.cpp index 8e3e49dc42ce..e97584c293cc 100644 --- a/clang/test/CXX/drs/cwg15xx.cpp +++ b/clang/test/CXX/drs/cwg15xx.cpp @@ -38,22 +38,40 @@ namespace cwg1512 { // cwg1512: 4 template<typename A, typename B, typename C> void composite_pointer_type_is_ord() { composite_pointer_type_is_base<A, B, C>(); - typedef __typeof(val<A>() < val<B>()) cmp; // #cwg1512-lt - // since-cxx17-warning@#cwg1512-lt {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} - // since-cxx17-note@#cwg1512-noexcept-1st {{in instantiation of function template specialization 'cwg1512::composite_pointer_type_is_ord<int (*)() noexcept, int (*)(), int (*)()>' requested here}} - // since-cxx17-warning@#cwg1512-lt {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} - // since-cxx17-note@#cwg1512-noexcept-2nd {{in instantiation of function template specialization 'cwg1512::composite_pointer_type_is_ord<int (*)(), int (*)() noexcept, int (*)()>' requested here}} + typedef __typeof(val<A>() < val<B>()) cmp; typedef __typeof(val<A>() <= val<B>()) cmp; - // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} - // since-cxx17-warning@-2 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} typedef __typeof(val<A>() > val<B>()) cmp; - // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} - // since-cxx17-warning@-2 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} typedef __typeof(val<A>() >= val<B>()) cmp; + typedef bool cmp; + } + +#if __cplusplus >= 201703L + void composite_pointer_type_is_ord_2() { + composite_pointer_type_is_base<int (*)() noexcept, int (*)(), int (*)()>(); + + typedef __typeof(val<int (*)() noexcept>() < val<int (*)()>()) cmp; + // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} + typedef __typeof(val<int (*)() noexcept>() <= val<int (*)()>()) cmp; + // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} + typedef __typeof(val<int (*)() noexcept>() > val<int (*)()>()) cmp; + // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} + typedef __typeof(val<int (*)() noexcept>() >= val<int (*)()>()) cmp; // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}} - // since-cxx17-warning@-2 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} + + composite_pointer_type_is_base<int (*)(), int (*)() noexcept, int (*)()>(); + + typedef __typeof(val<int (*)()>() < val<int (*)() noexcept>()) cmp; + // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} + typedef __typeof(val<int (*)()>() <= val<int (*)() noexcept>()) cmp; + // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} + typedef __typeof(val<int (*)()>() > val<int (*)() noexcept>()) cmp; + // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} + typedef __typeof(val<int (*)()>() >= val<int (*)() noexcept>()) cmp; + // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}} + typedef bool cmp; } +#endif template <typename A, typename B, typename C> void composite_pointer_type_is_unord(int = 0) { @@ -100,8 +118,6 @@ namespace cwg1512 { // cwg1512: 4 // since-cxx20-warning@-1 {{volatile-qualified return type 'volatile int' is deprecated}} #if __cplusplus >= 201703L - composite_pointer_type_is_ord<int (*)() noexcept, int (*)(), int (*)()>(); // #cwg1512-noexcept-1st - composite_pointer_type_is_ord<int (*)(), int (*)() noexcept, int (*)()>(); // #cwg1512-noexcept-2nd composite_pointer_type_is_unord<int (A::*)() noexcept, int (A::*)(), int (A::*)()>(); composite_pointer_type_is_unord<int (A::*)(), int (A::*)() noexcept, int (A::*)()>(); // FIXME: This looks like a standard defect; these should probably all have type 'int (B::*)()'. @@ -157,15 +173,15 @@ namespace cwg1512 { // cwg1512: 4 // since-cxx11-note@#cwg1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}} // since-cxx11-note@#cwg1512-Wrap {{second operand was implicitly converted to type 'int *'}} void(Wrap<nullptr_t>() > Wrap<int*>()); - // since-cxx11-error@-1 {{invalid operands}} + // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<int *>')}} // since-cxx11-note@#cwg1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}} // since-cxx11-note@#cwg1512-Wrap{{second operand was implicitly converted to type 'int *'}} void(Wrap<nullptr_t>() <= Wrap<int*>()); - // since-cxx11-error@-1 {{invalid operands}} + // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<int *>')}} // since-cxx11-note@#cwg1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}} // since-cxx11-note@#cwg1512-Wrap {{second operand was implicitly converted to type 'int *'}} void(Wrap<nullptr_t>() >= Wrap<int*>()); - // since-cxx11-error@-1 {{invalid operands}} + // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<int *>')}} // since-cxx11-note@#cwg1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}} // since-cxx11-note@#cwg1512-Wrap {{second operand was implicitly converted to type 'int *'}} } @@ -309,16 +325,14 @@ namespace std_example { // since-cxx11-note@#cwg1518-x {{passing argument to parameter 't' here}} } - void test() { - f<A>(); // #cwg1518-f-A - f<B>(); // #cwg1518-f-B - f<C>(); // #cwg1518-f-C - f<D>(); // #cwg1518-f-D - g<A>(); // #cwg1518-g-A - g<B>(); // #cwg1518-g-B - g<C>(); // #cwg1518-g-C - g<D>(); // #cwg1518-g-D - } + template void f<A>(); // #cwg1518-f-A + template void f<B>(); // #cwg1518-f-B + template void f<C>(); // #cwg1518-f-C + template void f<D>(); // #cwg1518-f-D + template void g<A>(); // #cwg1518-g-A + template void g<B>(); // #cwg1518-g-B + template void g<C>(); // #cwg1518-g-C + template void g<D>(); // #cwg1518-g-D } #endif // __cplusplus >= 201103L } // namespace cwg1518 @@ -426,8 +440,8 @@ namespace cwg1573 { // cwg1573: 3.9 constexpr F f = F(0); // since-cxx11-error@-1 {{constexpr variable 'f' must be initialized by a constant expression}} // cxx11-20-note@-2 {{constructor inherited from base class 'C' cannot be used in a constant expression; derived class cannot be implicitly initialized}} - // since-cxx23-note@-3 {{in implicit initialization for inherited constructor of 'F'}} // since-cxx23-note@#cwg1573-F {{non-constexpr constructor 'C' cannot be used in a constant expression}} + // since-cxx23-note@-4 {{in implicit initialization for inherited constructor of 'F'}} // cxx11-20-note@#cwg1573-F {{declared here}} // since-cxx23-note@#cwg1573-C {{declared here}} @@ -564,16 +578,18 @@ namespace cwg1584 { // cwg1584: 7 drafting 2015-05 // Deducing function types from cv-qualified types template<typename T> void f(const T *); // #cwg1584-f template<typename T> void g(T *, const T * = 0); -template<typename T> void h(T *) { T::error; } -// expected-error@-1 {{type 'void ()' cannot be used prior to '::' because it has no members}} -// expected-note@#cwg1584-h {{in instantiation of function template specialization 'cwg1584::h<void ()>' requested here}} -template<typename T> void h(const T *); +template<typename T> void h(T *) = delete; // #cwg1584-h-T +// cxx98-error@-1 {{deleted function definitions are a C++11 extension}} +template<typename T> void h(const T *); // #cwg1584-h-const-T void i() { f(&i); // expected-error@-1 {{no matching function for call to 'f'}} // expected-note@#cwg1584-f {{candidate template ignored: could not match 'const T *' against 'void (*)()'}} g(&i); - h(&i); // #cwg1584-h + h(&i); + // expected-error@-1 {{call to deleted function 'h'}} + // expected-note@#cwg1584-h-T {{candidate function [with T = void ()] has been explicitly deleted}} + // expected-note@#cwg1584-h-const-T {{candidate template ignored: could not match 'const T *' against 'void (*)()'}} } template<typename T> struct tuple_size { diff --git a/clang/test/CXX/drs/cwg16xx.cpp b/clang/test/CXX/drs/cwg16xx.cpp index 1a36aba859e5..efb743871d52 100644 --- a/clang/test/CXX/drs/cwg16xx.cpp +++ b/clang/test/CXX/drs/cwg16xx.cpp @@ -266,12 +266,14 @@ namespace cwg1658 { // cwg1658: 5 struct A { A(A&); }; struct B : virtual A { virtual void f() = 0; }; struct C : virtual A { virtual void f(); }; - struct D : A { virtual void f() = 0; }; // since-cxx23-note {{previous declaration is here}} + struct D : A { virtual void f() = 0; }; // #cwg1658-D struct X { friend B::B(const B&) throw(); friend C::C(C&); - friend D::D(D&); // since-cxx23-error {{non-constexpr declaration of 'D' follows constexpr declaration}} + friend D::D(D&); + // since-cxx23-error@-1 {{non-constexpr declaration of 'D' follows constexpr declaration}} + // since-cxx23-note@#cwg1658-D {{previous declaration is here}} }; } @@ -373,7 +375,6 @@ namespace cwg1687 { // cwg1687: 7 int *a = To<int*>() + 100.0; // expected-error@-1 {{invalid operands to binary expression ('To<int *>' and 'double')}} // expected-note@#cwg1687-op-T {{first operand was implicitly converted to type 'int *'}} - // since-cxx20-note@#cwg1687-op-T {{second operand was implicitly converted to type 'cwg1687::E2'}} int *b = To<int*>() + To<double>(); // expected-error@-1 {{invalid operands to binary expression ('To<int *>' and 'To<double>')}} // expected-note@#cwg1687-op-T {{first operand was implicitly converted to type 'int *'}} @@ -384,7 +385,8 @@ namespace cwg1687 { // cwg1687: 7 enum E2 {}; auto c = To<E1>() <=> To<E2>(); // since-cxx20-error@-1 {{invalid operands to binary expression ('To<E1>' and 'To<E2>')}} - // since-cxx20-note@#cwg1687-op-T {{operand was implicitly converted to type 'cwg1687::E}} + // since-cxx20-note@#cwg1687-op-T {{first operand was implicitly converted to type 'cwg1687::E1'}} + // since-cxx20-note@#cwg1687-op-T {{second operand was implicitly converted to type 'cwg1687::E2'}} #endif } // namespace cwg1687 @@ -458,13 +460,13 @@ namespace cwg1696 { // cwg1696: 7 }; struct A2 { - A2() = default; - // since-cxx14-error@-1 {{reference member 'v' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} - // since-cxx14-note-re@#cwg1696-A2-b {{in defaulted default constructor for {{.*}} first required here}} - // since-cxx14-note@#cwg1696-A2-a {{initializing field 'v' with default member initializer}} A2(int v) : v(v) {} // since-cxx14-warning@-1 {{binding reference member 'v' to stack allocated parameter 'v'}} - // since-cxx14-note@#cwg1696-A2-a {{reference member declared here}} + // since-cxx14-note@#cwg1696-A2-a {{reference member declared here}} + A2() = default; + // since-cxx14-error@-1 {{reference member 'v' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} + // since-cxx14-note-re@#cwg1696-A2-b {{in defaulted default constructor for {{.*}} first required here}} + // since-cxx14-note@#cwg1696-A2-a {{initializing field 'v' with default member initializer}} const int &v = 42; // #cwg1696-A2-a }; A2 a1; // #cwg1696-A2-b diff --git a/clang/test/CXX/drs/cwg1736.cpp b/clang/test/CXX/drs/cwg1736.cpp new file mode 100644 index 000000000000..25b9fcb747ec --- /dev/null +++ b/clang/test/CXX/drs/cwg1736.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,cxx98 +// RUN: %clang_cc1 -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11 +// RUN: %clang_cc1 -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11 +// RUN: %clang_cc1 -std=c++17 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11 +// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11 +// RUN: %clang_cc1 -std=c++23 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11 +// RUN: %clang_cc1 -std=c++2c %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11 + +// cxx98-no-diagnostics + +namespace cwg1736 { // cwg1736: 3.9 +#if __cplusplus >= 201103L +struct S { + template <class T> S(T t) { + struct L : S { + using S::S; + }; + typename T::type value; + // since-cxx11-error@-1 {{type 'int' cannot be used prior to '::' because it has no members}} + // since-cxx11-note@#cwg1736-l {{in instantiation of function template specialization 'cwg1736::S::S<int>' requested here}} + // since-cxx11-note@#cwg1736-s {{in instantiation of function template specialization 'cwg1736::S::S<cwg1736::Q>' requested here}} + L l(value); // #cwg1736-l + } +}; +struct Q { typedef int type; } q; +S s(q); // #cwg1736-s +#endif +} // namespace cwg1736 diff --git a/clang/test/CXX/drs/cwg17xx.cpp b/clang/test/CXX/drs/cwg17xx.cpp index 8c4f916a606a..cafa21dc17ee 100644 --- a/clang/test/CXX/drs/cwg17xx.cpp +++ b/clang/test/CXX/drs/cwg17xx.cpp @@ -98,24 +98,7 @@ static_assert(__is_trivially_copyable(A), ""); #endif } // namespace cwg1734 -namespace cwg1736 { // cwg1736: 3.9 -#if __cplusplus >= 201103L -struct S { - template <class T> S(T t) { - struct L : S { - using S::S; - }; - typename T::type value; - // since-cxx11-error@-1 {{type 'int' cannot be used prior to '::' because it has no members}} - // since-cxx11-note@#cwg1736-l {{in instantiation of function template specialization 'cwg1736::S::S<int>' requested here}} - // since-cxx11-note@#cwg1736-s {{in instantiation of function template specialization 'cwg1736::S::S<cwg1736::Q>' requested here}} - L l(value); // #cwg1736-l - } -}; -struct Q { typedef int type; } q; -S s(q); // #cwg1736-s -#endif -} // namespace cwg1736 +// cwg1736 is in cwg1736.cpp namespace cwg1738 { // cwg1738: sup P0136R1 #if __cplusplus >= 201103L diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp index c0363fa467ea..f8f85611498f 100644 --- a/clang/test/CXX/drs/cwg18xx.cpp +++ b/clang/test/CXX/drs/cwg18xx.cpp @@ -213,8 +213,8 @@ namespace cwg1815 { // cwg1815: 20 struct B { int &&r = 0; }; // #cwg1815-B // since-cxx14-error@-1 {{reference member 'r' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}} - // since-cxx14-note@#cwg1815-B {{initializing field 'r' with default member initializer}} // since-cxx14-note@#cwg1815-b {{in implicit default constructor for 'cwg1815::B' first required here}} + // since-cxx14-note@#cwg1815-B {{initializing field 'r' with default member initializer}} B b; // #cwg1815-b #if __cplusplus >= 201703L @@ -584,16 +584,16 @@ void cwg1891() { // cwg1891: 4 typedef decltype(b) B; static_assert(!__is_trivially_constructible(A), ""); - // since-cxx20-error@-1 {{failed}} + // since-cxx20-error-re@-1 {{static assertion failed due to requirement '!__is_trivially_constructible((lambda at {{.+}}))':}} static_assert(!__is_trivially_constructible(B), ""); // C++20 allows default construction for non-capturing lambdas (P0624R2). A x; - // cxx11-17-error@-1 {{no matching constructor for initialization of 'A' (aka '(lambda at}} + // cxx11-17-error-re@-1 {{no matching constructor for initialization of 'A' (aka '(lambda at {{.+}})')}} // cxx11-17-note@#cwg1891-a {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}} // cxx11-17-note@#cwg1891-a {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}} B y; - // since-cxx11-error@-1 {{no matching constructor for initialization of 'B' (aka '(lambda at}} + // since-cxx11-error-re@-1 {{no matching constructor for initialization of 'B' (aka '(lambda at {{.+}})')}} // since-cxx11-note@#cwg1891-b {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}} // since-cxx11-note@#cwg1891-b {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}} diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp index 066a429ea1c5..359a194b1fdb 100644 --- a/clang/test/CXX/drs/cwg1xx.cpp +++ b/clang/test/CXX/drs/cwg1xx.cpp @@ -213,8 +213,7 @@ namespace cwg115 { // cwg115: 3.0 &f; // expected-error@-1 {{reference to overloaded function could not be resolved; did you mean to call it?}} // expected-note@#cwg115-f {{possible target for call}} - &f<int>; - // expected-warning@-1 {{expression result unused}} + (void)&f<int>; &g<int>; // expected-error@-1 {{reference to overloaded function could not be resolved; did you mean to call it?}} // expected-note@#cwg115-g-int {{possible target for call}} @@ -242,8 +241,7 @@ namespace cwg115 { // cwg115: 3.0 &s.f; // expected-error@-1 {{cannot create a non-constant pointer to member function}} - &s.f<int>; - // expected-warning@-1 {{expression result unused}} + (void)&s.f<int>; &s.g<int>; // expected-error@-1 {{cannot create a non-constant pointer to member function}} } @@ -269,8 +267,7 @@ namespace cwg115 { // cwg115: 3.0 &s.f; // expected-error@-1 {{cannot create a non-constant pointer to member function}} - &s.f<int>; - // expected-warning@-1 {{expression result unused}} + (void)&s.f<int>; &s.g<int>; // expected-error@-1 {{cannot create a non-constant pointer to member function}} } @@ -290,8 +287,7 @@ namespace cwg115 { // cwg115: 3.0 &with_default; // since-cxx11-error@-1 {{reference to overloaded function could not be resolved; did you mean to call it?}} // since-cxx11-note@#cwg115-with-default {{possible target for call}} - &with_default<>; - // since-cxx11-warning@-1 {{expression result unused}} + (void)&with_default<>; } #endif } // namespace cwg115 @@ -467,15 +463,17 @@ namespace cwg127 { // cwg127: 2.9 template<typename T> struct A { A() { throw 0; } void *operator new(size_t, const char * = 0); - void operator delete(void *, const char *) { T::error; } // #cwg127-delete-const-char - // expected-error@#cwg127-delete-const-char {{type 'void' cannot be used prior to '::' because it has no members}} - // expected-note@#cwg127-p {{in instantiation of member function 'cwg127::A<void>::operator delete' requested here}} - // expected-error@#cwg127-delete-const-char {{type 'int' cannot be used prior to '::' because it has no members}} - // expected-note@#cwg127-q {{in instantiation of member function 'cwg127::A<int>::operator delete' requested here}} - void operator delete(void *) { T::error; } + void operator delete(void *, const char *) = delete; // #cwg127-delete-char + // cxx98-error@-1 {{deleted function definitions are a C++11 extension}} + void operator delete(void *) = delete; + // cxx98-error@-1 {{deleted function definitions are a C++11 extension}} }; - A<void> *p = new A<void>; // #cwg127-p - A<int> *q = new ("") A<int>; // #cwg127-q + A<void> *p = new A<void>; + // expected-error@-1 {{attempt to use a deleted function}} + // expected-note@#cwg127-delete-char {{'operator delete' has been explicitly marked deleted here}} + A<int> *q = new ("") A<int>; + // expected-error@-1 {{attempt to use a deleted function}} + // expected-note@#cwg127-delete-char {{'operator delete' has been explicitly marked deleted here}} } // namespace cwg127 namespace cwg128 { // cwg128: 2.7 @@ -706,7 +704,8 @@ namespace cwg141 { // cwg141: 3.1 // FIXME: we issue a useful diagnostic first, then some bogus ones. b.f<int>(); // expected-error@-1 {{no member named 'f' in 'cwg141::B'}} - // expected-error@-2 +{{}} + // expected-error-re@-2 {{{{.*}}}} + // expected-error-re@-3 {{{{.*}}}} (void)b.S<int>::n; } template<typename T> struct C { @@ -1253,9 +1252,11 @@ namespace cwg180 { // cwg180: 2.8 namespace cwg181 { // cwg181: 2.7 namespace X { template <template X<class T> > struct A { }; - // expected-error@-1 +{{}} + // expected-error@-1 {{expected '<' after 'template'}} + // expected-error@-2 {{expected unqualified-id}} template <template X<class T> > void f(A<X>) { } - // expected-error@-1 +{{}} + // expected-error@-1 {{expected '<' after 'template'}} + // expected-error@-2 {{expected unqualified-id}} } namespace Y { @@ -1426,7 +1427,7 @@ namespace cwg197 { // cwg197: 2.7 char &a = f(1); char &b = f(T(1)); // expected-error@-1 {{non-const lvalue reference to type 'char' cannot bind to a value of unrelated type 'int'}} - // expected-note@#cwg197-g-e-call {{in instantiation of function template specialization 'cwg197::g<cwg197::E>' requested here}} + // expected-note@#cwg197-g-E {{in instantiation of function template specialization 'cwg197::g<cwg197::E>' requested here}} char &c = f(t); // expected-error@-1 {{non-const lvalue reference to type 'char' cannot bind to a value of unrelated type 'int'}} } @@ -1436,11 +1437,9 @@ namespace cwg197 { // cwg197: 2.7 enum E { e }; int &f(E); - void h() { - g('a'); - g(2); - g(e); // #cwg197-g-e-call - } +template void g<char>(char); +template void g<int>(int); +template void g<E>(E); // #cwg197-g-E } // namespace cwg197 namespace cwg198 { // cwg198: 2.9 diff --git a/clang/test/CXX/drs/cwg2026.cpp b/clang/test/CXX/drs/cwg2026.cpp new file mode 100644 index 000000000000..23469f999b77 --- /dev/null +++ b/clang/test/CXX/drs/cwg2026.cpp @@ -0,0 +1,71 @@ +// RUN: %clang_cc1 -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,cxx98 +// RUN: %clang_cc1 -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11,cxx11 +// RUN: %clang_cc1 -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11,since-cxx14 +// RUN: %clang_cc1 -std=c++17 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11,since-cxx14 +// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11,since-cxx14,since-cxx20 +// RUN: %clang_cc1 -std=c++23 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11,since-cxx14,since-cxx20 +// RUN: %clang_cc1 -std=c++2c %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx11,since-cxx14,since-cxx20 + +namespace cwg2026 { // cwg2026: 11 + template<int> struct X {}; + + const int a = a + 1; // #cwg2026-a + // expected-warning@-1 {{variable 'a' is uninitialized when used within its own initialization}} + X<a> xa; // #cwg2026-xa + // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}} + // cxx98-note@-2 {{initializer of 'a' is not a constant expression}} + // cxx98-note@#cwg2026-a {{declared here}} + // since-cxx11-error@#cwg2026-xa {{non-type template argument is not a constant expression}} + // since-cxx11-note@#cwg2026-xa {{initializer of 'a' is not a constant expression}} + // since-cxx11-note@#cwg2026-a {{declared here}} + +#if __cplusplus >= 201103L + constexpr int b = b; + // since-cxx11-error@-1 {{constexpr variable 'b' must be initialized by a constant expression}} + // since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}} + [[clang::require_constant_initialization]] int c = c; + // since-cxx11-error@-1 {{variable does not have a constant initializer}} + // since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}} + // cxx11-note@-3 {{read of non-const variable 'c' is not allowed in a constant expression}} + // cxx11-note@-4 {{declared here}} + // since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}} +#endif + +#if __cplusplus >= 202002L + constinit int d = d; + // since-cxx20-error@-1 {{variable does not have a constant initializer}} + // since-cxx20-note@-2 {{required by 'constinit' specifier here}} + // since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}} +#endif + + void f() { + static const int e = e + 1; // #cwg2026-e + // expected-warning@-1 {{static variable 'e' is suspiciously used within its own initialization}} + X<e> xe; // #cwg2026-xe + // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}} + // cxx98-note@-2 {{initializer of 'e' is not a constant expression}} + // cxx98-note@#cwg2026-e {{declared here}} + // since-cxx11-error@#cwg2026-xe {{non-type template argument is not a constant expression}} + // since-cxx11-note@#cwg2026-xe {{initializer of 'e' is not a constant expression}} + // since-cxx11-note@#cwg2026-e {{declared here}} + +#if __cplusplus >= 201103L + static constexpr int f = f; + // since-cxx11-error@-1 {{constexpr variable 'f' must be initialized by a constant expression}} + // since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}} + [[clang::require_constant_initialization]] static int g = g; + // since-cxx11-error@-1 {{variable does not have a constant initializer}} + // since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}} + // cxx11-note@-3 {{read of non-const variable 'g' is not allowed in a constant expression}} + // cxx11-note@-4 {{declared here}} + // since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}} +#endif + +#if __cplusplus >= 202002L + static constinit int h = h; + // since-cxx20-error@-1 {{variable does not have a constant initializer}} + // since-cxx20-note@-2 {{required by 'constinit' specifier here}} + // since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}} +#endif + } +} // namespace cwg2026 diff --git a/clang/test/CXX/drs/cwg20xx.cpp b/clang/test/CXX/drs/cwg20xx.cpp index 339d4d83c47e..6b120844a606 100644 --- a/clang/test/CXX/drs/cwg20xx.cpp +++ b/clang/test/CXX/drs/cwg20xx.cpp @@ -25,70 +25,7 @@ int b = __builtin_addressof(b2)->foo; } // namespace cwg2007 // cwg2009: na - -namespace cwg2026 { // cwg2026: 11 - template<int> struct X {}; - - const int a = a + 1; // #cwg2026-a - // expected-warning@-1 {{variable 'a' is uninitialized when used within its own initialization}} - X<a> xa; // #cwg2026-xa - // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}} - // cxx98-note@-2 {{initializer of 'a' is not a constant expression}} - // cxx98-note@#cwg2026-a {{declared here}} - // since-cxx11-error@#cwg2026-xa {{non-type template argument is not a constant expression}} - // since-cxx11-note@#cwg2026-xa {{initializer of 'a' is not a constant expression}} - // since-cxx11-note@#cwg2026-a {{declared here}} - -#if __cplusplus >= 201103L - constexpr int b = b; - // since-cxx11-error@-1 {{constexpr variable 'b' must be initialized by a constant expression}} - // since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}} - [[clang::require_constant_initialization]] int c = c; - // since-cxx11-error@-1 {{variable does not have a constant initializer}} - // since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}} - // cxx11-note@-3 {{read of non-const variable 'c' is not allowed in a constant expression}} - // cxx11-note@-4 {{declared here}} - // since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}} -#endif - -#if __cplusplus >= 202002L - constinit int d = d; - // since-cxx20-error@-1 {{variable does not have a constant initializer}} - // since-cxx20-note@-2 {{required by 'constinit' specifier here}} - // since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}} -#endif - - void f() { - static const int e = e + 1; // #cwg2026-e - // expected-warning@-1 {{static variable 'e' is suspiciously used within its own initialization}} - X<e> xe; // #cwg2026-xe - // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}} - // cxx98-note@-2 {{initializer of 'e' is not a constant expression}} - // cxx98-note@#cwg2026-e {{declared here}} - // since-cxx11-error@#cwg2026-xe {{non-type template argument is not a constant expression}} - // since-cxx11-note@#cwg2026-xe {{initializer of 'e' is not a constant expression}} - // since-cxx11-note@#cwg2026-e {{declared here}} - -#if __cplusplus >= 201103L - static constexpr int f = f; - // since-cxx11-error@-1 {{constexpr variable 'f' must be initialized by a constant expression}} - // since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}} - [[clang::require_constant_initialization]] static int g = g; - // since-cxx11-error@-1 {{variable does not have a constant initializer}} - // since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}} - // cxx11-note@-3 {{read of non-const variable 'g' is not allowed in a constant expression}} - // cxx11-note@-4 {{declared here}} - // since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}} -#endif - -#if __cplusplus >= 202002L - static constinit int h = h; - // since-cxx20-error@-1 {{variable does not have a constant initializer}} - // since-cxx20-note@-2 {{required by 'constinit' specifier here}} - // since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}} -#endif - } -} // namespace cwg2026 +// cwg2026 is in cwg2026.cpp namespace cwg2049 { // cwg2049: 18 #if __cplusplus >= 202302L @@ -315,39 +252,33 @@ namespace cwg2083 { // cwg2083: partial void f() { // FIXME: We emit more errors than we should be. They are explicitly // marked below. - a.x; - // expected-warning@-1 {{expression result unused}} - // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME + (void)a.x; + // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME // expected-note@#cwg2083-a-3 {{'a' declared here}} - a.*&A::x; - // expected-warning@-1 {{expression result unused}} - // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME + (void)(a.*&A::x); + // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME // expected-note@#cwg2083-a-3 {{'a' declared here}} - true ? a.x : a.y; // #cwg2083-ternary - // expected-warning@-1 {{expression result unused}} - // expected-error@#cwg2083-ternary {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME + (void)(true ? a.x : a.y); + // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME // expected-note@#cwg2083-a-3 {{'a' declared here}} - // expected-error@#cwg2083-ternary {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME + // expected-error@-3 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME // expected-note@#cwg2083-a-3 {{'a' declared here}} (void)a.x; // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME // expected-note@#cwg2083-a-3 {{'a' declared here}} - a.x, discarded_lval(); - // expected-warning@-1 {{left operand of comma operator has no effect}} - // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME + (void)a.x, discarded_lval(); + // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME // expected-note@#cwg2083-a-3 {{'a' declared here}} // 'volatile' qualifier triggers an lvalue-to-rvalue conversion. - a.z; - // cxx98-warning@-1 {{expression result unused; assign into a variable to force a volatile load}} - // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} + int i = a.z; + // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} // expected-note@#cwg2083-a-3 {{'a' declared here}} // References always get "loaded" to determine what they reference, // even if the result is discarded. - r; - // expected-warning@-1 {{expression result unused}} - // expected-error@-2 {{reference to local variable 'r' declared in enclosing function 'cwg2083::discarded_lval'}} + (void)r; + // expected-error@-1 {{reference to local variable 'r' declared in enclosing function 'cwg2083::discarded_lval'}} // expected-note@#cwg2083-r {{'r' declared here}} } }; diff --git a/clang/test/CXX/drs/cwg2406.cpp b/clang/test/CXX/drs/cwg2406.cpp new file mode 100644 index 000000000000..03cd31b4e844 --- /dev/null +++ b/clang/test/CXX/drs/cwg2406.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,cxx98-14 +// RUN: %clang_cc1 -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,cxx98-14 +// RUN: %clang_cc1 -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,cxx98-14 +// RUN: %clang_cc1 -std=c++17 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx17 +// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx17 +// RUN: %clang_cc1 -std=c++23 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx17 +// RUN: %clang_cc1 -std=c++2c %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx17 + +// cxx98-14-no-diagnostics + +namespace cwg2406 { // cwg2406: 5 +#if __cplusplus >= 201703L +void fallthrough(int n) { + void g(), h(), i(); + switch (n) { + case 1: + case 2: + g(); + [[fallthrough]]; + case 3: // warning on fallthrough discouraged + do { + [[fallthrough]]; + // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} + } while (false); + case 6: + do { + [[fallthrough]]; + // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} + } while (n); + case 7: + while (false) { + [[fallthrough]]; + // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} + } + case 5: + h(); + case 4: // implementation may warn on fallthrough + i(); + [[fallthrough]]; + // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} + } +} +#endif +} // namespace cwg2406 diff --git a/clang/test/CXX/drs/cwg24xx.cpp b/clang/test/CXX/drs/cwg24xx.cpp index c499a2dfcccb..ec3b29ac7a59 100644 --- a/clang/test/CXX/drs/cwg24xx.cpp +++ b/clang/test/CXX/drs/cwg24xx.cpp @@ -6,40 +6,7 @@ // RUN: %clang_cc1 -std=c++23 -pedantic-errors %s -verify=expected,since-cxx20,since-cxx17 // RUN: %clang_cc1 -std=c++2c -pedantic-errors %s -verify=expected,since-cxx20,since-cxx17 -namespace cwg2406 { // cwg2406: 5 -#if __cplusplus >= 201703L -void fallthrough(int n) { - void g(), h(), i(); - switch (n) { - case 1: - case 2: - g(); - [[fallthrough]]; - case 3: // warning on fallthrough discouraged - do { - [[fallthrough]]; - // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} - } while (false); - case 6: - do { - [[fallthrough]]; - // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} - } while (n); - case 7: - while (false) { - [[fallthrough]]; - // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} - } - case 5: - h(); - case 4: // implementation may warn on fallthrough - i(); - [[fallthrough]]; - // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}} - } -} -#endif -} // namespace cwg2406 +// cwg2406 is in cwg2406.cpp namespace cwg2428 { // cwg2428: 19 #if __cplusplus >= 202002L diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp index 0e0fc735c684..ea79fe16a4fe 100644 --- a/clang/test/CXX/drs/cwg25xx.cpp +++ b/clang/test/CXX/drs/cwg25xx.cpp @@ -61,20 +61,17 @@ void f(T t) { // cxx11-14-error@-1 {{constexpr if is a C++17 extension}} static_assert(false, "must be int-sized"); // since-cxx11-error@-1 {{static assertion failed: must be int-sized}} - // since-cxx11-note@#cwg2518-f-c {{in instantiation of function template specialization 'cwg2518::f<char>' requested here}} + // since-cxx11-note@#cwg2518-f-char {{in instantiation of function template specialization 'cwg2518::f<char>' requested here}} } } -void g(char c) { - f(0); - f(c); // #cwg2518-f-c -} +template void f(int); +template void f(char); // #cwg2518-f-char template <typename Ty> struct S { - static_assert(false); - // cxx11-14-error@-1 {{'static_assert' with no message is a C++17 extension}} - // since-cxx11-error@-2 {{static assertion failed}} + static_assert(false, ""); + // since-cxx11-error@-1 {{static assertion failed:}} // since-cxx11-note@#cwg2518-S-double {{in instantiation of template class 'cwg2518::S<double>' requested here}} }; @@ -117,14 +114,14 @@ long double operator"" _RESERVED(long double); namespace cwg2547 { // cwg2547: 20 #if __cplusplus >= 202302L -struct S; -// since-cxx23-note@-1 {{forward declaration of 'cwg2547::S'}} -// since-cxx23-note@-2 {{forward declaration of 'cwg2547::S'}} -// since-cxx23-note@-3 {{forward declaration of 'cwg2547::S'}} +struct S; // #cwg2547-S bool operator==(S, S) = default; // error: S is not complete // since-cxx23-error@-1 {{variable has incomplete type 'S'}} -// since-cxx23-error@-2 {{variable has incomplete type 'S'}} -// since-cxx23-error@-3 {{equality comparison operator is not a friend of incomplete class 'cwg2547::S'}} +// since-cxx23-note@#cwg2547-S {{forward declaration of 'cwg2547::S'}} +// since-cxx23-error@-3 {{variable has incomplete type 'S'}} +// since-cxx23-note@#cwg2547-S {{forward declaration of 'cwg2547::S'}} +// since-cxx23-error@-5 {{equality comparison operator is not a friend of incomplete class 'cwg2547::S'}} +// since-cxx23-note@#cwg2547-S {{forward declaration of 'cwg2547::S'}} struct S { friend bool operator==(S, const S&) = default; // error: parameters of different types // since-cxx23-error@-1 {{parameters for defaulted equality comparison operator must have the same type (found 'S' vs 'const S &')}} diff --git a/clang/test/CXX/drs/cwg2881.cpp b/clang/test/CXX/drs/cwg2881.cpp new file mode 100644 index 000000000000..0a04a486d78b --- /dev/null +++ b/clang/test/CXX/drs/cwg2881.cpp @@ -0,0 +1,147 @@ +// RUN: %clang_cc1 -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,cxx98-20 +// RUN: %clang_cc1 -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,cxx98-20 +// RUN: %clang_cc1 -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,cxx98-20 +// RUN: %clang_cc1 -std=c++17 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,cxx98-20 +// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,cxx98-20 +// RUN: %clang_cc1 -std=c++23 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx23 +// RUN: %clang_cc1 -std=c++2c %s -fexceptions -fcxx-exceptions -pedantic-errors -verify=expected,since-cxx23 + +// cxx98-20-no-diagnostics + +namespace cwg2881 { // cwg2881: 19 +#if __cplusplus >= 202302L +template <typename T> struct A : T {}; +template <typename T> struct B : T {}; +template <typename T> struct C : virtual T { C(T t) : T(t) {} }; +template <typename T> struct D : virtual T { D(T t) : T(t) {} }; + +template <typename Ts> +struct O1 : A<Ts>, B<Ts> { + using A<Ts>::operator(); + using B<Ts>::operator(); +}; + +template <typename Ts> struct O2 : protected Ts { // #cwg2881-O2 + using Ts::operator(); + O2(Ts ts) : Ts(ts) {} +}; + +template <typename Ts> struct O3 : private Ts { // #cwg2881-O3 + using Ts::operator(); + O3(Ts ts) : Ts(ts) {} +}; + +// Not ambiguous because of virtual inheritance. +template <typename Ts> +struct O4 : C<Ts>, D<Ts> { + using C<Ts>::operator(); + using D<Ts>::operator(); + O4(Ts t) : Ts(t), C<Ts>(t), D<Ts>(t) {} +}; + +// This still has a public path to the lambda, and it's also not +// ambiguous because of virtual inheritance. +template <typename Ts> +struct O5 : private C<Ts>, D<Ts> { + using C<Ts>::operator(); + using D<Ts>::operator(); + O5(Ts t) : Ts(t), C<Ts>(t), D<Ts>(t) {} +}; + +// This is only invalid if we call T's call operator. +template <typename T, typename U> +struct O6 : private T, U { // #cwg2881-O6 + using T::operator(); + using U::operator(); + O6(T t, U u) : T(t), U(u) {} +}; + +void f() { + int x; + auto L1 = [=](this auto&& self) { (void) &x; }; + auto L2 = [&](this auto&& self) { (void) &x; }; + O1<decltype(L1)>{L1, L1}(); + /* since-cxx23-error-re@-1 {{lambda '(lambda at {{.+}})' is inaccessible due to ambiguity: + struct cwg2881::O1<class (lambda at {{.+}})> -> A<class (lambda at {{.+}})> -> class (lambda at {{.+}}) + struct cwg2881::O1<class (lambda at {{.+}})> -> B<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/ + O1<decltype(L2)>{L2, L2}(); + /* since-cxx23-error-re@-1 {{lambda '(lambda at {{.+}})' is inaccessible due to ambiguity: + struct cwg2881::O1<class (lambda at {{.+}})> -> A<class (lambda at {{.+}})> -> class (lambda at {{.+}}) + struct cwg2881::O1<class (lambda at {{.+}})> -> B<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/ + O2{L1}(); + // since-cxx23-error-re@-1 {{invalid explicit object parameter type 'cwg2881::O2<(lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}} + // since-cxx23-note@#cwg2881-O2 {{declared protected here}} + O3{L1}(); + // since-cxx23-error-re@-1 {{invalid explicit object parameter type 'cwg2881::O3<(lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}} + // since-cxx23-note@#cwg2881-O3 {{declared private here}} + O4{L1}(); + O5{L1}(); + O6 o{L1, L2}; + o.decltype(L1)::operator()(); + // since-cxx23-error-re@-1 {{invalid explicit object parameter type 'cwg2881::O6<(lambda at {{.+}}), (lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}} + // since-cxx23-note@#cwg2881-O6 {{declared private here}} + o.decltype(L1)::operator()(); // No error here because we've already diagnosed this method. + o.decltype(L2)::operator()(); +} + +void f2() { + int x = 0; + auto lambda = [x] (this auto self) { return x; }; + using Lambda = decltype(lambda); + struct D : private Lambda { // #cwg2881-D + D(Lambda l) : Lambda(l) {} + using Lambda::operator(); + friend Lambda; + } d(lambda); + d(); + // since-cxx23-error@-1 {{invalid explicit object parameter type 'D' in lambda with capture; the type must derive publicly from the lambda}} + // since-cxx23-note@#cwg2881-D {{declared private here}} +} + +template <typename L> +struct Private : private L { + using L::operator(); + Private(L l) : L(l) {} +}; + +template<typename T> +struct Indirect : T { + using T::operator(); +}; + +template<typename T> +struct Ambiguous : Indirect<T>, T { +/* since-cxx23-warning-re@-1 {{direct base '(lambda at {{.+}})' is inaccessible due to ambiguity: + struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> Indirect<class (lambda at {{.+}})> -> class (lambda at {{.+}}) + struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/ +// since-cxx23-note-re@#cwg2881-f4 {{in instantiation of template class 'cwg2881::Ambiguous<(lambda at {{.+}})>' requested here}} +// since-cxx34-note-re@#cwg2881-f4-call {{while substituting deduced template arguments into function template 'f4' [with L = (lambda at {{.+}})]}} + using Indirect<T>::operator(); +}; + +template <typename L> +constexpr auto f3(L l) -> decltype(Private<L>{l}()) { return l(); } // #cwg2881-f3 + +template <typename L> +constexpr auto f4(L l) -> decltype(Ambiguous<L>{{l}, l}()) { return l(); } // #cwg2881-f4 + +template<typename T> +concept is_callable = requires(T t) { { t() }; }; + +void g() { + int x = 0; + auto lambda = [x](this auto self) {}; + f3(lambda); + // since-cxx23-error@-1 {{no matching function for call to 'f3'}} + // since-cxx23-note-re@#cwg2881-f3 {{candidate template ignored: substitution failure [with L = (lambda at {{.+}})]: invalid explicit object parameter type 'cwg2881::Private<(lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}} + f4(lambda); // #cwg2881-f4-call + // expected-error@-1 {{no matching function for call to 'f4'}} + // expected-note-re@-2 {{while substituting deduced template arguments into function template 'f4' [with L = (lambda at {{.+}})]}} + /* expected-note-re@#cwg2881-f4 {{candidate template ignored: substitution failure [with L = (lambda at {{.+}})]: lambda '(lambda at {{.+}})' is inaccessible due to ambiguity: + struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> Indirect<class (lambda at {{.+}})> -> class (lambda at {{.+}}) + struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/ + static_assert(!is_callable<Private<decltype(lambda)>>); + static_assert(!is_callable<Ambiguous<decltype(lambda)>>); +} +#endif +} // namespace cwg2881 diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp index d0ee191ef23d..6d247bb9abe0 100644 --- a/clang/test/CXX/drs/cwg28xx.cpp +++ b/clang/test/CXX/drs/cwg28xx.cpp @@ -191,143 +191,7 @@ void g() { #endif } // namespace cwg2877 -namespace cwg2881 { // cwg2881: 19 -#if __cplusplus >= 202302L -template <typename T> struct A : T {}; -template <typename T> struct B : T {}; -template <typename T> struct C : virtual T { C(T t) : T(t) {} }; -template <typename T> struct D : virtual T { D(T t) : T(t) {} }; - -template <typename Ts> -struct O1 : A<Ts>, B<Ts> { - using A<Ts>::operator(); - using B<Ts>::operator(); -}; - -template <typename Ts> struct O2 : protected Ts { // #cwg2881-O2 - using Ts::operator(); - O2(Ts ts) : Ts(ts) {} -}; - -template <typename Ts> struct O3 : private Ts { // #cwg2881-O3 - using Ts::operator(); - O3(Ts ts) : Ts(ts) {} -}; - -// Not ambiguous because of virtual inheritance. -template <typename Ts> -struct O4 : C<Ts>, D<Ts> { - using C<Ts>::operator(); - using D<Ts>::operator(); - O4(Ts t) : Ts(t), C<Ts>(t), D<Ts>(t) {} -}; - -// This still has a public path to the lambda, and it's also not -// ambiguous because of virtual inheritance. -template <typename Ts> -struct O5 : private C<Ts>, D<Ts> { - using C<Ts>::operator(); - using D<Ts>::operator(); - O5(Ts t) : Ts(t), C<Ts>(t), D<Ts>(t) {} -}; - -// This is only invalid if we call T's call operator. -template <typename T, typename U> -struct O6 : private T, U { // #cwg2881-O6 - using T::operator(); - using U::operator(); - O6(T t, U u) : T(t), U(u) {} -}; - -void f() { - int x; - auto L1 = [=](this auto&& self) { (void) &x; }; - auto L2 = [&](this auto&& self) { (void) &x; }; - O1<decltype(L1)>{L1, L1}(); - /* since-cxx23-error-re@-1 {{inaccessible due to ambiguity: - struct cwg2881::O1<class (lambda at {{.+}})> -> A<class (lambda at {{.+}})> -> class (lambda at {{.+}}) - struct cwg2881::O1<class (lambda at {{.+}})> -> B<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/ - O1<decltype(L2)>{L2, L2}(); - /* since-cxx23-error-re@-1 {{inaccessible due to ambiguity: - struct cwg2881::O1<class (lambda at {{.+}})> -> A<class (lambda at {{.+}})> -> class (lambda at {{.+}}) - struct cwg2881::O1<class (lambda at {{.+}})> -> B<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/ - O2{L1}(); - // since-cxx23-error-re@-1 {{invalid explicit object parameter type 'cwg2881::O2<(lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}} - // since-cxx23-note@#cwg2881-O2 {{declared protected here}} - O3{L1}(); - // since-cxx23-error-re@-1 {{invalid explicit object parameter type 'cwg2881::O3<(lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}} - // since-cxx23-note@#cwg2881-O3 {{declared private here}} - O4{L1}(); - O5{L1}(); - O6 o{L1, L2}; - o.decltype(L1)::operator()(); - // since-cxx23-error-re@-1 {{invalid explicit object parameter type 'cwg2881::O6<(lambda at {{.+}}), (lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}} - // since-cxx23-note@#cwg2881-O6 {{declared private here}} - o.decltype(L1)::operator()(); // No error here because we've already diagnosed this method. - o.decltype(L2)::operator()(); -} - -void f2() { - int x = 0; - auto lambda = [x] (this auto self) { return x; }; - using Lambda = decltype(lambda); - struct D : private Lambda { // #cwg2881-D - D(Lambda l) : Lambda(l) {} - using Lambda::operator(); - friend Lambda; - } d(lambda); - d(); - // since-cxx23-error@-1 {{invalid explicit object parameter type 'D' in lambda with capture; the type must derive publicly from the lambda}} - // since-cxx23-note@#cwg2881-D {{declared private here}} -} - -template <typename L> -struct Private : private L { - using L::operator(); - Private(L l) : L(l) {} -}; - -template<typename T> -struct Indirect : T { - using T::operator(); -}; - -template<typename T> -struct Ambiguous : Indirect<T>, T { -/* since-cxx23-warning-re@-1 {{direct base '(lambda at {{.+}})' is inaccessible due to ambiguity: - struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> Indirect<class (lambda at {{.+}})> -> class (lambda at {{.+}}) - struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/ -// since-cxx23-note-re@#cwg2881-f4 {{in instantiation of template class 'cwg2881::Ambiguous<(lambda at {{.+}})>' requested here}} -// since-cxx34-note-re@#cwg2881-f4-call {{while substituting deduced template arguments into function template 'f4' [with L = (lambda at {{.+}})]}} - using Indirect<T>::operator(); -}; - -template <typename L> -constexpr auto f3(L l) -> decltype(Private<L>{l}()) { return l(); } // #cwg2881-f3 - -template <typename L> -constexpr auto f4(L l) -> decltype(Ambiguous<L>{{l}, l}()) { return l(); } // #cwg2881-f4 - -template<typename T> -concept is_callable = requires(T t) { { t() }; }; - -void g() { - int x = 0; - auto lambda = [x](this auto self) {}; - f3(lambda); - // since-cxx23-error@-1 {{no matching function for call to 'f3'}} - // since-cxx23-note-re@#cwg2881-f3 {{candidate template ignored: substitution failure [with L = (lambda at {{.+}})]: invalid explicit object parameter type 'cwg2881::Private<(lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}} - f4(lambda); // #cwg2881-f4-call - // expected-error@-1 {{no matching function for call to 'f4'}} - // expected-note-re@-2 {{while substituting deduced template arguments into function template 'f4' [with L = (lambda at {{.+}})]}} - /* expected-note-re@#cwg2881-f4 {{candidate template ignored: substitution failure [with L = (lambda at {{.+}})]: lambda '(lambda at {{.+}})' is inaccessible due to ambiguity: - struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> Indirect<class (lambda at {{.+}})> -> class (lambda at {{.+}}) - struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/ - static_assert(!is_callable<Private<decltype(lambda)>>); - static_assert(!is_callable<Ambiguous<decltype(lambda)>>); -} -#endif -} // namespace cwg2881 +// cwg2881 is in cwg2881.cpp namespace cwg2882 { // cwg2882: 2.7 struct C { diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp index a4995ddc2c58..566eba71310a 100644 --- a/clang/test/CXX/drs/cwg2xx.cpp +++ b/clang/test/CXX/drs/cwg2xx.cpp @@ -6,10 +6,7 @@ // RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors -// FIXME: diagnostic above is emitted only on Windows platforms -// PR13819 -- __SIZE_TYPE__ is incompatible. -typedef __SIZE_TYPE__ size_t; -// cxx98-error@-1 0-1 {{'long long' is a C++11 extension}} +typedef __decltype(sizeof(0)) size_t; #if __cplusplus == 199711L #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) diff --git a/clang/test/CXX/drs/cwg329.cpp b/clang/test/CXX/drs/cwg329.cpp new file mode 100644 index 000000000000..6ea01805580a --- /dev/null +++ b/clang/test/CXX/drs/cwg329.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++17 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++23 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++2c %s -fexceptions -fcxx-exceptions -pedantic-errors -verify + +namespace cwg329 { // cwg329: 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@-1 {{use of undeclared identifier 'g'}} + // expected-note@#cwg329-h-call {{in instantiation of member function 'cwg329::h' requested here}} + friend void i(B b) {} // #cwg329-i + // expected-error@-1 {{redefinition of 'i'}} + // expected-note@#cwg329-b {{in instantiation of template class 'cwg329::A<char>' requested here}} + // expected-note@#cwg329-i {{previous definition is here}} + }; + A<int> a; + A<char> b; // #cwg329-b + + void test() { + h(a); // #cwg329-h-call + } +} // namespace cwg329 diff --git a/clang/test/CXX/drs/cwg390.cpp b/clang/test/CXX/drs/cwg390.cpp new file mode 100644 index 000000000000..8ee41a87cf47 --- /dev/null +++ b/clang/test/CXX/drs/cwg390.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++17 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++23 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++2c %s -fexceptions -fcxx-exceptions -pedantic-errors -verify + +namespace cwg390 { // cwg390: 3.3 + template<typename T> + struct A { + 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 'cwg390::A<int>'}} + // expected-note@#cwg390-A-int {{in instantiation of member function 'cwg390::A<int>::A' requested here}} + // expected-note@#cwg390-f {{'f' declared here}} + virtual void f() = 0; // #cwg390-f + virtual ~A() = 0; + }; + 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@#cwg390-A-int {{in instantiation of member function 'cwg390::A<int>::~A' requested here}} + template<typename T> void A<T>::f() { T::error; } // ok, not odr-used + struct B : A<int> { // #cwg390-A-int + void f() {} + } b; +} // namespace cwg390 diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp index 754eb2315728..e3cd0725c817 100644 --- a/clang/test/CXX/drs/cwg3xx.cpp +++ b/clang/test/CXX/drs/cwg3xx.cpp @@ -1,10 +1,10 @@ -// 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 -// 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++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++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++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++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++2c -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++98 -verify=expected,cxx98-14,cxx98-17,cxx98-20,cxx98 -triple x86_64-linux-gnu %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 x86_64-linux-gnu %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 x86_64-linux-gnu %s -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++17 -verify=expected,cxx98-17,cxx98-20,since-cxx11,since-cxx17 -triple x86_64-linux-gnu %s -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++20 -verify=expected,cxx98-20,cxx20-23,since-cxx11,since-cxx17 -triple x86_64-linux-gnu %s -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++23 -verify=expected,cxx20-23,cxx23,since-cxx11,since-cxx17,since-cxx23 -triple x86_64-linux-gnu %s -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++2c -verify=expected,cxx20-23,cxx23,since-cxx11,since-cxx17,since-cxx23 -triple x86_64-linux-gnu %s -fexceptions -fcxx-exceptions -pedantic-errors #if __cplusplus == 199711L #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) @@ -17,6 +17,19 @@ #define __enable_constant_folding #endif +namespace std { +template<bool Cond, typename T = void> +struct enable_if; + +template<typename T> +struct enable_if<true, T> { + typedef T type; +}; + +template<typename T> +struct enable_if<false, T> { }; +} // namespace std + namespace cwg300 { // cwg300: 2.7 template<typename R, typename A> void f(R (&)(A)) {} int g(int); @@ -432,25 +445,7 @@ namespace cwg328 { // cwg328: 2.7 // expected-note@#cwg328-A {{forward declaration of 'cwg328::A'}} } // namespace cwg328 -namespace cwg329 { // cwg329: 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@-1 {{use of undeclared identifier 'g'}} - // expected-note@#cwg329-h-call {{in instantiation of member function 'cwg329::h' requested here}} - friend void i(B b) {} // #cwg329-i - // expected-error@-1 {{redefinition of 'i'}} - // expected-note@#cwg329-b {{in instantiation of template class 'cwg329::A<char>' requested here}} - // expected-note@#cwg329-i {{previous definition is here}} - }; - A<int> a; - A<char> b; // #cwg329-b - - void test() { - h(a); // #cwg329-h-call - } -} // namespace cwg329 +// cwg329 is in cwg329.cpp namespace cwg330 { // cwg330: 7 // Conversions between P and Q will be allowed by P0388. @@ -560,13 +555,13 @@ namespace cwg331 { // cwg331: 11 namespace cwg332 { // cwg332: dup 577 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}} + // cxx20-23-warning@-1 {{volatile-qualified parameter type 'volatile void' is deprecated}} + // expected-error@-2 {{'void' as parameter must not have type qualifiers}} 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}} + // cxx20-23-warning@-1 {{volatile-qualified parameter type 'volatile void' is deprecated}} + // expected-error@-2 {{'void' must be the first and only parameter if specified}} } // namespace cwg332 namespace cwg333 { // cwg333: 2.7 @@ -746,10 +741,9 @@ namespace cwg345 { // cwg345: 2.7 // expected-error@-1 {{typename specifier refers to non-type member 'X' in 'cwg345::A'}} // expected-note@#cwg345-f-a {{in instantiation of function template specialization 'cwg345::f<cwg345::A>' requested here}} // expected-note@#cwg345-int-X {{referenced member 'X' is declared here}} - void f(A a, B b) { - f(b); - f(a); // #cwg345-f-a - } + + template void f<A>(A); // #cwg345-f-a + template void f<B>(B); } // namespace cwg345 // cwg346: na @@ -780,24 +774,21 @@ namespace cwg347 { // cwg347: 2.7 namespace cwg349 { // cwg349: no struct A { - template <class T> operator T ***() { - int ***p = 0; - 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@#cwg349-p1 {{in instantiation of function template specialization 'cwg349::A::operator const int ***<const int>' requested here}} - } + template <class T, typename std::enable_if<!__is_const(T), int>::type = 0> + // cxx98-error@-1 {{default template arguments for a function template are a C++11 extension}} + operator T ***(); // #cwg349-A }; // FIXME: This is valid. A a; const int *const *const *p1 = a; // #cwg349-p1 + // expected-error@-1 {{no viable conversion from 'A' to 'const int *const *const *'}} + // expected-note@#cwg349-A {{candidate template ignored: requirement '!__is_const(const int)' was not satisfied [with T = const int]}} struct B { - template <class T> operator T ***() { - const int ***p = 0; - return p; - } + template <class T, typename std::enable_if<__is_const(T), int>::type = 0> + // cxx98-error@-1 {{default template arguments for a function template are a C++11 extension}} + operator T ***(); }; // FIXME: This is invalid. @@ -1296,13 +1287,10 @@ namespace cwg374 { // cwg374: 7 // cwg376: na namespace cwg377 { // cwg377: 2.7 - 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}} + enum E { // #cwg377-E + // expected-error@#cwg377-E {{enumeration values exceed range of largest integer}} + a = -__LONG_MAX__ - 1, + b = 2 * (unsigned long)__LONG_MAX__ }; } // namespace cwg377 @@ -1617,24 +1605,7 @@ namespace cwg389 { // cwg389: no } } // namespace cwg389 -namespace cwg390 { // cwg390: 3.3 - template<typename T> - struct A { - 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 'cwg390::A<int>'}} - // expected-note@#cwg390-A-int {{in instantiation of member function 'cwg390::A<int>::A' requested here}} - // expected-note@#cwg390-f {{'f' declared here}} - virtual void f() = 0; // #cwg390-f - virtual ~A() = 0; - }; - 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@#cwg390-A-int {{in instantiation of member function 'cwg390::A<int>::~A' requested here}} - template<typename T> void A<T>::f() { T::error; } // ok, not odr-used - struct B : A<int> { // #cwg390-A-int - void f() {} - } b; -} // namespace cwg390 +// cwg390 is in cwg390.cpp namespace cwg391 { // cwg391: 2.8 c++11 // FIXME: Should this apply to C++98 too? @@ -1684,7 +1655,8 @@ void h() { namespace cwg395 { // cwg395: 3.0 struct S { 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}} + // cxx98-error@-1 {{cannot specify any part of a return type in the declaration of a conversion function}} + // since-cxx11-error@-2 {{cannot specify any part of a return type in the declaration of a conversion function; use an alias template to declare a conversion to 'T (&)[N]'}} template <typename T, int N> operator(T (&)[N])(); // expected-error@-1 {{expected ')'}} // expected-note@-2 {{to match this '('}} @@ -1694,9 +1666,9 @@ namespace cwg395 { // cwg395: 3.0 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}} - + // cxx98-error@-3 {{cannot specify any part of a return type in the declaration of a conversion function}} + // since-cxx11-error@-4 {{cannot specify any part of a return type in the declaration of a conversion function; use an alias template to declare a conversion to 'T (())() const'}} + // expected-error@-5 {{conversion function cannot convert to a function type}} }; struct null1_t { diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp index eccfbea01492..ee2940d7f2fa 100644 --- a/clang/test/CXX/drs/cwg4xx.cpp +++ b/clang/test/CXX/drs/cwg4xx.cpp @@ -1,10 +1,10 @@ -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++98 %s -verify=expected,cxx98-14,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++11 %s -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++14 %s -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++20 %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++23 %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++2c %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++98 %s -triple x86_64-linux-gnu -verify=expected,cxx98-14,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++11 %s -triple x86_64-linux-gnu -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++14 %s -triple x86_64-linux-gnu -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -verify=expected,since-cxx17,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++23 %s -triple x86_64-linux-gnu -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++2c %s -triple x86_64-linux-gnu -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors #if __cplusplus == 199711L #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) @@ -309,15 +309,14 @@ namespace cwg413 { // cwg413: 2.7 // expected-error@-1 {{excess elements in struct initializer}} struct E {}; - struct T { // #cwg413-T + struct S2 { int a; E e; int b; }; - T t1 = { 1, {}, 2 }; - T t2 = { 1, 2 }; + S2 s2_1 = { 1, {}, 2 }; + S2 s2_2 = { 1, 2 }; // expected-error@-1 {{initializer for aggregate with no elements requires explicit braces}} - // expected-note@#cwg413-T {{'cwg413::T' declared here}} } // namespace cwg413 namespace cwg414 { // cwg414: dup 305 @@ -534,16 +533,28 @@ namespace cwg425 { // cwg425: 2.7 struct A { template<typename T> operator T() const; } a; float f = 1.0f * a; // expected-error@-1 {{use of overloaded operator '*' is ambiguous (with operand types 'float' and 'struct A')}} - // expected-note@-2 +{{built-in candidate operator*}} + // expected-note-re@-2 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-3 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-4 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-5 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-6 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-7 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-8 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-9 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-10 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-11 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-12 {{built-in candidate operator*{{.*}}}} + // expected-note-re@-13 {{built-in candidate operator*{{.*}}}} template<typename T> struct is_float; template<> struct is_float<float> { typedef void type; }; +#if __cplusplus >= 201103L struct B { template<typename T, typename U = typename is_float<T>::type> operator T() const; - // cxx98-error@-1 {{default template arguments for a function template are a C++11 extension}} } b; float g = 1.0f * b; // ok +#endif } // namespace cwg425 namespace cwg427 { // cwg427: 2.7 @@ -767,12 +778,12 @@ namespace cwg446 { // cwg446: 2.8 // expected-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}} b ? A() : A(); // cxx98-14-error@-1 {{call to deleted constructor of 'A'}} - // expected-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}} + // cxx98-14-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}} void(b ? a : c); b ? a : C(); // expected-error@-1 {{call to deleted constructor of 'A'}} - // cxx98-14-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}} + // expected-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}} b ? c : A(); // cxx98-14-error@-1 {{call to deleted constructor of 'A'}} // cxx98-14-note@#cwg446-deleted {{'A' has been explicitly marked deleted here}} diff --git a/clang/test/CXX/drs/cwg5xx.cpp b/clang/test/CXX/drs/cwg5xx.cpp index f29c1e813101..450f8b211326 100644 --- a/clang/test/CXX/drs/cwg5xx.cpp +++ b/clang/test/CXX/drs/cwg5xx.cpp @@ -475,10 +475,9 @@ namespace cwg535 { // cwg535: 3.1 // cwg538: na namespace cwg539 { // cwg539: 3.4 -const f( -// expected-error@-1 {{a type specifier is required for all declarations}} - const a) { - // expected-error@-1 {{unknown type name 'a'}} +const f(const a) { +// expected-error@-1 {{unknown type name 'a'}} +// expected-error@-2 {{a type specifier is required for all declarations}} const b; // expected-error@-1 {{a type specifier is required for all declarations}} new const; @@ -512,8 +511,14 @@ const f( { for (const n // #cwg539-for // since-cxx11-error@-1 {{unknown type name 'n'}} : arr) ; {} } - // since-cxx11-error@-1 +{{}} - // since-cxx11-note@#cwg539-for {{}} + // since-cxx11-error-re@-1 {{{{.*}}}} + // since-cxx11-error-re@-2 {{{{.*}}}} + // since-cxx11-error-re@-3 {{{{.*}}}} + // since-cxx11-error-re@-4 {{{{.*}}}} + // since-cxx11-error-re@-5 {{{{.*}}}} + // since-cxx11-error-re@-6 {{{{.*}}}} + // since-cxx11-note-re@#cwg539-for {{{{.*}}}} + // since-cxx11-error-re@-8 {{{{.*}}}} (void) [](const) {}; // since-cxx11-error@-1 {{a type specifier is required for all declarations}} (void) [](const n) {}; @@ -537,9 +542,9 @@ namespace cwg540 { // cwg540: 2.7 typedef const a &c; // #cwg540-typedef-a-c // expected-warning@-1 {{'const' qualifier on reference type 'a' (aka 'int &') has no effect}} typedef const b &c; // #cwg540-typedef-b-c + // expected-warning@#cwg540-typedef-b-c {{'const' qualifier on reference type 'b' (aka 'const int &') has no effect}} // expected-error@#cwg540-typedef-b-c {{typedef redefinition with different types ('const int &' vs 'int &')}} // expected-note@#cwg540-typedef-a-c {{previous definition is here}} - // expected-warning@#cwg540-typedef-b-c {{'const' qualifier on reference type 'b' (aka 'const int &') has no effect}} } // namespace cwg540 namespace cwg541 { // cwg541: 2.7 @@ -1150,12 +1155,12 @@ namespace cwg588 { // cwg588: 2.7 int a = s.f(); int b = s.n; // expected-error@-1 {{member 'n' found in multiple base classes of different types}} - // expected-note@#cwg588-k {{in instantiation of function template specialization 'cwg588::f<cwg588::B>' requested here}} + // expected-note@#cwg588-inst {{in instantiation of function template specialization 'cwg588::f<cwg588::B>' requested here}} // expected-note@#cwg588-A {{member found by ambiguous name lookup}} // expected-note@#cwg588-B {{member found by ambiguous name lookup}} } struct B { int n; }; // #cwg588-B - int k = f<B>(); // #cwg588-k + template int f<B>(); // #cwg588-inst } // namespace cwg588 namespace cwg589 { // cwg589: 2.7 diff --git a/clang/test/CXX/drs/cwg6xx.cpp b/clang/test/CXX/drs/cwg6xx.cpp index 3937a80d4f3c..3f91780d3366 100644 --- a/clang/test/CXX/drs/cwg6xx.cpp +++ b/clang/test/CXX/drs/cwg6xx.cpp @@ -2,9 +2,9 @@ // RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-20,cxx98-17,cxx11-17,cxx98-14,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx11-20,cxx98-17,cxx11-17,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++17 %s -verify=expected,cxx11-20,cxx98-17,cxx11-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++20 %s -verify=expected,cxx11-20,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx20,cxx11-20,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx20,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx20,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors #if __cplusplus == 199711L #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) @@ -269,7 +269,8 @@ namespace cwg625 { // cwg625: 2.9 void f(int); void (*p)(auto) = f; // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}} - // expected-error@-2 {{'auto' not allowed in function prototype}} + // cxx98-17-error@-2 {{'auto' not allowed in function prototype}} + // since-cxx20-error@-3 {{'auto' not allowed in function prototype that is not a function declaration}} } // namespace cwg625 namespace cwg626 { // cwg626: 2.7 @@ -839,12 +840,12 @@ namespace cwg662 { // cwg662: 2.7 T &tr = t; T *tp = &t; // expected-error@-1 {{'tp' declared as a pointer to a reference of type 'int &'}} - // expected-note@#cwg662-f-call {{in instantiation of function template specialization 'cwg662::f<int &>' requested here}} + // expected-note@#cwg662-inst {{in instantiation of function template specialization 'cwg662::f<int &>' requested here}} #if __cplusplus >= 201103L auto *ap = &t; #endif } - void g(int n) { f<int&>(n); } // #cwg662-f-call + template void f<int&>(int&); // #cwg662-inst } // namespace cwg662 namespace cwg663 { // cwg663: sup P1949 @@ -904,8 +905,8 @@ namespace cwg666 { // cwg666: 2.8 } struct X { static const int type = 0; }; struct Y { typedef int type; }; - int a = f<X>(); - int b = f<Y>(); // #cwg666-f-Y + template int f<X>(); + template int f<Y>(); // #cwg666-f-Y } // namespace cwg666 // Triviality is entirely different in C++98. @@ -1005,25 +1006,25 @@ namespace cwg674 { // cwg674: 8 class X { friend int cwg674::f(int); - friend int cwg674::g(int); - friend int cwg674::h<>(int); + friend int cwg674::g<>(int); + friend int cwg674::h(int); int n; // #cwg674-X-n }; template<typename T> int f(T) { return X().n; } int g(int) { return X().n; } - template<typename T> int g(T) { return X().n; } // expected-error@-1 {{'n' is a private member of 'cwg674::X'}} - // expected-note@#cwg674-g-int {{in instantiation of function template specialization 'cwg674::g<int>' requested here}} // expected-note@#cwg674-X-n {{implicitly declared private here}} + template<typename T> int g(T) { return X().n; } int h(int) { return X().n; } + template<typename T> int h(T) { return X().n; } // expected-error@-1 {{'n' is a private member of 'cwg674::X'}} + // expected-note@#cwg674-h-int {{in instantiation of function template specialization 'cwg674::h<int>' requested here}} // expected-note@#cwg674-X-n {{implicitly declared private here}} - template<typename T> int h(T) { return X().n; } template int f(int); - template int g(int); // #cwg674-g-int - template int h(int); + template int g(int); + template int h(int); // #cwg674-h-int struct Y { @@ -1038,26 +1039,26 @@ namespace cwg674 { // cwg674: 8 class Z { friend int Y::f(int); - friend int Y::g(int); - friend int Y::h<>(int); + friend int Y::g<>(int); + friend int Y::h(int); int n; // #cwg674-Z-n }; template<typename T> int Y::f(T) { return Z().n; } int Y::g(int) { return Z().n; } - template<typename T> int Y::g(T) { return Z().n; } // expected-error@-1 {{'n' is a private member of 'cwg674::Z'}} - // expected-note@#cwg674-Y-g-int {{in instantiation of function template specialization 'cwg674::Y::g<int>' requested here}} // expected-note@#cwg674-Z-n {{implicitly declared private here}} + template<typename T> int Y::g(T) { return Z().n; } int Y::h(int) { return Z().n; } + template<typename T> int Y::h(T) { return Z().n; } // expected-error@-1 {{'n' is a private member of 'cwg674::Z'}} + // expected-note@#cwg674-Y-h-int {{in instantiation of function template specialization 'cwg674::Y::h<int>' requested here}} // expected-note@#cwg674-Z-n {{implicitly declared private here}} - template<typename T> int Y::h(T) { return Z().n; } // FIXME: Should the <> be required here? template int Y::f<>(int); - template int Y::g<>(int); // #cwg674-Y-g-int - template int Y::h<>(int); + template int Y::g<>(int); + template int Y::h<>(int); // #cwg674-Y-h-int } // namespace cwg674 namespace cwg675 { // cwg675: dup 739 diff --git a/clang/test/CXX/drs/cwg7xx.cpp b/clang/test/CXX/drs/cwg7xx.cpp index 84bcc07bf0a3..7f49f5ecabf0 100644 --- a/clang/test/CXX/drs/cwg7xx.cpp +++ b/clang/test/CXX/drs/cwg7xx.cpp @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify=expected,cxx98,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify=expected,cxx98-14,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify=expected,cxx98-14,since-cxx14,since-cxx11,cxx14 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++23 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2c %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++23 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2c %s -verify=expected,since-cxx17,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors #if __cplusplus == 199711L #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) @@ -35,8 +35,6 @@ namespace cwg712 { // cwg712: partial use(a); use((a)); use(cond ? a : a); - use((cond, a)); - // expected-warning@-1 {{left operand of comma operator has no effect}} (void)a; // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME @@ -49,10 +47,13 @@ namespace cwg712 { // cwg712: partial // expected-note@#cwg712-f-a {{'a' declared here}} // expected-error@#cwg712-ternary {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME // expected-note@#cwg712-f-a {{'a' declared here}} - (void)(cond, a); // #cwg712-comma + (void)(cond, a); // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME // expected-note@#cwg712-f-a {{'a' declared here}} - // expected-warning@#cwg712-comma {{left operand of comma operator has no effect}} + // expected-warning@-3 {{left operand of comma operator has no effect}} + + use((cond, a)); + // expected-warning@-1 {{left operand of comma operator has no effect}} } }; } @@ -136,8 +137,8 @@ namespace cwg727 { // cwg727: partial // expected-error@-2 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}} // expected-note@#cwg727-C {{explicitly specialized declaration is here}} template<> void A::f<double>(); - // expected-error@-1 {{o function template matches function template specialization 'f'}} - // expected-error@-2 {{non-friend class member 'f' cannot have a qualified name}} + // expected-error@-1 {{non-friend class member 'f' cannot have a qualified name}} + // expected-error@-2 {{no function template matches function template specialization 'f'}} template<> int A::N<double>; // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}} // expected-error@-2 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}} @@ -188,37 +189,46 @@ namespace cwg727 { // cwg727: partial template<typename T> void f() { T::error; } // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}} // expected-note@#cwg727-f-float {{in instantiation of function template specialization 'cwg727::D<int>::f<float>' requested here}} - template<typename T> static const int N = T::error; - // cxx98-11-error@-1 {{variable templates are a C++14 extension}} - // expected-error@-2 {{type 'float' cannot be used prior to '::' because it has no members}} - // expected-note@#cwg727-N-float {{in instantiation of static data member 'cwg727::D<int>::N<float>' requested here}} template<> struct C<int> {}; template<> void f<int>() {} - template<> const int N<int>; template<typename T> struct C<T*> {}; - template<typename T> static const int N<T*>; - - template<typename> - struct E { - template<> void f<void>() {} - // expected-error@-1 {{no candidate function template was found for dependent member function template specialization}} - }; }; void d(D<int> di) { D<int>::C<int>(); di.f<int>(); - int a = D<int>::N<int>; - D<int>::C<int*>(); - int b = D<int>::N<int*>; + D<int>::C<float>(); // #cwg727-C-float + } + + template void D<int>::f<float>(); // #cwg727-f-float - D<int>::C<float>(); // #cwg727-C-float - di.f<float>(); // #cwg727-f-float - int c = D<int>::N<float>; // #cwg727-N-float +#if __cplusplus >= 201402L + template<typename> + struct E { + template<typename T> static const int N = T::error; + // since-cxx14-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}} + // since-cxx14-note@#cwg727-N-float {{in instantiation of static data member 'cwg727::E<int>::N<float>' requested here}} + template<> const int N<int>; + template<typename T> static const int N<T*>; + }; + void e() { + int a = E<int>::N<int>; + int b = E<int>::N<int*>; + int c = E<int>::N<float>; // #cwg727-N-float } +#endif + + template<typename> + struct F { + template<typename> + struct F2 { + template<> void f<void>() {} + // expected-error@-1 {{no candidate function template was found for dependent member function template specialization}} + }; + }; namespace mixed_inner_outer_specialization { #if __cplusplus >= 201103L @@ -294,23 +304,21 @@ namespace cwg727 { // cwg727: partial template<> int f2<T>() {} template<> int f2<U>() {} +#if __cplusplus >= 201402L template<typename> static int v1; - // cxx98-11-error@-1 {{variable templates are a C++14 extension}} template<> int v1<T>; // #cwg727-v1-T template<> int v1<U>; - // expected-error@-1 {{duplicate member 'v1'}} - // expected-note@#cwg727-Collision-int-int {{in instantiation of template class 'cwg727::Collision<int, int>' requested here}} - // expected-note@#cwg727-v1-T {{previous}} - + // since-cxx14-error@-1 {{duplicate member 'v1'}} + // since-cxx14-note@#cwg727-Collision-int-int {{in instantiation of template class 'cwg727::Collision<int, int>' requested here}} + // since-cxx14-note@#cwg727-v1-T {{previous declaration is here}} +#endif +#if __cplusplus >= 201703L template<typename> static inline int v2; - // cxx98-11-error@-1 {{variable templates are a C++14 extension}} - // cxx98-14-error@-2 {{inline variables are a C++17 extension}} template<> inline int v2<T>; // #cwg727-v2-T - // cxx98-14-error@-1 {{inline variables are a C++17 extension}} template<> inline int v2<U>; - // cxx98-14-error@-1 {{inline variables are a C++17 extension}} - // expected-error@-2 {{duplicate member 'v2'}} - // expected-note@#cwg727-v2-T {{previous declaration is here}} + // since-cxx17-error@-1 {{duplicate member 'v2'}} + // since-cxx17-note@#cwg727-v2-T {{previous declaration is here}} +#endif // FIXME: Missing diagnostic for duplicate class explicit specialization. template<typename> struct S1; @@ -321,7 +329,8 @@ namespace cwg727 { // cwg727: partial template<> struct S2<T> {}; // #cwg727-S2-T template<> struct S2<U> {}; // expected-error@-1 {{redefinition of 'S2<int>'}} - // expected-note@#cwg727-S2-T {{previous}} + // cxx98-11-note@#cwg727-Collision-int-int {{in instantiation of template class 'cwg727::Collision<int, int>' requested here}} + // expected-note@#cwg727-S2-T {{previous definition is here}} }; Collision<int, int> c; // #cwg727-Collision-int-int } // namespace cwg727 diff --git a/clang/test/CXX/drs/cwg98.cpp b/clang/test/CXX/drs/cwg98.cpp new file mode 100644 index 000000000000..5618b82388bf --- /dev/null +++ b/clang/test/CXX/drs/cwg98.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -std=c++98 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++11 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++14 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++17 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++23 %s -fexceptions -fcxx-exceptions -pedantic-errors -verify +// RUN: %clang_cc1 -std=c++2c %s -fexceptions -fcxx-exceptions -pedantic-errors -verify + +namespace cwg98 { // cwg98: 2.7 + void test(int n) { + switch (n) { + try { // #cwg98-try + case 0: + // expected-error@-1 {{cannot jump from switch statement to this case label}} + // expected-note@#cwg98-try {{jump bypasses initialization of try block}} + x: + throw n; + } catch (...) { // #cwg98-catch + case 1: + // expected-error@-1 {{cannot jump from switch statement to this case label}} + // expected-note@#cwg98-catch {{jump bypasses initialization of catch block}} + y: + throw n; + } + case 2: + goto x; + // expected-error@-1 {{cannot jump from this goto statement to its label}} + // expected-note@#cwg98-try {{jump bypasses initialization of try block}} + case 3: + goto y; + // expected-error@-1 {{cannot jump from this goto statement to its label}} + // expected-note@#cwg98-catch {{jump bypasses initialization of catch block}} + } + } +} // namespace cwg98 diff --git a/clang/test/CXX/drs/cwg9xx.cpp b/clang/test/CXX/drs/cwg9xx.cpp index 96e46742650d..3863cb4600fc 100644 --- a/clang/test/CXX/drs/cwg9xx.cpp +++ b/clang/test/CXX/drs/cwg9xx.cpp @@ -59,29 +59,33 @@ struct A { struct B : private A { // #cwg952-B }; struct C : B { - void f() { - I i1; - // expected-error@-1 {{'I' is a private member of 'cwg952::example1::A'}} - // expected-note@#cwg952-B {{constrained by private inheritance here}} - // expected-note@#cwg952-I {{member is declared here}} - } - I i2; + void f(); + I i1; // expected-error@-1 {{'I' is a private member of 'cwg952::example1::A'}} // expected-note@#cwg952-B {{constrained by private inheritance here}} // expected-note@#cwg952-I {{member is declared here}} struct D { - I i3; + I i2; // expected-error@-1 {{'I' is a private member of 'cwg952::example1::A'}} // expected-note@#cwg952-B {{constrained by private inheritance here}} // expected-note@#cwg952-I {{member is declared here}} - void g() { - I i4; - // expected-error@-1 {{'I' is a private member of 'cwg952::example1::A'}} - // expected-note@#cwg952-B {{constrained by private inheritance here}} - // expected-note@#cwg952-I {{member is declared here}} - } + void g(); }; }; + +void C::f() { + I i3; + // expected-error@-1 {{'I' is a private member of 'cwg952::example1::A'}} + // expected-note@#cwg952-B {{constrained by private inheritance here}} + // expected-note@#cwg952-I {{member is declared here}} +} + +void C::D::g() { + I i4; + // expected-error@-1 {{'I' is a private member of 'cwg952::example1::A'}} + // expected-note@#cwg952-B {{constrained by private inheritance here}} + // expected-note@#cwg952-I {{member is declared here}} +} } // namespace example1 namespace example2 { struct A { |
