diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 |
commit | 9f4dbff6669c8037f3b036bcf580d14f1a4f12a5 (patch) | |
tree | 47df2c12b57214af6c31e47404b005675b8b7ffc /test/CXX | |
parent | f73d5f23a889b93d89ddef61ac0995df40286bb8 (diff) |
Notes
Diffstat (limited to 'test/CXX')
108 files changed, 4455 insertions, 638 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp index 1f78a738f38bf..b9e83988cfb82 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp @@ -105,9 +105,10 @@ namespace InhCtor { }; + // FIXME: Consider reusing the same diagnostic between dependent and non-dependent contexts typedef int I; struct UsingInt { - using I::I; // expected-error {{expected a class or namespace}} + using I::I; // expected-error {{'I' (aka 'int') is not a class, namespace, or scoped enumeration}} }; template<typename T> struct UsingIntTemplate { using T::T; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp index 30393961b3f38..7918e9f861e4a 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp @@ -63,3 +63,14 @@ void test3() { Numbers2::f(f); Numbers2::g(f); // expected-error {{no viable conversion from 'float' to 'Numbers::Number'}} } + +namespace inline_ns { + int x; // expected-note 2{{found}} + inline namespace A { // expected-warning {{C++11}} + int x; // expected-note 2{{found}} + int y; // expected-note 2{{found}} + } + int y; // expected-note 2{{found}} + int k1 = x + y; // expected-error 2{{ambiguous}} + int k2 = inline_ns::x + inline_ns::y; // expected-error 2{{ambiguous}} +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp index c745c8451bc86..c3be712ddbcaa 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp @@ -1,26 +1,25 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// XFAIL: * -// Our C++0x doesn't currently have specialized destructor name handling, -// since the specification is still in flux. -struct C { +// expected-no-diagnostics + +struct C { typedef int I; -}; +}; -typedef int I1, I2; -extern int* p; -extern int* q; +typedef int I1, I2; +extern int* p; +extern int* q; void f() { - p->C::I::~I(); + p->C::I::~I(); q->I1::~I2(); } -struct A { +struct A { ~A(); -}; +}; -typedef A AB; +typedef A AB; int main() { - AB *p; + AB *p; p->AB::~AB(); } diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp index 0956de3c2a889..83c8dd8fc22df 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics struct C { typedef int I; @@ -20,5 +21,5 @@ struct A { typedef A AB; int main() { AB *p; - p->AB::~AB(); // expected-error{{expected the class name after '~' to name a destructor}} + p->AB::~AB(); } diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp index 253d15e90178d..c59c4a550d7a2 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -// XFAIL: * +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s class C { public: @@ -10,8 +9,13 @@ C::C(int a, // expected-note {{previous definition}} int b) // expected-note {{previous definition}} try { int c; - } catch (int a) { // expected-error {{redefinition of 'a'}} int b; // expected-error {{redefinition of 'b'}} ++c; // expected-error {{use of undeclared identifier 'c'}} } + +void f(int i) { + struct S { + void g() try {} catch (int i) {}; // OK + }; +} diff --git a/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp b/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp index 7c7b84d67823b..1b4199155faed 100644 --- a/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp +++ b/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp @@ -9,8 +9,8 @@ void func2(int i) try { // expected-note{{previous definition is here}} } catch (...) { } -void func3(int i) try { // FIXME: note {{previous definition is here}} -} catch (int i) { // FIXME: error {{redefinition of 'i'}} +void func3(int i) try { // expected-note {{previous definition is here}} +} catch (int i) { // expected-error {{redefinition of 'i'}} } void func4(int i) try { // expected-note{{previous definition is here}} @@ -58,3 +58,9 @@ void func10() { int b; // FIXME: decide whether this is valid } } + +void func11(int a) { + try { + } catch (int a) { // OK + } +} diff --git a/test/CXX/basic/basic.start/basic.start.init/p3.cpp b/test/CXX/basic/basic.start/basic.start.init/p3.cpp new file mode 100644 index 0000000000000..506232ebacc4c --- /dev/null +++ b/test/CXX/basic/basic.start/basic.start.init/p3.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -verify %s -pedantic-errors +// RUN: %clang_cc1 -verify %s -pedantic-errors -DINLINE +// RUN: %clang_cc1 -verify %s -pedantic-errors -DSTATIC +// RUN: %clang_cc1 -verify %s -pedantic-errors -std=c++11 -DCONSTEXPR +// RUN: %clang_cc1 -verify %s -std=c++11 -DDELETED + +#if INLINE +inline // expected-error {{'main' is not allowed to be declared inline}} +#elif STATIC +static // expected-error {{'main' is not allowed to be declared static}} +#elif CONSTEXPR +constexpr // expected-error {{'main' is not allowed to be declared constexpr}} +#endif +int main(int argc, char **argv) +#if DELETED + = delete; // expected-error {{'main' is not allowed to be deleted}} +#else +{ + int (*pmain)(int, char**) = &main; // expected-error {{ISO C++ does not allow 'main' to be used by a program}} + + if (argc) + main(0, 0); // expected-error {{ISO C++ does not allow 'main' to be used by a program}} +} +#endif diff --git a/test/CXX/basic/basic.start/basic.start.main/p2.cpp b/test/CXX/basic/basic.start/basic.start.main/p2.cpp index 5c7d60c1df4c3..42e87e5431f2a 100644 --- a/test/CXX/basic/basic.start/basic.start.main/p2.cpp +++ b/test/CXX/basic/basic.start/basic.start.main/p2.cpp @@ -62,6 +62,8 @@ main( // expected-error {{first parameter of 'main' (argument count) must be of ) { } +const int main(); // expected-error {{'main' must return 'int'}} + #elif TEST7 // expected-no-diagnostics diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp index 8a62ae84e2afc..3b77a62ce7d6f 100644 --- a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp +++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp @@ -9,7 +9,8 @@ namespace NS { void *operator new(size_t);; // expected-error {{'operator new' cannot be declared inside a namespace}} } -static void *operator new(size_t); // expected-error {{'operator new' cannot be declared static in global scope}} +static void *operator new(size_t); // expected-error {{static declaration of 'operator new' follows non-static declaration}} expected-note {{previous}} +static void *operator new(size_t, int, int); // expected-error {{'operator new' cannot be declared static in global scope}} struct B { void operator new(size_t); // expected-error {{'operator new' must return type 'void *'}} diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp index e00e9486f0bfa..09dde8efde00e 100644 --- a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp +++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp @@ -8,4 +8,5 @@ namespace NS { void operator delete(void *); // expected-error {{'operator delete' cannot be declared inside a namespace}} } -static void operator delete(void *); // expected-error {{'operator delete' cannot be declared static in global scope}} +static void operator delete(void *); // expected-error {{follows non-static declaration}} expected-note {{implicit}} +static void operator delete(void *, int, int); // expected-error {{'operator delete' cannot be declared static in global scope}} diff --git a/test/CXX/class.access/class.access.base/p1.cpp b/test/CXX/class.access/class.access.base/p1.cpp index 43cc99eb8b493..88e2688406c75 100644 --- a/test/CXX/class.access/class.access.base/p1.cpp +++ b/test/CXX/class.access/class.access.base/p1.cpp @@ -153,3 +153,18 @@ namespace test2 { t->Base::spriv++; // expected-error 2 {{private member}} } } + +namespace PR12788 { + class A { + protected: + struct { + int x; + }; + }; + class B : A { + void f() { + ++x; + A::x++; + } + }; +} diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp index 0564a52b6d0d9..435b09920df63 100644 --- a/test/CXX/class.access/p4.cpp +++ b/test/CXX/class.access/p4.cpp @@ -79,8 +79,8 @@ namespace test1 { -ca; // These are all surrogate calls ca(pub); - ca(prot); // expected-error {{'operator void (*)(class Protected &)' is a protected member}} - ca(priv); // expected-error {{'operator void (*)(class Private &)' is a private member}} + ca(prot); // expected-error {{'operator void (*)(Protected &)' is a protected member}} + ca(priv); // expected-error {{'operator void (*)(Private &)' is a private member}} } } diff --git a/test/CXX/class.access/p6.cpp b/test/CXX/class.access/p6.cpp index 6a93658fc78d0..f9b95f0851ef3 100644 --- a/test/CXX/class.access/p6.cpp +++ b/test/CXX/class.access/p6.cpp @@ -177,7 +177,7 @@ namespace test8 { }; void test(A &a) { - if (a) return; // expected-error {{'operator void *(class test8::A::*)(void) const' is a private member of 'test8::A'}} + if (a) return; // expected-error-re {{'operator void *(test8::A::*)(){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}} } } diff --git a/test/CXX/class/class.static/class.static.data/p4.cpp b/test/CXX/class/class.static/class.static.data/p4.cpp index 2b1eca7419374..85d18c6b5fac2 100644 --- a/test/CXX/class/class.static/class.static.data/p4.cpp +++ b/test/CXX/class/class.static/class.static.data/p4.cpp @@ -10,15 +10,14 @@ struct OutOfClassInitializerOnly { int const OutOfClassInitializerOnly::i = 0; struct InClassInitializerAndOutOfClassCopyInitializer { - static const int i = 0; // expected-note{{previous definition is here}} + static const int i = 0; // expected-note{{previous initialization is here}} }; -int const InClassInitializerAndOutOfClassCopyInitializer::i = 0; // expected-error{{redefinition of 'i'}} +int const InClassInitializerAndOutOfClassCopyInitializer::i = 0; // expected-error{{static data member 'i' already has an initializer}} struct InClassInitializerAndOutOfClassDirectInitializer { - static const int i = 0; // expected-note{{previous definition is here}} + static const int i = 0; // expected-note{{previous initialization is here}} }; -int const InClassInitializerAndOutOfClassDirectInitializer::i(0); // expected-error{{redefinition of 'i'}} - +int const InClassInitializerAndOutOfClassDirectInitializer::i(0); // expected-error{{static data member 'i' already has an initializer}} int main() { } diff --git a/test/CXX/class/class.union/p8.cpp b/test/CXX/class/class.union/p8.cpp new file mode 100644 index 0000000000000..cc54ba4066193 --- /dev/null +++ b/test/CXX/class/class.union/p8.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +union U { + int x = 0; // expected-note {{previous initialization is here}} + union {}; + union { + int z; + int y = 1; // expected-error {{initializing multiple members of union}} + }; +}; diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp index c7966ce643f1b..4ffb93a1ef74d 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp @@ -1,14 +1,16 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// C++03 [namespace.udecl]p11: +// C++03 [namespace.udecl]p11: (per DR101) // If a function declaration in namespace scope or block scope has // the same name and the same parameter types as a function -// introduced by a using-declaration, the program is -// ill-formed. [Note: two using-declarations may introduce functions -// with the same name and the same parameter types. If, for a call -// to an unqualified function name, function overload resolution -// selects the functions introduced by such using-declarations, the -// function call is ill-formed. +// introduced by a using-declaration, and the declarations do not declare the +// same function, the program is ill-formed. [Note: two using-declarations may +// introduce functions with the same name and the same parameter types. If, +// for a call to an unqualified function name, function overload resolution +// selects the functions introduced by such using-declarations, the function +// call is ill-formed.] +// +// FIXME: DR565 introduces parallel wording here for function templates. namespace test0 { namespace ns { void foo(); } // expected-note {{target of using declaration}} @@ -89,3 +91,19 @@ namespace test5 { template class Test0<int>; template class Test1<int>; } + +namespace test6 { + namespace ns { void foo(); } // expected-note {{target of using declaration}} + using ns::foo; // expected-note {{using declaration}} + namespace ns { + using test6::foo; + void foo() {} + } + void foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}} +} + +namespace test7 { + void foo(); + using test7::foo; + void foo() {} +} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp index edaa975a58905..35ef3b57b0cc2 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp @@ -7,6 +7,6 @@ struct A { }; struct B : A { - using A::f<double>; // expected-error{{using declaration can not refer to a template specialization}} - using A::X<int>; // expected-error{{using declaration can not refer to a template specialization}} + using A::f<double>; // expected-error{{using declaration cannot refer to a template specialization}} + using A::X<int>; // expected-error{{using declaration cannot refer to a template specialization}} }; diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp index c4b8849e58cfc..c2fb95902454d 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp @@ -5,4 +5,4 @@ namespace A { namespace B { } } -using A::B; // expected-error{{using declaration can not refer to namespace}} +using A::B; // expected-error{{using declaration cannot refer to namespace}} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp index 78b5a41648a76..4f89dcfb3f522 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp @@ -1,4 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s +// RUN: not %clang_cc1 -fsyntax-only -std=c++98 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX98 %s +// RUN: not %clang_cc1 -fsyntax-only -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefix=CXX11 %s // C++0x N2914. struct X { @@ -6,10 +9,101 @@ struct X { static int a; }; -using X::i; // expected-error{{using declaration can not refer to class member}} -using X::s; // expected-error{{using declaration can not refer to class member}} +using X::i; // expected-error{{using declaration cannot refer to class member}} +using X::s; // expected-error{{using declaration cannot refer to class member}} void f() { - using X::i; // expected-error{{using declaration can not refer to class member}} - using X::s; // expected-error{{using declaration can not refer to class member}} + using X::i; // expected-error{{using declaration cannot refer to class member}} + using X::s; // expected-error{{using declaration cannot refer to class member}} +} + +struct S { + static int n; + struct Q {}; + enum E {}; + typedef Q T; + void f(); + static void g(); +}; + +using S::n; // expected-error{{class member}} expected-note {{use a reference instead}} +#if __cplusplus < 201103L +// CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-2]] +#else +// CXX11: fix-it:"{{.*}}":{[[@LINE-4]]:1-[[@LINE-4]]:6}:"auto &n = " +#endif + +using S::Q; // expected-error{{class member}} +#if __cplusplus < 201103L +// expected-note@-2 {{use a typedef declaration instead}} +// CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef" +// CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" Q" +#else +// expected-note@-6 {{use an alias declaration instead}} +// CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"Q = " +#endif + +using S::E; // expected-error{{class member}} +#if __cplusplus < 201103L +// expected-note@-2 {{use a typedef declaration instead}} +// CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef" +// CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" E" +#else +// expected-note@-6 {{use an alias declaration instead}} +// CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"E = " +#endif + +using S::T; // expected-error{{class member}} +#if __cplusplus < 201103L +// expected-note@-2 {{use a typedef declaration instead}} +// CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef" +// CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" T" +#else +// expected-note@-6 {{use an alias declaration instead}} +// CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"T = " +#endif + +using S::f; // expected-error{{class member}} +using S::g; // expected-error{{class member}} + +void h() { + using S::n; // expected-error{{class member}} expected-note {{use a reference instead}} +#if __cplusplus < 201103L + // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-2]] +#else + // CXX11: fix-it:"{{.*}}":{[[@LINE-4]]:3-[[@LINE-4]]:8}:"auto &n = " +#endif + + using S::Q; // expected-error{{class member}} +#if __cplusplus < 201103L + // expected-note@-2 {{use a typedef declaration instead}} + // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef" + // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" Q" +#else + // expected-note@-6 {{use an alias declaration instead}} + // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"Q = " +#endif + + using S::E; // expected-error{{class member}} +#if __cplusplus < 201103L + // expected-note@-2 {{use a typedef declaration instead}} + // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef" + // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" E" +#else + // expected-note@-6 {{use an alias declaration instead}} + // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"E = " +#endif + + using S::T; // expected-error{{class member}} +#if __cplusplus < 201103L + // expected-note@-2 {{use a typedef declaration instead}} + // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef" + // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" T" +#else + // expected-note@-6 {{use an alias declaration instead}} + // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"T = " +#endif + + using S::f; // expected-error{{class member}} + using S::g; // expected-error{{class member}} } diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp index 10be98d16ea04..3c250f9d25dd2 100644 --- a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp +++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp @@ -9,6 +9,7 @@ alignas(1) alignas(4) int n6 alignas(2); // ok alignas(1) int n7 alignas(2), // expected-error {{less than minimum alignment}} n8 alignas(4); // ok alignas(8) int n9 alignas(2); // ok, overaligned +alignas(1) extern int n10; // expected-error {{less than minimum alignment}} enum alignas(1) E1 {}; // expected-error {{requested alignment is less than minimum alignment of 4 for type 'E1'}} enum alignas(1) E2 : char {}; // ok diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp index 21119398b2f4f..3bbbf9eed6e4f 100644 --- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp +++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp @@ -1,25 +1,25 @@ // RUN: %clang_cc1 -std=c++1y -verify %s -class [[deprecated]] C {}; // expected-note {{declared here}} +class [[deprecated]] C {}; // expected-note {{'C' has been explicitly marked deprecated here}} C c; // expected-warning {{'C' is deprecated}} -typedef int t [[deprecated]]; // expected-note {{declared here}} +typedef int t [[deprecated]]; // expected-note {{'t' has been explicitly marked deprecated here}} t x = 42; // expected-warning {{'t' is deprecated}} -[[deprecated]] int old = 42; // expected-note {{declared here}} +[[deprecated]] int old = 42; // expected-note {{'old' has been explicitly marked deprecated here}} int use = old; // expected-warning {{'old' is deprecated}} -struct S { [[deprecated]] int member = 42; } s; // expected-note {{declared here}} +struct S { [[deprecated]] int member = 42; } s; // expected-note {{'member' has been explicitly marked deprecated here}} int use2 = s.member; // expected-warning {{'member' is deprecated}} -[[deprecated]] int f() { return 42; } // expected-note {{declared here}} +[[deprecated]] int f() { return 42; } // expected-note {{'f' has been explicitly marked deprecated here}} int use3 = f(); // expected-warning {{'f' is deprecated}} -enum [[deprecated]] e { E }; // expected-note {{declared here}} +enum [[deprecated]] e { E }; // expected-note {{'e' has been explicitly marked deprecated here}} e my_enum; // expected-warning {{'e' is deprecated}} template <typename T> class X {}; -template <> class [[deprecated]] X<int> {}; // expected-note {{declared here}} +template <> class [[deprecated]] X<int> {}; // expected-note {{'X<int>' has been explicitly marked deprecated here}} X<char> x1; // FIXME: The diagnostic here could be much better by mentioning X<int>. X<int> x2; // expected-warning {{'X' is deprecated}} diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp index 0af241f55fe52..59cac367dbf23 100644 --- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp +++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp @@ -13,7 +13,7 @@ void a2 [[noreturn]] () { [[noreturn()]] void c(); // expected-error {{attribute 'noreturn' cannot have an argument list}} void d() [[noreturn]]; // expected-error {{'noreturn' attribute cannot be applied to types}} -int d2 [[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions and methods}} +int d2 [[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions}} [[noreturn]] int e() { b2(); } // ok diff --git a/test/CXX/dcl.dcl/dcl.enum/p2.cpp b/test/CXX/dcl.dcl/dcl.enum/p2.cpp new file mode 100644 index 0000000000000..de826d0570422 --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.enum/p2.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +// expected-no-diagnostics +enum class E : int const volatile { }; +using T = __underlying_type(E); +using T = int; diff --git a/test/CXX/dcl.dcl/dcl.link/p2.cpp b/test/CXX/dcl.dcl/dcl.link/p2.cpp new file mode 100644 index 0000000000000..d1c3bcb8fa037 --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.link/p2.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +extern "C" { + extern R"(C++)" { } +} + +#define plusplus "++" +extern "C" plusplus { +} + +extern u8"C" {} // expected-error {{string literal in language linkage specifier cannot have an encoding-prefix}} +extern L"C" {} // expected-error {{string literal in language linkage specifier cannot have an encoding-prefix}} +extern u"C++" {} // expected-error {{string literal in language linkage specifier cannot have an encoding-prefix}} +extern U"C" {} // expected-error {{string literal in language linkage specifier cannot have an encoding-prefix}} diff --git a/test/CXX/dcl.dcl/dcl.link/p7.cpp b/test/CXX/dcl.dcl/dcl.link/p7.cpp index bd9ff3c3665c2..7d80a22ca3007 100644 --- a/test/CXX/dcl.dcl/dcl.link/p7.cpp +++ b/test/CXX/dcl.dcl/dcl.link/p7.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s struct X { }; @@ -7,8 +7,6 @@ struct X { }; // CHECK: @x2 = external global %struct.X // CHECK: @x3 = external global %struct.X extern "C" { - - X x1; } diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp index cf422972a280c..08fefdc91fb5b 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp @@ -27,7 +27,7 @@ void f2(constexpr int i) {} // expected-error {{function parameter cannot be con struct s2 { constexpr int mi1; // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}} static constexpr int mi2; // expected-error {{requires an initializer}} - mutable constexpr int mi3 = 3; // expected-error-re {{non-static data member cannot be constexpr$}} expected-error {{'mutable' and 'const' cannot be mixed}} + mutable constexpr int mi3 = 3; // expected-error-re {{non-static data member cannot be constexpr{{$}}}} expected-error {{'mutable' and 'const' cannot be mixed}} }; // typedef typedef constexpr int CI; // expected-error {{typedef cannot be constexpr}} @@ -73,7 +73,7 @@ template <typename T> T gt(T t) { return t; } struct S { template<typename T> constexpr T f(); // expected-warning {{C++1y}} template <typename T> - T g() const; // expected-note {{candidate template ignored: could not match 'T () const' against 'char ()'}} + T g() const; // expected-note-re {{candidate template ignored: could not match 'T (){{( __attribute__\(\(thiscall\)\))?}} const' against 'char (){{( __attribute__\(\(thiscall\)\))?}}'}} }; // explicit specialization can differ in constepxr diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp index 001a086a008b6..eeb5b6f9c2aa1 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm -triple %itanium_abi_triple %s -o - | FileCheck %s // constexpr functions and constexpr constructors are implicitly inline. struct S { diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp index bb7f7ac326e73..370f732fd92b9 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp @@ -35,7 +35,7 @@ template<typename R> struct ConstexprMember { constexpr R F() const { return 0; } }; constexpr int d = ConstexprMember<int>().F(); // ok -constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}} +constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}} expected-note {{non-literal type 'const NonLiteral' cannot be used in a constant expression}} template<typename ...P> struct ConstexprCtor { constexpr ConstexprCtor(P...) {} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp index 07eec1edbe397..12237a39ab54a 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp @@ -1,7 +1,6 @@ -// RUN: %clang_cc1 -verify %s -// XFAIL: * +// RUN: %clang_cc1 -fsyntax-only -verify %s -void f0() { +void f0() { // expected-note {{previous definition is here}} } -inline void f0(); // expected-error {{function definition cannot precede inline declaration}} +inline void f0(); // expected-error {{inline declaration of 'f0' follows non-inline definition}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp index ee870d9601614..5d1e6fb85ce9c 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp @@ -14,3 +14,7 @@ public: explicit A::A() { } // expected-error {{'explicit' can only be specified inside the class definition}} explicit A::operator bool() { return false; } // expected-warning {{explicit conversion functions are a C++11 extension}}\ // expected-error {{'explicit' can only be specified inside the class definition}} + +class B { + friend explicit A::A(); // expected-error {{'explicit' is invalid in friend declarations}} +}; diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp index fd86276e85488..d7e7c52f3f70d 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -verify %s -// XFAIL: * +// RUN: %clang_cc1 -fsyntax-only -verify %s typedef const int T0; typedef int& T1; @@ -9,6 +8,6 @@ struct s0 { mutable T0 f1; // expected-error{{'mutable' and 'const' cannot be mixed}} mutable int &f2; // expected-error{{'mutable' cannot be applied to references}} mutable T1 f3; // expected-error{{'mutable' cannot be applied to references}} - mutable struct s1 {}; // expected-error{{'mutable' cannot be applied to non-data members}} + mutable struct s1 {}; // expected-error{{'mutable' can only be applied to member variables}} mutable void im0(); // expected-error{{'mutable' cannot be applied to functions}} }; diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp index 84f9f9b829834..46c874f605cbf 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-c++1y-extensions // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions template<typename T> @@ -41,3 +42,25 @@ struct S { }; const int S::b; const auto S::c = 0; + +namespace std { template<typename T> struct initializer_list { initializer_list(); }; } + +// In an initializer of the form ( expression-list ), the expression-list +// shall be a single assigment-expression. +auto parens1(1); +auto parens2(2, 3); // expected-error {{initializer for variable 'parens2' with type 'auto' contains multiple expressions}} +#if __cplusplus >= 201103L +auto parens3({4, 5, 6}); // expected-error {{cannot deduce type for variable 'parens3' with type 'auto' from parenthesized initializer list}} +auto parens4 = [p4(1)] {}; +auto parens5 = [p5(2, 3)] {}; // expected-error {{initializer for lambda capture 'p5' contains multiple expressions}} +auto parens6 = [p6({4, 5, 6})] {}; // expected-error {{cannot deduce type for lambda capture 'p6' from parenthesized initializer list}} +#endif + +#if __cplusplus >= 201402L +namespace std_example { + // The other half of this example is in p3.cpp + auto f() -> int; + auto g() { return 0.0; } + auto h(); +} +#endif diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp index 1ed93b137540f..7f1b3b0f240ed 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp @@ -30,29 +30,33 @@ struct DD { typedef int n; }; +PD pd(); +DD dd(); + struct A { - decltype(PD()) s; // ok - decltype(PD())::n n; // ok - decltype(DD()) *p = new decltype(DD()); // ok + decltype(pd()) s; // ok + decltype(pd())::n n; // ok + decltype(dd()) *p = new decltype(dd()); // ok }; +A a(); // Two errors here: one for the decltype, one for the variable. decltype( - PD(), // expected-error {{private destructor}} - PD()) pd1; // expected-error {{private destructor}} -decltype(DD(), // expected-error {{deleted function}} - DD()) dd1; -decltype(A(), - DD()) dd2; // expected-error {{deleted function}} + pd(), // expected-error {{private destructor}} + pd()) pd1; // expected-error {{private destructor}} +decltype(dd(), // expected-error {{deleted function}} + dd()) dd1; +decltype(a(), + dd()) dd2; // expected-error {{deleted function}} decltype( - PD(), // expected-error {{temporary of type 'PD' has private destructor}} + pd(), // expected-error {{temporary of type 'PD' has private destructor}} 0) pd2; -decltype(((13, ((DD())))))::n dd_parens; // ok -decltype(((((42)), PD())))::n pd_parens_comma; // ok +decltype(((13, ((dd())))))::n dd_parens; // ok +decltype(((((42)), pd())))::n pd_parens_comma; // ok // Ensure parens aren't stripped from a decltype node. -extern decltype(PD()) pd_ref; // ok +extern decltype(pd()) pd_ref; // ok decltype((pd_ref)) pd_ref3 = pd_ref; // ok, PD & decltype(pd_ref) pd_ref2 = pd_ref; // expected-error {{private destructor}} @@ -107,7 +111,7 @@ namespace RequireCompleteType { namespace Overload { DD operator+(PD &a, PD &b); - decltype(PD()) *pd_ptr; + decltype(pd()) *pd_ptr; decltype(*pd_ptr + *pd_ptr) *dd_ptr; // ok decltype(0, *pd_ptr) pd_ref2 = pd_ref; // ok diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp index 02cc973018b87..39d6e706b6c1c 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp @@ -2,12 +2,12 @@ using X = struct { // ok }; -template<typename T> using Y = struct { // expected-error {{can not be defined in a type alias template}} +template<typename T> using Y = struct { // expected-error {{cannot be defined in a type alias template}} }; class K { virtual ~K(); - operator struct S {} (); // expected-error{{'K::S' can not be defined in a type specifier}} + operator struct S {} (); // expected-error{{'K::S' cannot be defined in a type specifier}} }; struct A {}; @@ -18,26 +18,26 @@ void f() { for (struct S { S(int) {} } s : arr) { // expected-error {{types may not be defined in a for range declaration}} } - new struct T {}; // expected-error {{'T' can not be defined in a type specifier}} - new struct A {}; // expected-error {{'A' can not be defined in a type specifier}} + new struct T {}; // expected-error {{'T' cannot be defined in a type specifier}} + new struct A {}; // expected-error {{'A' cannot be defined in a type specifier}} - try {} catch (struct U {}) {} // expected-error {{'U' can not be defined in a type specifier}} + try {} catch (struct U {}) {} // expected-error {{'U' cannot be defined in a type specifier}} - (void)(struct V { V(int); })0; // expected-error {{'V' can not be defined in a type specifier}} + (void)(struct V { V(int); })0; // expected-error {{'V' cannot be defined in a type specifier}} - (void)dynamic_cast<struct W {}*>((K*)0); // expected-error {{'W' can not be defined in a type specifier}} - (void)static_cast<struct X {}*>(0); // expected-error {{'X' can not be defined in a type specifier}} - (void)reinterpret_cast<struct Y {}*>(0); // expected-error {{'Y' can not be defined in a type specifier}} - (void)const_cast<struct Z {}*>((const Z*)0); // expected-error {{'Z' can not be defined in a type specifier}} + (void)dynamic_cast<struct W {}*>((K*)0); // expected-error {{'W' cannot be defined in a type specifier}} + (void)static_cast<struct X {}*>(0); // expected-error {{'X' cannot be defined in a type specifier}} + (void)reinterpret_cast<struct Y {}*>(0); // expected-error {{'Y' cannot be defined in a type specifier}} + (void)const_cast<struct Z {}*>((const Z*)0); // expected-error {{'Z' cannot be defined in a type specifier}} } -void g() throw (struct Ex {}) { // expected-error {{'Ex' can not be defined in a type specifier}} +void g() throw (struct Ex {}) { // expected-error {{'Ex' cannot be defined in a type specifier}} } -alignas(struct Aa {}) int x; // expected-error {{'Aa' can not be defined in a type specifier}} +alignas(struct Aa {}) int x; // expected-error {{'Aa' cannot be defined in a type specifier}} -int a = sizeof(struct So {}); // expected-error {{'So' can not be defined in a type specifier}} -int b = alignof(struct Ao {}); // expected-error {{'Ao' can not be defined in a type specifier}} +int a = sizeof(struct So {}); // expected-error {{'So' cannot be defined in a type specifier}} +int b = alignof(struct Ao {}); // expected-error {{'Ao' cannot be defined in a type specifier}} namespace std { struct type_info; } -const std::type_info &ti = typeid(struct Ti {}); // expected-error {{'Ti' can not be defined in a type specifier}} +const std::type_info &ti = typeid(struct Ti {}); // expected-error {{'Ti' cannot be defined in a type specifier}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp index 89a28adcc65c1..cc44f74a5547e 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp @@ -154,5 +154,5 @@ namespace Access { namespace VoidArg { using V = void; V f(int); // ok - V g(V); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}} + V g(V); // ok (DR577) } diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp index b30e0ec7856ba..b44b2c7d1566b 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp @@ -8,9 +8,9 @@ namespace PR12453 { template<typename T> void f(int i) { T x{i}; // expected-error{{non-constant-expression cannot be narrowed from type 'int' to 'float' in initializer list}} \ - // expected-note{{override this message by inserting an explicit cast}} + // expected-note{{insert an explicit cast to silence this issue}} T y{i}; // expected-error{{non-constant-expression cannot be narrowed from type 'int' to 'float' in initializer list}} \ - // expected-note{{override this message by inserting an explicit cast}} + // expected-note{{insert an explicit cast to silence this issue}} } template void f<float>(int); // expected-note{{in instantiation of function template specialization 'PR12453::f<float>' requested here}} diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp index 58d038366c81e..971e0c11aff14 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp @@ -23,7 +23,7 @@ namespace std { namespace bullet1 { double ad[] = { 1, 2.0 }; - int ai[] = { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} + int ai[] = { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} struct S2 { int m1; @@ -31,7 +31,7 @@ namespace bullet1 { }; S2 s21 = { 1, 2, 3.0 }; - S2 s22 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} + S2 s22 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} S2 s23 { }; } @@ -62,13 +62,13 @@ namespace bullet4_example3 { }; S s1 = { 1, 2, 3.0 }; - S s2 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} + S s2 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} S s3 {}; } namespace bullet5 { int x1 {2}; - int x2 {2.0}; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} + int x2 {2.0}; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} } namespace bullet6 { @@ -81,7 +81,7 @@ namespace bullet6 { const S& r2 = { "Spinach" }; S& r3 = { 1, 2, 3 }; // expected-error {{non-const lvalue reference to type 'bullet6::S' cannot bind to an initializer list temporary}} const int& i1 = { 1 }; - const int& i2 = { 1.1 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}} + const int& i2 = { 1.1 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} expected-warning {{implicit conversion}} const int (&iar)[2] = { 1, 2 }; } @@ -92,20 +92,20 @@ namespace bullet7 { namespace bullet8 { struct A { int i; int j; }; A a1 { 1, 2 }; - A a2 { 1.2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}} + A a2 { 1.2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} expected-warning {{implicit conversion}} struct B { B(std::initializer_list<int> i) {} }; B b1 { 1, 2 }; - B b2 { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} + B b2 { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} struct C { C(int i, double j) {} }; C c1 = { 1, 2.2 }; // FIXME: Suppress the narrowing warning in the cases where we issue a narrowing error. - C c2 = { 1.1, 2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}} + C c2 = { 1.1, 2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} expected-warning {{implicit conversion}} int j { 1 }; int k { }; diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp index 0bea4ede19cad..299611ba73593 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp @@ -26,7 +26,7 @@ void test_template() { maybe_shrink_int((char)3); // CHECK: warning:{{.*}} cannot be narrowed // CHECK: note:{{.*}} in instantiation - // CHECK: note:{{.*}} override + // CHECK: note:{{.*}} silence // FIXME: This should be static_cast<T>. // CHECK: fix-it:{{.*}}"static_cast<char>(" // CHECK: fix-it:{{.*}}")" diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp index 9b1727fd04afe..42dee92b3ca33 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp @@ -8,16 +8,16 @@ void std_example() { const int y = 999; const int z = 99; char c1 = x; // OK, though it might narrow (in this case, it does narrow) - char c2{x}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - char c3{y}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + char c2{x}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + char c3{y}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}} char c4{z}; // OK: no narrowing needed unsigned char uc1 = {5}; // OK: no narrowing needed - unsigned char uc2 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - unsigned int ui1 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + unsigned char uc2 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + unsigned int ui1 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} signed int si1 = - { (unsigned int)-1 }; // expected-error {{ cannot be narrowed }} expected-note {{override}} - int ii = {2.0}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - float f1 { x }; // expected-error {{ cannot be narrowed }} expected-note {{override}} + { (unsigned int)-1 }; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + int ii = {2.0}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + float f1 { x }; // expected-error {{ cannot be narrowed }} expected-note {{silence}} float f2 { 7 }; // OK: 7 can be exactly represented as a float int f(int); int a[] = @@ -44,19 +44,19 @@ template<typename T> Convert<T> ConvertVar(); // * from a floating-point type to an integer type, or void float_to_int() { - Agg<char> a1 = {1.0F}; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} - Agg<char> a2 = {1.0}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - Agg<char> a3 = {1.0L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<char> a1 = {1.0F}; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{silence}} + Agg<char> a2 = {1.0}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + Agg<char> a3 = {1.0L}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} float f = 1.0; double d = 1.0; long double ld = 1.0; - Agg<char> a4 = {f}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - Agg<char> a5 = {d}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - Agg<char> a6 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<char> a4 = {f}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + Agg<char> a5 = {d}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + Agg<char> a6 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} - Agg<char> ce1 = { Convert<float>(1.0) }; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} - Agg<char> ce2 = { ConvertVar<double>() }; // expected-error {{type 'double' cannot be narrowed to 'char'}} expected-note {{override}} + Agg<char> ce1 = { Convert<float>(1.0) }; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{silence}} + Agg<char> ce2 = { ConvertVar<double>() }; // expected-error {{type 'double' cannot be narrowed to 'char'}} expected-note {{silence}} } // * from long double to double or float, or from double to float, except where @@ -72,8 +72,8 @@ void shrink_float() { // Variables. Agg<float> f1 = {f}; // OK (no-op) - Agg<float> f2 = {d}; // expected-error {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{override}} - Agg<float> f3 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<float> f2 = {d}; // expected-error {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{silence}} + Agg<float> f3 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} // Exact constants. Agg<float> f4 = {1.0}; // OK (double constant represented exactly) Agg<float> f5 = {1.0L}; // OK (long double constant represented exactly) @@ -81,8 +81,8 @@ void shrink_float() { Agg<float> f6 = {0.1}; // OK (double constant in range but rounded) Agg<float> f7 = {0.1L}; // OK (long double constant in range but rounded) // Out of range constants. - Agg<float> f8 = {1E50}; // expected-error {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{override}} - Agg<float> f9 = {1E50L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<float> f8 = {1E50}; // expected-error {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{silence}} + Agg<float> f9 = {1E50L}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} // More complex constant expression. constexpr long double e40 = 1E40L, e30 = 1E30L, e39 = 1E39L; Agg<float> f10 = {e40 - 5 * e39 + e30 - 5 * e39}; // OK @@ -90,19 +90,19 @@ void shrink_float() { // Variables. Agg<double> d1 = {f}; // OK (widening) Agg<double> d2 = {d}; // OK (no-op) - Agg<double> d3 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<double> d3 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} // Exact constant. Agg<double> d4 = {1.0L}; // OK (long double constant represented exactly) // Inexact but in-range constant. Agg<double> d5 = {0.1L}; // OK (long double constant in range but rounded) // Out of range constant. - Agg<double> d6 = {1E315L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<double> d6 = {1E315L}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} // More complex constant expression. constexpr long double e315 = 1E315L, e305 = 1E305L, e314 = 1E314L; Agg<double> d7 = {e315 - 5 * e314 + e305 - 5 * e314}; // OK - Agg<float> ce1 = { Convert<double>(1e300) }; // expected-error {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{override}} - Agg<double> ce2 = { ConvertVar<long double>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{override}} + Agg<float> ce1 = { Convert<double>(1e300) }; // expected-error {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{silence}} + Agg<double> ce2 = { ConvertVar<long double>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{silence}} } // * from an integer type or unscoped enumeration type to a floating-point type, @@ -114,16 +114,16 @@ void int_to_float() { char c = 1; // Variables. Yes, even though all char's will fit into any floating type. - Agg<float> f1 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - Agg<double> f2 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - Agg<long double> f3 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<float> f1 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + Agg<double> f2 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + Agg<long double> f3 = {c}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} // Constants. Agg<float> f4 = {12345678}; // OK (exactly fits in a float) - Agg<float> f5 = {123456789}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<float> f5 = {123456789}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} - Agg<float> ce1 = { Convert<int>(123456789) }; // expected-error {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{override}} - Agg<double> ce2 = { ConvertVar<long long>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{override}} + Agg<float> ce1 = { Convert<int>(123456789) }; // expected-error {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{silence}} + Agg<double> ce2 = { ConvertVar<long long>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{silence}} } // * from an integer type or unscoped enumeration type to an integer type that @@ -135,52 +135,53 @@ void shrink_int() { // Not a constant expression. short s = 1; unsigned short us = 1; - Agg<char> c1 = {s}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - Agg<unsigned short> s1 = {s}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - Agg<short> s2 = {us}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<char> c1 = {s}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + Agg<unsigned short> s1 = {s}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + Agg<short> s2 = {us}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} // "that cannot represent all the values of the original type" means that the // validity of the program depends on the relative sizes of integral types. // This test compiles with -m64, so sizeof(int)<sizeof(long)==sizeof(long // long). long l1 = 1; - Agg<int> i1 = {l1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<int> i1 = {l1}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} long long ll = 1; Agg<long> l2 = {ll}; // OK // Constants. Agg<char> c2 = {127}; // OK - Agg<char> c3 = {300}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + Agg<char> c3 = {300}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}} Agg<int> i2 = {0x7FFFFFFFU}; // OK - Agg<int> i3 = {0x80000000U}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - Agg<unsigned int> i4 = {-0x80000000L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<int> i3 = {0x80000000U}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + Agg<unsigned int> i4 = {-0x80000000L}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} // Bool is also an integer type, but conversions to it are a different AST // node. Agg<bool> b1 = {0}; // OK Agg<bool> b2 = {1}; // OK - Agg<bool> b3 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<bool> b3 = {-1}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} // Conversions from pointers to booleans aren't narrowing conversions. - Agg<bool> b = {&b1}; // OK + Agg<bool>* ptr = &b1; + Agg<bool> b = {ptr}; // OK - Agg<short> ce1 = { Convert<int>(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}} - Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}} + Agg<short> ce1 = { Convert<int>(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{silence}} expected-warning {{changes value from 100000 to -31072}} + Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{silence}} // Negative -> larger unsigned type. - unsigned long long ll1 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}} + unsigned long long ll1 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{silence}} unsigned long long ll2 = { 1 }; // OK - unsigned long long ll3 = { s }; // expected-error {{cannot be narrowed from type 'short'}} expected-note {{override}} + unsigned long long ll3 = { s }; // expected-error {{cannot be narrowed from type 'short'}} expected-note {{silence}} unsigned long long ll4 = { us }; // OK - unsigned long long ll5 = { ll }; // expected-error {{cannot be narrowed from type 'long long'}} expected-note {{override}} - Agg<unsigned long long> ll6 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}} + unsigned long long ll5 = { ll }; // expected-error {{cannot be narrowed from type 'long long'}} expected-note {{silence}} + Agg<unsigned long long> ll6 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{silence}} Agg<unsigned long long> ll7 = { 18446744073709551615ULL }; // OK - Agg<unsigned long long> ll8 = { __int128(18446744073709551615ULL) + 1 }; // expected-error {{ 18446744073709551616 which cannot be narrowed}} expected-note {{override}} expected-warning {{changes value}} + Agg<unsigned long long> ll8 = { __int128(18446744073709551615ULL) + 1 }; // expected-error {{ 18446744073709551616 which cannot be narrowed}} expected-note {{silence}} expected-warning {{changes value}} signed char c = 'x'; - unsigned short usc1 = { c }; // expected-error {{non-constant-expression cannot be narrowed from type 'signed char'}} expected-note {{override}} + unsigned short usc1 = { c }; // expected-error {{non-constant-expression cannot be narrowed from type 'signed char'}} expected-note {{silence}} unsigned short usc2 = { (signed char)'x' }; // OK - unsigned short usc3 = { (signed char)-1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}} + unsigned short usc3 = { (signed char)-1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{silence}} } // Be sure that type- and value-dependent expressions in templates get the error @@ -188,9 +189,9 @@ void shrink_int() { template<int I, typename T> void maybe_shrink_int(T t) { - Agg<short> s1 = {t}; // expected-error {{ cannot be narrowed }} expected-note {{override}} - Agg<short> s2 = {I}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} - Agg<T> t2 = {700}; // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + Agg<short> s1 = {t}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + Agg<short> s2 = {I}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}} + Agg<T> t2 = {700}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}} } void test_template() { @@ -203,9 +204,9 @@ void test_template() { void test_qualifiers(int i) { const int j = i; - struct {const unsigned char c;} c1 = {j}; // expected-error {{from type 'int' to 'unsigned char' in}} expected-note {{override}} + struct {const unsigned char c;} c1 = {j}; // expected-error {{from type 'int' to 'unsigned char' in}} expected-note {{silence}} // Template arguments make it harder to avoid printing qualifiers: - Agg<const unsigned char> c2 = {j}; // expected-error {{from type 'int' to 'const unsigned char' in}} expected-note {{override}} + Agg<const unsigned char> c2 = {j}; // expected-error {{from type 'int' to 'const unsigned char' in}} expected-note {{silence}} } // Test SFINAE checks. diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp index 4bcf113d71429..d4d8198d4fc83 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp @@ -9,16 +9,16 @@ void std_example() { const int y = 999; const int z = 99; char c1 = x; // OK, though it might narrow (in this case, it does narrow) - char c2{x}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - char c3{y}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + char c2{x}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + char c3{y}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}} char c4{z}; // OK: no narrowing needed unsigned char uc1 = {5}; // OK: no narrowing needed - unsigned char uc2 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - unsigned int ui1 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + unsigned char uc2 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + unsigned int ui1 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} signed int si1 = - { (unsigned int)-1 }; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - int ii = {2.0}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - float f1 { x }; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + { (unsigned int)-1 }; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + int ii = {2.0}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + float f1 { x }; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} float f2 { 7 }; // OK: 7 can be exactly represented as a float int f(int); int a[] = @@ -45,19 +45,19 @@ template<typename T> Convert<T> ConvertVar(); // * from a floating-point type to an integer type, or void float_to_int() { - Agg<char> a1 = {1.0F}; // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} - Agg<char> a2 = {1.0}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - Agg<char> a3 = {1.0L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<char> a1 = {1.0F}; // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{silence}} + Agg<char> a2 = {1.0}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + Agg<char> a3 = {1.0L}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} float f = 1.0; double d = 1.0; long double ld = 1.0; - Agg<char> a4 = {f}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - Agg<char> a5 = {d}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - Agg<char> a6 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<char> a4 = {f}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + Agg<char> a5 = {d}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + Agg<char> a6 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} - Agg<char> ce1 = { Convert<float>(1.0) }; // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} - Agg<char> ce2 = { ConvertVar<double>() }; // expected-warning {{type 'double' cannot be narrowed to 'char'}} expected-note {{override}} + Agg<char> ce1 = { Convert<float>(1.0) }; // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{silence}} + Agg<char> ce2 = { ConvertVar<double>() }; // expected-warning {{type 'double' cannot be narrowed to 'char'}} expected-note {{silence}} } // * from long double to double or float, or from double to float, except where @@ -73,8 +73,8 @@ void shrink_float() { // Variables. Agg<float> f1 = {f}; // OK (no-op) - Agg<float> f2 = {d}; // expected-warning {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{override}} - Agg<float> f3 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<float> f2 = {d}; // expected-warning {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{silence}} + Agg<float> f3 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} // Exact constants. Agg<float> f4 = {1.0}; // OK (double constant represented exactly) Agg<float> f5 = {1.0L}; // OK (long double constant represented exactly) @@ -82,8 +82,8 @@ void shrink_float() { Agg<float> f6 = {0.1}; // OK (double constant in range but rounded) Agg<float> f7 = {0.1L}; // OK (long double constant in range but rounded) // Out of range constants. - Agg<float> f8 = {1E50}; // expected-warning {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{override}} - Agg<float> f9 = {1E50L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<float> f8 = {1E50}; // expected-warning {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{silence}} + Agg<float> f9 = {1E50L}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} // More complex constant expression. constexpr long double e40 = 1E40L, e30 = 1E30L, e39 = 1E39L; Agg<float> f10 = {e40 - 5 * e39 + e30 - 5 * e39}; // OK @@ -91,19 +91,19 @@ void shrink_float() { // Variables. Agg<double> d1 = {f}; // OK (widening) Agg<double> d2 = {d}; // OK (no-op) - Agg<double> d3 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<double> d3 = {ld}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} // Exact constant. Agg<double> d4 = {1.0L}; // OK (long double constant represented exactly) // Inexact but in-range constant. Agg<double> d5 = {0.1L}; // OK (long double constant in range but rounded) // Out of range constant. - Agg<double> d6 = {1E315L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<double> d6 = {1E315L}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} // More complex constant expression. constexpr long double e315 = 1E315L, e305 = 1E305L, e314 = 1E314L; Agg<double> d7 = {e315 - 5 * e314 + e305 - 5 * e314}; // OK - Agg<float> ce1 = { Convert<double>(1e300) }; // expected-warning {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{override}} - Agg<double> ce2 = { ConvertVar<long double>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{override}} + Agg<float> ce1 = { Convert<double>(1e300) }; // expected-warning {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{silence}} + Agg<double> ce2 = { ConvertVar<long double>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{silence}} } // * from an integer type or unscoped enumeration type to a floating-point type, @@ -115,16 +115,16 @@ void int_to_float() { char c = 1; // Variables. Yes, even though all char's will fit into any floating type. - Agg<float> f1 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - Agg<double> f2 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - Agg<long double> f3 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<float> f1 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + Agg<double> f2 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + Agg<long double> f3 = {c}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} // Constants. Agg<float> f4 = {12345678}; // OK (exactly fits in a float) - Agg<float> f5 = {123456789}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<float> f5 = {123456789}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} - Agg<float> ce1 = { Convert<int>(123456789) }; // expected-warning {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{override}} - Agg<double> ce2 = { ConvertVar<long long>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{override}} + Agg<float> ce1 = { Convert<int>(123456789) }; // expected-warning {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{silence}} + Agg<double> ce2 = { ConvertVar<long long>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{silence}} } // * from an integer type or unscoped enumeration type to an integer type that @@ -136,38 +136,39 @@ void shrink_int() { // Not a constant expression. short s = 1; unsigned short us = 1; - Agg<char> c1 = {s}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - Agg<unsigned short> s1 = {s}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - Agg<short> s2 = {us}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<char> c1 = {s}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + Agg<unsigned short> s1 = {s}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + Agg<short> s2 = {us}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} // "that cannot represent all the values of the original type" means that the // validity of the program depends on the relative sizes of integral types. // This test compiles with -m64, so sizeof(int)<sizeof(long)==sizeof(long // long). long l1 = 1; - Agg<int> i1 = {l1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<int> i1 = {l1}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} long long ll = 1; Agg<long> l2 = {ll}; // OK // Constants. Agg<char> c2 = {127}; // OK - Agg<char> c3 = {300}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + Agg<char> c3 = {300}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}} Agg<int> i2 = {0x7FFFFFFFU}; // OK - Agg<int> i3 = {0x80000000U}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - Agg<unsigned int> i4 = {-0x80000000L}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<int> i3 = {0x80000000U}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + Agg<unsigned int> i4 = {-0x80000000L}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} // Bool is also an integer type, but conversions to it are a different AST // node. Agg<bool> b1 = {0}; // OK Agg<bool> b2 = {1}; // OK - Agg<bool> b3 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} + Agg<bool> b3 = {-1}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} // Conversions from pointers to booleans aren't narrowing conversions. - Agg<bool> b = {&b1}; // OK + Agg<bool>* ptr = &b1; + Agg<bool> b = {ptr}; // OK - Agg<short> ce1 = { Convert<int>(100000) }; // expected-warning {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}} - Agg<char> ce2 = { ConvertVar<short>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}} + Agg<short> ce1 = { Convert<int>(100000) }; // expected-warning {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{silence}} expected-warning {{changes value from 100000 to -31072}} + Agg<char> ce2 = { ConvertVar<short>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{silence}} } // Be sure that type- and value-dependent expressions in templates get the warning @@ -175,9 +176,9 @@ void shrink_int() { template<int I, typename T> void maybe_shrink_int(T t) { - Agg<short> s1 = {t}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} - Agg<short> s2 = {I}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} - Agg<T> t2 = {700}; // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}} + Agg<short> s1 = {t}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} + Agg<short> s2 = {I}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}} + Agg<T> t2 = {700}; // expected-warning {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}} } void test_template() { @@ -190,9 +191,9 @@ void test_template() { void test_qualifiers(int i) { const int j = i; - struct {const unsigned char c;} c1 = {j}; // expected-warning {{from type 'int' to 'unsigned char' in}} expected-note {{override}} + struct {const unsigned char c;} c1 = {j}; // expected-warning {{from type 'int' to 'unsigned char' in}} expected-note {{silence}} // Template arguments make it harder to avoid printing qualifiers: - Agg<const unsigned char> c2 = {j}; // expected-warning {{from type 'int' to 'const unsigned char' in}} expected-note {{override}} + Agg<const unsigned char> c2 = {j}; // expected-warning {{from type 'int' to 'const unsigned char' in}} expected-note {{silence}} } // Make sure we still get the right SFINAE behavior. diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp index 2ec1454100b69..cec747e1d6054 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp @@ -22,13 +22,13 @@ typedef func_type_rvalue &func_type_rvalue_ref; // expected-error{{reference to template<typename T = func_type_lvalue> struct wrap { typedef T val; - typedef T *ptr; - typedef T &ref; + typedef T *ptr; // expected-error-re 2{{pointer to function type '{{.*}}' cannot have '{{&|&&}}' qualifier}} + typedef T &ref; // expected-error-re 2{{reference to function type '{{.*}}' cannot have '{{&|&&}}' qualifier}} }; -using func_type_lvalue = wrap<>::val; +using func_type_lvalue = wrap<>::val; // expected-note{{in instantiation of}} using func_type_lvalue = wrap<func_type_lvalue>::val; -using func_type_rvalue = wrap<func_type_rvalue>::val; +using func_type_rvalue = wrap<func_type_rvalue>::val; // expected-note{{in instantiation of}} using func_type_lvalue_ptr = wrap<>::ptr; using func_type_lvalue_ptr = wrap<func_type_lvalue>::ptr; @@ -51,3 +51,10 @@ void (X::*mpf2)() && = &X::f1; void (f() &&); // expected-error{{non-member function cannot have '&&' qualifier}} + +// FIXME: These are ill-formed. +template<typename T> struct pass { + void f(T); +}; +pass<func_type_lvalue> pass0; +pass<func_type_lvalue> pass1; diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp index e2d94fbf3811a..a035086c9a127 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp @@ -18,3 +18,16 @@ struct Y { friend void X::f() const; friend void ::f() const; // expected-error {{non-member function cannot have 'const' qualifier}} }; + +template<typename T> struct S { + typedef T F; + typedef T *P; // expected-error {{pointer to function type 'void () const' cannot have 'const' qualifier}} + typedef T &R; // expected-error {{reference to function type 'void () const' cannot have 'const' qualifier}} +}; +S<F> s; // expected-note {{in instantiation of}} + +// FIXME: This is ill-formed. +template<typename T> struct U { + void f(T); +}; +U<F> u; diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp index ec1ccbf5de5fd..0454412229fad 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp @@ -1,8 +1,8 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s struct A { }; -A::A (enum { e1 }) {} // expected-error{{can not be defined in a parameter}} -void A::f(enum { e2 }) {} // expected-error{{can not be defined in a parameter}} +A::A (enum { e1 }) {} // expected-error{{cannot be defined in a parameter}} +void A::f(enum { e2 }) {} // expected-error{{cannot be defined in a parameter}} -enum { e3 } A::g() { } // expected-error{{can not be defined in the result type}} \ +enum { e3 } A::g() { } // expected-error{{cannot be defined in the result type}} \ // expected-error{{out-of-line definition}} diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp index 7e35788d898be..e159ab729d5f1 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp @@ -17,7 +17,7 @@ void f() { A a(b); int A::*ip = &A::s; // expected-error {{cannot initialize a variable of type 'int A::*' with an rvalue of type 'int *'}} - a.*&A::s = 10; // expected-error{{right hand operand to .* has non pointer-to-member type 'int *'}} + a.*&A::s = 10; // expected-error{{right hand operand to .* has non-pointer-to-member type 'int *'}} a.*&A::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}} ft(a); // expected-note{{in instantiation of function template specialization 'ft<A>' requested here}} diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp index cd623df71e81b..0f76e1f3c79b7 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// expected-no-diagnostics template<typename T, typename U> struct is_same { @@ -20,8 +19,8 @@ typedef int& LRI; typedef int&& RRI; typedef LRI& r1; CHECK_EQUAL_TYPES(r1, int&); -typedef const LRI& r2; CHECK_EQUAL_TYPES(r2, int&); -typedef const LRI&& r3; CHECK_EQUAL_TYPES(r3, int&); +typedef const LRI& r2; CHECK_EQUAL_TYPES(r2, int&); // expected-warning {{'const' qualifier on reference type 'LRI' (aka 'int &') has no effect}} +typedef const LRI&& r3; CHECK_EQUAL_TYPES(r3, int&); // expected-warning {{'const' qualifier on reference type 'LRI' (aka 'int &') has no effect}} typedef RRI& r4; CHECK_EQUAL_TYPES(r4, int&); typedef RRI&& r5; CHECK_EQUAL_TYPES(r5, int&&); diff --git a/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp b/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp index 99334b845aba2..1d04d7d2a7005 100644 --- a/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp @@ -22,3 +22,83 @@ int decltype(tfoo<T>())::i; // expected-error{{nested name specifier 'decltype(t template<typename T> void decltype(tfoo<T>())::func() { // expected-error{{nested name specifier 'decltype(tfoo<T>())::' for declaration does not refer into a class, class template or class template partial specialization}} } + +// An init-declarator named with a qualified-id can refer to an element of the +// inline namespace set of the named namespace. +namespace inline_namespaces { + namespace N { + inline namespace M { + void f(); // expected-note {{possible target}} + void g(); + extern int m; // expected-note {{candidate}} + extern int n; + struct S; // expected-note {{candidate}} + struct T; + enum E : int; // expected-note {{candidate}} + enum F : int; + template<typename T> void ft(); // expected-note {{here}} + template<typename T> void gt(); // expected-note {{here}} + template<typename T> extern int mt; // expected-note {{here}} expected-warning {{extension}} + template<typename T> extern int nt; // expected-note {{here}} expected-warning {{extension}} + template<typename T> struct U; // expected-note {{here}} + template<typename T> struct V; // expected-note {{here}} + } + + // When named by unqualified-id, we do *not* look in the inline namespace + // set. + void f() {} // expected-note {{possible target}} + int m; // expected-note {{candidate}} + struct S {}; // expected-note {{candidate}} + enum E : int {}; // expected-note {{candidate}} + + static_assert(&f != &M::f, ""); // expected-error {{reference to overloaded function could not be resolved}} + static_assert(&m != &M::m, ""); // expected-error {{ambiguous}} + typedef S X; // expected-error {{ambiguous}} + typedef E Y; // expected-error {{ambiguous}} + + // When named by (unqualified) template-id, we do look in the inline + // namespace set. See [namespace.def]p8, [temp.explicit]p3, + // [temp.expl.spec]p2. + // + // This is not explicitly specified for partial specializations, but + // that is just a language defect. + template<> void ft<int>() {} + template void ft<char>(); // expected-error {{undefined}} + + template<typename T> int mt<T*>; + template<> int mt<int>; + template int mt<int*>; + template int mt<char>; // expected-error {{undefined}} + + template<typename T> struct U<T*> {}; + template<> struct U<int> {}; + template struct U<int*>; + template struct U<char>; // expected-error {{undefined}} + } + + // When named by qualified-id, we *do* look in the inline namespace set. + void N::g() {} + int N::n; + struct N::T {}; + enum N::F : int {}; + + static_assert(&N::g == &N::M::g, ""); + static_assert(&N::n == &N::M::n, ""); + typedef N::T X; + typedef N::M::T X; + typedef N::F Y; + typedef N::M::F Y; + + template<> void N::gt<int>() {} + template void N::gt<char>(); // expected-error {{undefined}} + + template<typename T> int N::nt<T*>; + template<> int N::nt<int>; + template int N::nt<int*>; + template int N::nt<char>; // expected-error {{undefined}} + + template<typename T> struct N::V<T*> {}; + template<> struct N::V<int> {}; + template struct N::V<int*>; + template struct N::V<char>; // expected-error {{undefined}} +} diff --git a/test/CXX/dcl.decl/dcl.meaning/p1.cpp b/test/CXX/dcl.decl/dcl.meaning/p1.cpp index ec9a2611872ca..5747380f2806d 100644 --- a/test/CXX/dcl.decl/dcl.meaning/p1.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/p1.cpp @@ -29,9 +29,17 @@ namespace NS { template<typename T> void wibble(T); } namespace NS { - void NS::foo() {} // expected-error{{extra qualification on member 'foo'}} - int NS::bar; // expected-error{{extra qualification on member 'bar'}} - struct NS::X { }; // expected-error{{extra qualification on member 'X'}} - template<typename T> struct NS::Y; // expected-error{{extra qualification on member 'Y'}} - template<typename T> void NS::wibble(T) { } // expected-error{{extra qualification on member 'wibble'}} + // Under DR482, these are all valid, except for forward-declaring a struct + // with a nested-name-specifier. + void NS::foo(); // expected-warning {{extra qualification}} + extern int NS::bar; // expected-warning {{extra qualification}} + struct NS::X; // expected-error {{forward declaration of struct cannot have a nested name specifier}} expected-warning {{extra qualification}} + template<typename T> struct NS::Y; // expected-error {{forward declaration of struct cannot have a nested name specifier}} expected-warning {{extra qualification}} + template<typename T> void NS::wibble(T); // expected-warning {{extra qualification}} + + void NS::foo() {} // expected-warning{{extra qualification on member 'foo'}} + int NS::bar; // expected-warning{{extra qualification on member 'bar'}} + struct NS::X { }; // expected-warning{{extra qualification on member 'X'}} + template<typename T> struct NS::Y { }; // expected-warning{{extra qualification on member 'Y'}} + template<typename T> void NS::wibble(T) { } // expected-warning{{extra qualification on member 'wibble'}} } diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp index 265a52d9261aa..29e1720b1bbf0 100644 --- a/test/CXX/drs/dr0xx.cpp +++ b/test/CXX/drs/dr0xx.cpp @@ -4,7 +4,7 @@ namespace dr1 { // dr1: no namespace X { extern "C" void dr1_f(int a = 1); } - namespace Y { extern "C" void dr1_f(int a = 2); } + namespace Y { extern "C" void dr1_f(int a = 1); } using X::dr1_f; using Y::dr1_f; void g() { dr1_f(0); @@ -25,7 +25,23 @@ namespace dr1 { // dr1: no } void X::z(int = 1) {} // expected-note {{previous}} namespace X { - void z(int = 2); // expected-error {{redefinition of default argument}} + void z(int = 1); // expected-error {{redefinition of default argument}} + } + + void i(int = 1); + void j() { + void i(int = 1); + using dr1::i; + i(0); + // FIXME: This should be rejected, due to the ambiguous default argument. + i(); + } + void k() { + using dr1::i; + void i(int = 1); + i(0); + // FIXME: This should be rejected, due to the ambiguous default argument. + i(); } } @@ -141,6 +157,21 @@ namespace dr12 { // dr12: sup 239 } } +namespace dr13 { // dr13: no + extern "C" void f(int); + void g(char); + + template<typename T> struct A { + A(void (*fp)(T)); + }; + template<typename T> int h(void (T)); + + A<int> a1(f); // FIXME: We should reject this. + A<char> a2(g); + int a3 = h(f); // FIXME: We should reject this. + int a4 = h(g); +} + namespace dr14 { // dr14: yes namespace X { extern "C" int dr14_f(); } namespace Y { extern "C" int dr14_f(); } @@ -194,10 +225,7 @@ namespace dr17 { // dr17: yes }; } -namespace dr18 { // dr18: yes - typedef void Void; - void f(Void); // expected-error {{empty parameter list defined with a typedef of 'void'}} -} +// dr18: sup 577 namespace dr19 { // dr19: yes struct A { @@ -464,23 +492,15 @@ namespace dr46 { // dr46: yes template template struct A<int>::B<int>; // expected-error {{expected unqualified-id}} } -namespace dr47 { // dr47: no +namespace dr47 { // dr47: sup 329 template<typename T> struct A { - friend void f() { T t; } + friend void f() { T t; } // expected-error {{redefinition}} expected-note {{previous}} }; A<int> a; - A<float> b; -#if __cplusplus < 201103L - // expected-error@-5 {{redefinition}} expected-note@-5 {{previous}} - // expected-note@-3 {{instantiation of}} -#else + A<float> b; // expected-note {{instantiation of}} + void f(); - // FIXME: We should produce some kind of error here. C++11 [temp.friend]p4 - // says we instantiate 'f' when it's odr-used, but that doesn't imply that - // this is valid; we still have multiple definitions of 'f' even if we never - // instantiate any of them. void g() { f(); } -#endif } namespace dr48 { // dr48: yes @@ -919,11 +939,10 @@ namespace dr87 { // dr87: no namespace dr88 { // dr88: yes template<typename T> struct S { - static const int a = 1; + static const int a = 1; // expected-note {{previous}} static const int b; }; - // FIXME: This diagnostic is pretty bad. - template<> const int S<int>::a = 4; // expected-error {{redefinition}} expected-note {{previous}} + template<> const int S<int>::a = 4; // expected-error {{already has an initializer}} template<> const int S<int>::b = 4; } @@ -963,6 +982,22 @@ namespace dr91 { // dr91: yes int k = f(U()); } +namespace dr92 { // dr92: yes + void f() throw(int, float); + void (*p)() throw(int) = &f; // expected-error {{target exception specification is not superset of source}} + void (*q)() throw(int); + void (**pp)() throw() = &q; // expected-error {{exception specifications are not allowed}} + + void g(void() throw()); + void h() { + g(f); // expected-error {{is not superset}} + g(q); // expected-error {{is not superset}} + } + + template<void() throw()> struct X {}; + X<&f> xp; // ok +} + // dr93: na namespace dr94 { // dr94: yes diff --git a/test/CXX/drs/dr10xx.cpp b/test/CXX/drs/dr10xx.cpp new file mode 100644 index 0000000000000..64c71b2b0f92f --- /dev/null +++ b/test/CXX/drs/dr10xx.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +// expected-no-diagnostics + +namespace std { + __extension__ typedef __SIZE_TYPE__ size_t; + + template<typename T> struct initializer_list { + const T *p; size_t n; + initializer_list(const T *p, size_t n); + }; +} + +namespace dr1070 { // dr1070: 3.5 +#if __cplusplus >= 201103L + struct A { + A(std::initializer_list<int>); + }; + struct B { + int i; + A a; + }; + B b = {1}; + struct C { + std::initializer_list<int> a; + B b; + std::initializer_list<double> c; + }; + C c = {}; +#endif +} diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp new file mode 100644 index 0000000000000..5827291142dc6 --- /dev/null +++ b/test/CXX/drs/dr13xx.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +namespace dr1346 { // dr1346: 3.5 + auto a(1); // expected-error 0-1{{extension}} + auto b(1, 2); // expected-error {{multiple expressions}} expected-error 0-1{{extension}} +#if __cplusplus >= 201103L + auto c({}); // expected-error {{parenthesized initializer list}} expected-error {{cannot deduce}} + auto d({1}); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}} + auto e({1, 2}); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}} +#endif + template<typename...Ts> void f(Ts ...ts) { // expected-error 0-1{{extension}} + auto x(ts...); // expected-error {{empty}} expected-error 0-1{{extension}} + } + template void f(); // expected-note {{instantiation}} + +#if __cplusplus >= 201103L + void init_capture() { + [a(1)] {} (); // expected-error 0-1{{extension}} + [b(1, 2)] {} (); // expected-error {{multiple expressions}} expected-error 0-1{{extension}} +#if __cplusplus >= 201103L + [c({})] {} (); // expected-error {{parenthesized initializer list}} expected-error {{cannot deduce}} expected-error 0-1{{extension}} + [d({1})] {} (); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}} expected-error 0-1{{extension}} + [e({1, 2})] {} (); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}} expected-error 0-1{{extension}} +#endif + } +#endif +} diff --git a/test/CXX/drs/dr14xx.cpp b/test/CXX/drs/dr14xx.cpp new file mode 100644 index 0000000000000..8de1b8d623a92 --- /dev/null +++ b/test/CXX/drs/dr14xx.cpp @@ -0,0 +1,196 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +#if __cplusplus < 201103L +// expected-no-diagnostics +#endif + +namespace dr1460 { // dr1460: 3.5 +#if __cplusplus >= 201103L + namespace DRExample { + union A { + union {}; + union {}; + constexpr A() {} + }; + constexpr A a = A(); + + union B { + union {}; + union {}; + constexpr B() = default; + }; + constexpr B b = B(); + + union C { + union {}; + union {}; + }; + constexpr C c = C(); +#if __cplusplus > 201103L + constexpr void f() { C c; } + static_assert((f(), true), ""); +#endif + } + + union A {}; + union B { int n; }; // expected-note +{{here}} + union C { int n = 0; }; + struct D { union {}; }; + struct E { union { int n; }; }; // expected-note +{{here}} + struct F { union { int n = 0; }; }; + + struct X { + friend constexpr A::A() noexcept; + friend constexpr B::B() noexcept; // expected-error {{follows non-constexpr declaration}} + friend constexpr C::C() noexcept; + friend constexpr D::D() noexcept; + friend constexpr E::E() noexcept; // expected-error {{follows non-constexpr declaration}} + friend constexpr F::F() noexcept; + }; + + // These are OK, because value-initialization doesn't actually invoke the + // constructor. + constexpr A a = A(); + constexpr B b = B(); + constexpr C c = C(); + constexpr D d = D(); + constexpr E e = E(); + constexpr F f = F(); + + namespace Defaulted { + union A { constexpr A() = default; }; + union B { int n; constexpr B() = default; }; // expected-error {{not constexpr}} + union C { int n = 0; constexpr C() = default; }; + struct D { union {}; constexpr D() = default; }; + struct E { union { int n; }; constexpr E() = default; }; // expected-error {{not constexpr}} + struct F { union { int n = 0; }; constexpr F() = default; }; + + struct G { union { int n = 0; }; union { int m; }; constexpr G() = default; }; // expected-error {{not constexpr}} + struct H { + union { + int n = 0; + }; + union { // expected-note 2{{member not initialized}} + int m; + }; + constexpr H() {} // expected-error {{must initialize all members}} + constexpr H(bool) : m(1) {} + constexpr H(char) : n(1) {} // expected-error {{must initialize all members}} + constexpr H(double) : m(1), n(1) {} + }; + } + +#if __cplusplus > 201103L + template<typename T> constexpr bool check() { + T t; // expected-note-re 2{{non-constexpr constructor '{{[BE]}}'}} + return true; + } + static_assert(check<A>(), ""); + static_assert(check<B>(), ""); // expected-error {{constant}} expected-note {{in call}} + static_assert(check<C>(), ""); + static_assert(check<D>(), ""); + static_assert(check<E>(), ""); // expected-error {{constant}} expected-note {{in call}} + static_assert(check<F>(), ""); +#endif + + union G { + int a = 0; // expected-note {{previous initialization is here}} + int b = 0; // expected-error {{initializing multiple members of union}} + }; + union H { + union { + int a = 0; // expected-note {{previous initialization is here}} + }; + union { + int b = 0; // expected-error {{initializing multiple members of union}} + }; + }; + struct I { + union { + int a = 0; // expected-note {{previous initialization is here}} + int b = 0; // expected-error {{initializing multiple members of union}} + }; + }; + struct J { + union { int a = 0; }; + union { int b = 0; }; + }; + + namespace Overriding { + struct A { + int a = 1, b, c = 3; + constexpr A() : b(2) {} + }; + static_assert(A().a == 1 && A().b == 2 && A().c == 3, ""); + + union B { + int a, b = 2, c; + constexpr B() : a(1) {} + constexpr B(char) : b(4) {} + constexpr B(int) : c(3) {} + constexpr B(const char*) {} + }; + static_assert(B().a == 1, ""); + static_assert(B().b == 2, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(B('x').a == 0, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(B('x').b == 4, ""); + static_assert(B(123).b == 2, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(B(123).c == 3, ""); + static_assert(B("").a == 1, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(B("").b == 2, ""); + static_assert(B("").c == 3, ""); // expected-error {{constant}} expected-note {{read of}} + + struct C { + union { int a, b = 2, c; }; + union { int d, e = 5, f; }; + constexpr C() : a(1) {} + constexpr C(char) : c(3) {} + constexpr C(int) : d(4) {} + constexpr C(float) : f(6) {} + constexpr C(const char*) {} + }; + + static_assert(C().a == 1, ""); + static_assert(C().b == 2, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(C().d == 4, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(C().e == 5, ""); + + static_assert(C('x').b == 2, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(C('x').c == 3, ""); + static_assert(C('x').d == 4, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(C('x').e == 5, ""); + + static_assert(C(1).b == 2, ""); + static_assert(C(1).c == 3, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(C(1).d == 4, ""); + static_assert(C(1).e == 5, ""); // expected-error {{constant}} expected-note {{read of}} + + static_assert(C(1.f).b == 2, ""); + static_assert(C(1.f).c == 3, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(C(1.f).e == 5, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(C(1.f).f == 6, ""); + + static_assert(C("").a == 1, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(C("").b == 2, ""); + static_assert(C("").c == 3, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(C("").d == 4, ""); // expected-error {{constant}} expected-note {{read of}} + static_assert(C("").e == 5, ""); + static_assert(C("").f == 6, ""); // expected-error {{constant}} expected-note {{read of}} + + struct D; + extern const D d; + struct D { + int a; + union { + int b = const_cast<D&>(d).a = 1; // not evaluated + int c; + }; + constexpr D() : a(0), c(0) {} + }; + constexpr D d {}; + static_assert(d.a == 0, ""); + } +#endif +} diff --git a/test/CXX/drs/dr15xx.cpp b/test/CXX/drs/dr15xx.cpp new file mode 100644 index 0000000000000..66618c1716d62 --- /dev/null +++ b/test/CXX/drs/dr15xx.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1y -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +// expected-no-diagnostics + +namespace DR1550 { // dr1550: yes + int f(bool b, int n) { + return (b ? (throw 0) : n) + (b ? n : (throw 0)); + } +} + +namespace DR1560 { // dr1560: 3.5 + void f(bool b, int n) { + (b ? throw 0 : n) = (b ? n : throw 0) = 0; + } + class X { X(const X&); }; + const X &get(); + const X &x = true ? get() : throw 0; +} diff --git a/test/CXX/drs/dr1xx.cpp b/test/CXX/drs/dr1xx.cpp index 7045148034fbf..6aff43c6a4885 100644 --- a/test/CXX/drs/dr1xx.cpp +++ b/test/CXX/drs/dr1xx.cpp @@ -9,7 +9,7 @@ namespace dr100 { // dr100: yes B<"bar"> b; // expected-error {{does not refer to any declaration}} } -namespace dr101 { // dr101: yes +namespace dr101 { // dr101: 3.5 extern "C" void dr101_f(); typedef unsigned size_t; namespace X { @@ -18,6 +18,8 @@ namespace dr101 { // dr101: yes } using X::dr101_f; using X::size_t; + extern "C" void dr101_f(); + typedef unsigned size_t; } namespace dr102 { // dr102: yes @@ -38,13 +40,13 @@ namespace dr102 { // dr102: yes namespace dr106 { // dr106: sup 540 typedef int &r1; typedef r1 &r1; - typedef const r1 r1; - typedef const r1 &r1; + typedef const r1 r1; // expected-warning {{has no effect}} + typedef const r1 &r1; // expected-warning {{has no effect}} typedef const int &r2; typedef r2 &r2; - typedef const r2 r2; - typedef const r2 &r2; + typedef const r2 r2; // expected-warning {{has no effect}} + typedef const r2 &r2; // expected-warning {{has no effect}} } namespace dr107 { // dr107: yes @@ -64,7 +66,7 @@ namespace dr108 { // dr108: yes namespace dr109 { // dr109: yes struct A { template<typename T> void f(T); }; template<typename T> struct B : T { - using T::template f; // expected-error {{using declaration can not refer to a template}} + using T::template f; // expected-error {{using declaration cannot refer to a template}} void g() { this->f<int>(123); } // expected-error {{use 'template'}} }; } @@ -592,11 +594,12 @@ namespace dr155 { // dr155: dup 632 struct S { int n; } s = { { 1 } }; // expected-warning {{braces around scalar initializer}} } -namespace dr159 { // dr159: no +// dr158 FIXME write codegen test + +namespace dr159 { // dr159: 3.5 namespace X { void f(); } void f(); - // FIXME: This should be accepted. - void dr159::f() {} // expected-error {{extra qualification}} + void dr159::f() {} // expected-warning {{extra qualification}} void dr159::X::f() {} } @@ -719,9 +722,9 @@ namespace dr169 { // dr169: yes }; struct D : A<int>, B { using A<int>::n; - using B::C<int>; // expected-error {{using declaration can not refer to a template specialization}} - using B::f<int>; // expected-error {{using declaration can not refer to a template specialization}} - using B::n<int>; // expected-error {{using declaration can not refer to a template specialization}} + using B::C<int>; // expected-error {{using declaration cannot refer to a template specialization}} + using B::f<int>; // expected-error {{using declaration cannot refer to a template specialization}} + using B::n<int>; // expected-error {{using declaration cannot refer to a template specialization}} }; } diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp index 2c32a9e503f93..bb9af9fd9337e 100644 --- a/test/CXX/drs/dr2xx.cpp +++ b/test/CXX/drs/dr2xx.cpp @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // PR13819 -- __SIZE_TYPE__ is incompatible. -// REQUIRES: LP64 +typedef __SIZE_TYPE__ size_t; // expected-error 0-1 {{extension}} #if __cplusplus < 201103L #define fold(x) (__builtin_constant_p(x) ? (x) : (x)) @@ -216,8 +216,22 @@ namespace dr221 { // dr221: yes } } -// dr222 is a mystery -- it lists no changes to the standard, and yet was -// apparently both voted into the WP and acted upon by the editor. +namespace dr222 { // dr222: dup 637 + void f(int a, int b, int c, int *x) { +#pragma clang diagnostic push +#pragma clang diagnostic warning "-Wunsequenced" + void((a += b) += c); + void((a += b) + (a += c)); // expected-warning {{multiple unsequenced modifications to 'a'}} + + x[a++] = a; // expected-warning {{unsequenced modification and access to 'a'}} + + a = b = 0; // ok, read and write of 'b' are sequenced + + a = (b = a++); // expected-warning {{multiple unsequenced modifications to 'a'}} + a = (b = ++a); +#pragma clang diagnostic pop + } +} // dr223: na @@ -363,6 +377,13 @@ namespace dr229 { // dr229: yes template<> void f<int>() {} } +namespace dr230 { // dr230: yes + struct S { + S() { f(); } // expected-warning {{call to pure virtual member function}} + virtual void f() = 0; // expected-note {{declared here}} + }; +} + namespace dr231 { // dr231: yes namespace outer { namespace inner { @@ -445,7 +466,7 @@ namespace dr243 { // dr243: yes A a2 = b; // expected-error {{ambiguous}} } -namespace dr244 { // dr244: no +namespace dr244 { // dr244: 3.5 struct B {}; struct D : B {}; // expected-note {{here}} D D_object; @@ -459,7 +480,7 @@ namespace dr244 { // dr244: no B_ptr->~B_alias(); B_ptr->B_alias::~B(); // This is valid under DR244. - B_ptr->B_alias::~B_alias(); // FIXME: expected-error {{expected the class name after '~' to name a destructor}} + B_ptr->B_alias::~B_alias(); B_ptr->dr244::~B(); // expected-error {{refers to a member in namespace}} B_ptr->dr244::~B_alias(); // expected-error {{refers to a member in namespace}} } @@ -552,21 +573,21 @@ namespace dr252 { // dr252: yes struct E { void operator delete(void*, int); - void operator delete(void*) = delete; // expected-error 0-1{{extension}} expected-note {{here}} - virtual ~E(); + void operator delete(void*) = delete; // expected-error 0-1{{extension}} expected-note 1-2 {{here}} + virtual ~E(); // expected-error 0-1 {{attempt to use a deleted function}} }; - E::~E() {} // expected-error {{deleted}} + E::~E() {} // expected-error {{attempt to use a deleted function}} struct F { // If both functions are available, the first one is a placement delete. - void operator delete(void*, __SIZE_TYPE__); + void operator delete(void*, size_t); void operator delete(void*) = delete; // expected-error 0-1{{extension}} expected-note {{here}} virtual ~F(); }; - F::~F() {} // expected-error {{deleted}} + F::~F() {} // expected-error {{attempt to use a deleted function}} struct G { - void operator delete(void*, __SIZE_TYPE__); + void operator delete(void*, size_t); virtual ~G(); }; G::~G() {} @@ -665,6 +686,8 @@ namespace dr259 { // dr259: yes c++11 #endif } +// FIXME: When dr260 is resolved, also add tests for DR507. + namespace dr261 { // dr261: no #pragma clang diagnostic push #pragma clang diagnostic warning "-Wused-but-marked-unused" @@ -674,7 +697,7 @@ namespace dr261 { // dr261: no // translation unit. // We're also missing the -Wused-but-marked-unused diagnostic here. struct A { - inline void *operator new(__SIZE_TYPE__) __attribute__((unused)); + inline void *operator new(size_t) __attribute__((unused)); inline void operator delete(void*) __attribute__((unused)); A() {} }; @@ -724,3 +747,293 @@ namespace dr263 { // dr263: yes // dr266: na // dr269: na // dr270: na + +namespace dr272 { // dr272: yes + struct X { + void f() { + this->~X(); + X::~X(); + ~X(); // expected-error {{unary expression}} + } + }; +} + +#include <stdarg.h> +#include <stddef.h> +namespace dr273 { // dr273: yes + struct A { + int n; + }; + void operator&(A); + void f(A a, ...) { + offsetof(A, n); + va_list val; + va_start(val, a); + va_end(val); + } +} + +// dr274: na + +namespace dr275 { // dr275: no + namespace N { + template <class T> void f(T) {} // expected-note 1-4{{here}} + template <class T> void g(T) {} // expected-note {{candidate}} + template <> void f(int); + template <> void f(char); + template <> void f(double); + template <> void g(char); + } + + using namespace N; + + namespace M { + template <> void N::f(char) {} // expected-error {{'M' does not enclose namespace 'N'}} + template <class T> void g(T) {} + template <> void g(char) {} + template void f(long); +#if __cplusplus >= 201103L + // FIXME: this should be rejected in c++98 too + // expected-error@-3 {{must occur in namespace 'N'}} +#endif + template void N::f(unsigned long); +#if __cplusplus >= 201103L + // FIXME: this should be rejected in c++98 too + // expected-error@-3 {{not in a namespace enclosing 'N'}} +#endif + template void h(long); // expected-error {{does not refer to a function template}} + template <> void f(double) {} // expected-error {{no function template matches}} + } + + template <class T> void g(T) {} // expected-note {{candidate}} + + template <> void N::f(char) {} + template <> void f(int) {} // expected-error {{no function template matches}} + + template void f(short); +#if __cplusplus >= 201103L + // FIXME: this should be rejected in c++98 too + // expected-error@-3 {{must occur in namespace 'N'}} +#endif + template void N::f(unsigned short); + + // FIXME: this should probably be valid. the wording from the issue + // doesn't clarify this, but it follows from the usual rules. + template void g(int); // expected-error {{ambiguous}} + + // FIXME: likewise, this should also be valid. + template<typename T> void f(T) {} // expected-note {{candidate}} + template void f(short); // expected-error {{ambiguous}} +} + +// dr276: na + +namespace dr277 { // dr277: yes + typedef int *intp; + int *p = intp(); + int a[fold(intp() ? -1 : 1)]; +} + +namespace dr280 { // dr280: yes + typedef void f0(); + typedef void f1(int); + typedef void f2(int, int); + typedef void f3(int, int, int); + struct A { + operator f1*(); // expected-note {{here}} expected-note {{candidate}} + operator f2*(); + }; + struct B { + operator f0*(); // expected-note {{candidate}} + private: + operator f3*(); // expected-note {{here}} expected-note {{candidate}} + }; + struct C { + operator f0*(); // expected-note {{candidate}} + operator f1*(); // expected-note {{candidate}} + operator f2*(); // expected-note {{candidate}} + operator f3*(); // expected-note {{candidate}} + }; + struct D : private A, B { // expected-note 2{{here}} + operator f2*(); // expected-note {{candidate}} + } d; + struct E : C, D {} e; + void g() { + d(); // ok, public + d(0); // expected-error {{private member of 'dr280::A'}} expected-error {{private base class 'dr280::A'}} + d(0, 0); // ok, suppressed by member in D + d(0, 0, 0); // expected-error {{private member of 'dr280::B'}} + e(); // expected-error {{ambiguous}} + e(0); // expected-error {{ambiguous}} + e(0, 0); // expected-error {{ambiguous}} + e(0, 0, 0); // expected-error {{ambiguous}} + } +} + +namespace dr281 { // dr281: no + void a(); + inline void b(); + + void d(); + inline void e(); + + struct S { + friend inline void a(); // FIXME: ill-formed + friend inline void b(); + friend inline void c(); // FIXME: ill-formed + friend inline void d() {} + friend inline void e() {} + friend inline void f() {} + }; +} + +namespace dr283 { // dr283: yes + template<typename T> // expected-note 2{{here}} + struct S { + friend class T; // expected-error {{shadows}} + class T; // expected-error {{shadows}} + }; +} + +namespace dr284 { // dr284: no + namespace A { + struct X; + enum Y {}; + class Z {}; + } + namespace B { + struct W; + using A::X; + using A::Y; + using A::Z; + } + struct B::V {}; // expected-error {{no struct named 'V'}} + struct B::W {}; + struct B::X {}; // FIXME: ill-formed + enum B::Y e; // ok per dr417 + class B::Z z; // ok per dr417 + + struct C { + struct X; + enum Y {}; + class Z {}; + }; + struct D : C { + struct W; + using C::X; + using C::Y; + using C::Z; + }; + struct D::V {}; // expected-error {{no struct named 'V'}} + struct D::W {}; + struct D::X {}; // FIXME: ill-formed + enum D::Y e2; // ok per dr417 + class D::Z z2; // ok per dr417 +} + +namespace dr285 { // dr285: yes + template<typename T> void f(T, int); // expected-note {{match}} + template<typename T> void f(int, T); // expected-note {{match}} + template<> void f<int>(int, int) {} // expected-error {{ambiguous}} +} + +namespace dr286 { // dr286: yes + template<class T> struct A { + class C { + template<class T2> struct B {}; // expected-note {{here}} + }; + }; + + template<class T> + template<class T2> + struct A<T>::C::B<T2*> { }; + + A<short>::C::B<int*> absip; // expected-error {{private}} +} + +// dr288: na + +namespace dr289 { // dr289: yes + struct A; // expected-note {{forward}} + struct B : A {}; // expected-error {{incomplete}} + + template<typename T> struct C { typename T::error error; }; // expected-error {{cannot be used prior to '::'}} + struct D : C<int> {}; // expected-note {{instantiation}} +} + +// dr290: na +// dr291: dup 391 +// dr292 FIXME: write a codegen test + +namespace dr294 { // dr294: no + void f() throw(int); + int main() { + // FIXME: we reject this for the wrong reason, because we don't implement + // dr87 yet. + (void)static_cast<void (*)() throw()>(f); // expected-error {{not superset}} + void (*p)() throw() = f; // expected-error {{not superset}} + + (void)static_cast<void (*)() throw(int)>(f); // FIXME: ill-formed + } +} + +namespace dr295 { // dr295: no + typedef int f(); + // FIXME: This warning is incorrect. + const f g; // expected-warning {{unspecified behavior}} + const f &r = g; // expected-warning {{unspecified behavior}} + template<typename T> struct X { + const T &f; + }; + X<f> x = {g}; // FIXME: expected-error {{drops qualifiers}} +} + +namespace dr296 { // dr296: yes + struct A { + static operator int() { return 0; } // expected-error {{static}} + }; +} + +namespace dr298 { // dr298: yes + struct A { + typedef int type; + A(); + ~A(); + }; + typedef A B; // expected-note {{here}} + typedef const A C; // expected-note {{here}} + + A::type i1; + B::type i2; + C::type i3; + + struct A a; + struct B b; // expected-error {{refers to a typedef}} + struct C c; // expected-error {{refers to a typedef}} + + B::B() {} // expected-error {{requires a type specifier}} + B::A() {} // ok + C::~C() {} // expected-error {{destructor cannot be declared using a typedef 'C' (aka 'const dr298::A') of the class name}} + + typedef struct D E; // expected-note {{here}} + struct E {}; // expected-error {{conflicts with typedef}} + + struct F { + ~F(); + }; + typedef const F G; + G::~F() {} // ok +} + +namespace dr299 { // dr299: yes c++11 + struct S { + operator int(); + }; + struct T { + operator int(); // expected-note {{}} + operator unsigned short(); // expected-note {{}} + }; + // FIXME: should this apply to c++98 mode? + int *p = new int[S()]; // expected-error 0-1{{extension}} + int *q = new int[T()]; // expected-error {{ambiguous}} +} diff --git a/test/CXX/drs/dr3xx.cpp b/test/CXX/drs/dr3xx.cpp new file mode 100644 index 0000000000000..53fc20e23fe69 --- /dev/null +++ b/test/CXX/drs/dr3xx.cpp @@ -0,0 +1,1285 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +namespace dr300 { // dr300: yes + template<typename R, typename A> void f(R (&)(A)) {} + int g(int); + void h() { f(g); } +} + +namespace dr301 { // dr301: yes + // see also dr38 + struct S; + template<typename T> void operator+(T, T); + void operator-(S, S); + + void f() { + bool a = (void(*)(S, S))operator+<S> < + (void(*)(S, S))operator+<S>; + bool b = (void(*)(S, S))operator- < + (void(*)(S, S))operator-; + bool c = (void(*)(S, S))operator+ < + (void(*)(S, S))operator-; // expected-error {{expected '>'}} + } + + template<typename T> void f() { + typename T::template operator+<int> a; // expected-error {{typename specifier refers to a non-type template}} expected-error +{{}} + // FIXME: This shouldn't say (null). + class T::template operator+<int> b; // expected-error {{identifier followed by '<' indicates a class template specialization but (null) refers to a function template}} + enum T::template operator+<int> c; // expected-error {{expected identifier}} expected-error {{does not declare anything}} + enum T::template operator+<int>::E d; // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}} expected-error {{forward reference}} + enum T::template X<int>::E e; + T::template operator+<int>::foobar(); // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}} + T::template operator+<int>(0); // ok + } + + template<typename T> class operator&<T*> {}; // expected-error +{{}} + template<typename T> class T::operator& {}; // expected-error +{{}} + template<typename T> class S::operator&<T*> {}; // expected-error +{{}} +} + +namespace dr302 { // dr302: yes + struct A { A(); ~A(); }; +#if __cplusplus < 201103L + struct B { // expected-error {{implicit default constructor for 'dr302::B' must explicitly initialize the const member 'n'}} + const int n; // expected-note {{declared here}} + A a; + } b = B(); // expected-note {{first required here}} + // Trivial default constructor C::C() is not called here. + struct C { + const int n; + } c = C(); +#else + struct B { + const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}} + A a; + } b = B(); // expected-error {{call to implicitly-deleted default constructor}} + // C::C() is called here, because even though it's trivial, it's deleted. + struct C { + const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}} + } c = C(); // expected-error {{call to implicitly-deleted default constructor}} + struct D { + const int n = 0; + } d = D(); +#endif +} + +// dr303: na + +namespace dr304 { // dr304: yes + typedef int &a; + int n = a(); // expected-error {{requires an initializer}} + + struct S { int &b; }; + int m = S().b; +#if __cplusplus < 201103L + // expected-error@-3 {{requires an initializer}} + // expected-note@-3 {{in value-initialization}} +#else + // expected-error@-5 {{deleted}} + // expected-note@-7 {{reference}} +#endif +} + +namespace dr305 { // dr305: no + struct A { + typedef A C; + }; + void f(A *a) { + struct A {}; + a->~A(); + a->~C(); + } + typedef A B; + void g(B *b) { + b->~B(); + b->~C(); + } + void h(B *b) { + struct B {}; // expected-note {{declared here}} + b->~B(); // expected-error {{does not match}} + } + + template<typename T> struct X {}; + void i(X<int>* x) { + struct X {}; + x->~X<int>(); + x->~X(); + x->~X<char>(); // expected-error {{no member named}} + } + + // FIXME: This appears to be valid (but allowing the nested types might be a + // defect). + template<typename> struct Nested { + template<typename> struct Nested {}; + }; + void testNested(Nested<int> n) { n.~Nested<int>(); } // expected-error {{no member named}} +#if __cplusplus < 201103L + // expected-error@-2 {{ambiguous}} + // expected-note@-6 {{here}} + // expected-note@-6 {{here}} +#endif + +#if __cplusplus >= 201103L + struct Y { + template<typename T> using T1 = Y; + }; + template<typename T> using T2 = Y; + void j(Y *y) { + y->~T1<int>(); + y->~T2<int>(); + } + struct Z { + template<typename T> using T2 = T; + }; + void k(Z *z) { + // FIXME: This diagnostic is terrible. + z->~T1<int>(); // expected-error {{'T1' following the 'template' keyword does not refer to a template}} expected-error +{{}} + z->~T2<int>(); // expected-error {{no member named '~int'}} + z->~T2<Z>(); + } + + // FIXME: This is valid. + namespace Q { + template<typename A> struct R {}; + } + template<typename A> using R = Q::R<int>; + void qr(Q::R<int> x) { x.~R<char>(); } // expected-error {{no member named}} +#endif +} + +namespace dr306 { // dr306: no + // FIXME: dup 39 + // FIXME: This should be accepted. + struct A { struct B {}; }; // expected-note 2{{member}} + struct C { typedef A::B B; }; // expected-note {{member}} + struct D : A, A::B, C {}; + D::B b; // expected-error {{found in multiple base classes of different types}} +} + +// dr307: na + +namespace dr308 { // dr308: yes + // This is mostly an ABI library issue. + struct A {}; + struct B : A {}; + struct C : A {}; + struct D : B, C {}; + void f() { + try { + throw D(); + } catch (const A&) { + // unreachable + } catch (const B&) { + // get here instead + } + } +} + +// dr309: dup 485 + +namespace dr311 { // dr311: yes + namespace X { namespace Y {} } + namespace X::Y {} // expected-error {{must define each namespace separately}} + namespace X { + namespace X::Y {} // expected-error {{must define each namespace separately}} + } + // FIXME: The diagnostics here are not very good. + namespace ::dr311::X {} // expected-error 2+{{}} // expected-warning {{extra qual}} +} + +// dr312: dup 616 + +namespace dr313 { // dr313: dup 299 c++11 + struct A { operator int() const; }; + int *p = new int[A()]; +#if __cplusplus < 201103L + // FIXME: should this be available in c++98 mode? expected-error@-2 {{extension}} +#endif +} + +namespace dr314 { // dr314: dup 1710 + template<typename T> struct A { + template<typename U> struct B {}; + }; + template<typename T> struct C : public A<T>::template B<T> { + C() : A<T>::template B<T>() {} + }; +} + +// dr315: na +// dr316: sup 1004 + +namespace dr317 { // dr317: 3.5 + void f() {} // expected-note {{previous}} + inline void f(); // expected-error {{inline declaration of 'f' follows non-inline definition}} + + int g(); + int n = g(); + inline int g() { return 0; } + + int h(); + int m = h(); + int h() { return 0; } // expected-note {{previous}} + inline int h(); // expected-error {{inline declaration of 'h' follows non-inline definition}} +} + +namespace dr318 { // dr318: sup 1310 + struct A {}; + struct A::A a; +} + +namespace dr319 { // dr319: no + // FIXME: dup dr389 + // FIXME: We don't have a diagnostic for a name with linkage + // having a type without linkage. + typedef struct { + int i; + } *ps; + extern "C" void f(ps); + void g(ps); // FIXME: ill-formed, type 'ps' has no linkage + + static enum { e } a1; + enum { e2 } a2; // FIXME: ill-formed, enum type has no linkage + + enum { n1 = 1u }; + typedef int (*pa)[n1]; + pa parr; // ok, type has linkage despite using 'n1' + + template<typename> struct X {}; + + void f() { + struct A { int n; }; + extern A a; // FIXME: ill-formed + X<A> xa; + + typedef A B; + extern B b; // FIXME: ill-formed + X<B> xb; + + const int n = 1; + typedef int (*C)[n]; + extern C c; // ok + X<C> xc; + } +#if __cplusplus < 201103L + // expected-error@-12 {{uses local type 'A'}} + // expected-error@-9 {{uses local type 'A'}} +#endif +} + +namespace dr320 { // dr320: yes +#if __cplusplus >= 201103L + struct X { + constexpr X() {} + constexpr X(const X &x) : copies(x.copies + 1) {} + unsigned copies = 0; + }; + constexpr X f(X x) { return x; } + constexpr unsigned g(X x) { return x.copies; } + static_assert(f(X()).copies == g(X()) + 1, "expected one extra copy for return value"); +#endif +} + +namespace dr321 { // dr321: dup 557 + namespace N { + template<int> struct A { + template<int> struct B; + }; + template<> template<> struct A<0>::B<0>; + void f(A<0>::B<0>); + } + template<> template<> struct N::A<0>::B<0> {}; + + template<typename T> void g(T t) { f(t); } + template void g(N::A<0>::B<0>); + + namespace N { + template<typename> struct I { friend bool operator==(const I&, const I&); }; + } + N::I<int> i, j; + bool x = i == j; +} + +namespace dr322 { // dr322: yes + struct A { + template<typename T> operator T&(); + } a; + int &r = static_cast<int&>(a); + int &s = a; +} + +// dr323: no + +namespace dr324 { // dr324: yes + struct S { int n : 1; } s; // expected-note 3{{bit-field is declared here}} + int &a = s.n; // expected-error {{non-const reference cannot bind to bit-field}} + int *b = &s.n; // expected-error {{address of bit-field}} + int &c = (s.n = 0); // expected-error {{non-const reference cannot bind to bit-field}} + int *d = &(s.n = 0); // expected-error {{address of bit-field}} + int &e = true ? s.n : s.n; // expected-error {{non-const reference cannot bind to bit-field}} + int *f = &(true ? s.n : s.n); // expected-error {{address of bit-field}} + int &g = (void(), s.n); // expected-error {{non-const reference cannot bind to bit-field}} + int *h = &(void(), s.n); // expected-error {{address of bit-field}} +} + +namespace dr326 { // dr326: yes + struct S {}; + int test[__is_trivially_constructible(S, const S&) ? 1 : -1]; +} + +namespace dr327 { // dr327: dup 538 + struct A; + class A {}; + + class B; + struct B {}; +} + +namespace dr328 { // dr328: yes + struct A; // expected-note 3{{forward declaration}} + struct B { A a; }; // expected-error {{incomplete}} + template<typename> struct C { A a; }; // expected-error {{incomplete}} + A *p = new A[0]; // expected-error {{incomplete}} +} + +namespace dr329 { // dr329: 3.5 + struct B {}; + template<typename T> struct A : B { + friend void f(A a) { g(a); } + friend void h(A a) { g(a); } // expected-error {{undeclared}} + friend void i(B b) {} // expected-error {{redefinition}} expected-note {{previous}} + }; + A<int> a; + A<char> b; // expected-note {{instantiation}} + + void test() { + h(a); // expected-note {{instantiation}} + } +} + +namespace dr331 { // dr331: yes + struct A { + A(volatile A&); // expected-note {{candidate}} + } const a, b(a); // expected-error {{no matching constructor}} +} + +namespace dr332 { // dr332: dup 557 + void f(volatile void); // expected-error {{'void' as parameter must not have type qualifiers}} + void g(const void); // expected-error {{'void' as parameter must not have type qualifiers}} + void h(int n, volatile void); // expected-error {{'void' must be the first and only parameter}} +} + +namespace dr333 { // dr333: yes + int n = 0; + int f(int(n)); + int g((int(n))); + int h = f(g); +} + +namespace dr334 { // dr334: yes + template<typename T> void f() { + T x; + f((x, 123)); + } + struct S { + friend S operator,(S, int); + friend void f(S); + }; + template void f<S>(); +} + +// dr335: no + +namespace dr336 { // dr336: yes + namespace Pre { + template<class T1> class A { + template<class T2> class B { + template<class T3> void mf1(T3); + void mf2(); + }; + }; + template<> template<class X> class A<int>::B {}; + template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {} // expected-error {{does not match}} + template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}} + } + namespace Post { + template<class T1> class A { + template<class T2> class B { + template<class T3> void mf1(T3); + void mf2(); + }; + }; + template<> template<class X> class A<int>::B { + template<class T> void mf1(T); + }; + template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {} + // FIXME: This diagnostic isn't very good. + template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}} + } +} + +namespace dr337 { // dr337: yes + template<typename T> void f(T (*)[1]); + template<typename T> int &f(...); + + struct A { virtual ~A() = 0; }; + int &r = f<A>(0); + + // FIXME: The language rules here are completely broken. We cannot determine + // whether an incomplete type is abstract. See DR1640, which will probably + // supersede this one and remove this rule. + struct B; + int &s = f<B>(0); // expected-error {{of type 'void'}} + struct B { virtual ~B() = 0; }; +} + +namespace dr339 { // dr339: yes + template <int I> struct A { static const int value = I; }; + + char xxx(int); + char (&xxx(float))[2]; + + template<class T> A<sizeof(xxx((T)0))> f(T) {} // expected-note {{candidate}} + + void test() { + A<1> a = f(0); + A<2> b = f(0.0f); + A<3> c = f("foo"); // expected-error {{no matching function}} + } + + + char f(int); + int f(...); + + template <class T> struct conv_int { + static const bool value = sizeof(f(T())) == 1; + }; + + template <class T> bool conv_int2(A<sizeof(f(T()))> p); + + template<typename T> A<sizeof(f(T()))> make_A(); + + int a[conv_int<char>::value ? 1 : -1]; + bool b = conv_int2<char>(A<1>()); + A<1> c = make_A<char>(); +} + +namespace dr340 { // dr340: yes + struct A { A(int); }; + struct B { B(A, A, int); }; + int x, y; + B b(A(x), A(y), 3); +} + +namespace dr341 { // dr341: sup 1708 + namespace A { + int n; + extern "C" int &dr341_a = n; // expected-note {{previous}} expected-note {{declared with C language linkage here}} + } + namespace B { + extern "C" int &dr341_a = dr341_a; // expected-error {{redefinition}} + } + extern "C" void dr341_b(); // expected-note {{declared with C language linkage here}} +} +int dr341_a; // expected-error {{declaration of 'dr341_a' in global scope conflicts with declaration with C language linkage}} +int dr341_b; // expected-error {{declaration of 'dr341_b' in global scope conflicts with declaration with C language linkage}} +int dr341_c; // expected-note {{declared in global scope here}} +int dr341_d; // expected-note {{declared in global scope here}} +namespace dr341 { + extern "C" int dr341_c; // expected-error {{declaration of 'dr341_c' with C language linkage conflicts with declaration in global scope}} + extern "C" void dr341_d(); // expected-error {{declaration of 'dr341_d' with C language linkage conflicts with declaration in global scope}} + + namespace A { extern "C" int dr341_e; } // expected-note {{previous}} + namespace B { extern "C" void dr341_e(); } // expected-error {{redefinition of 'dr341_e' as different kind of symbol}} +} + +// dr342: na + +namespace dr343 { // dr343: no + // FIXME: dup 1710 + template<typename T> struct A { + template<typename U> struct B {}; + }; + // FIXME: In these contexts, the 'template' keyword is optional. + template<typename T> struct C : public A<T>::B<T> { // expected-error {{use 'template'}} + C() : A<T>::B<T>() {} // expected-error {{use 'template'}} + }; +} + +namespace dr344 { // dr344: dup 1435 + struct A { inline virtual ~A(); }; + struct B { friend A::~A(); }; +} + +namespace dr345 { // dr345: yes + struct A { + struct X {}; + int X; // expected-note {{here}} + }; + struct B { + struct X {}; + }; + template <class T> void f(T t) { typename T::X x; } // expected-error {{refers to non-type member 'X'}} + void f(A a, B b) { + f(b); + f(a); // expected-note {{instantiation}} + } +} + +// dr346: na + +namespace dr347 { // dr347: yes + struct base { + struct nested; + static int n; + static void f(); + void g(); + }; + + struct derived : base {}; + + struct derived::nested {}; // expected-error {{no struct named 'nested'}} + int derived::n; // expected-error {{no member named 'n'}} + void derived::f() {} // expected-error {{does not match any}} + void derived::g() {} // expected-error {{does not match any}} +} + +// dr348: na + +namespace dr349 { // dr349: no + struct A { + template <class T> operator T ***() { + int ***p = 0; + return p; // expected-error {{cannot initialize return object of type 'const int ***' with an lvalue of type 'int ***'}} + } + }; + + // FIXME: This is valid. + A a; + const int *const *const *p1 = a; // expected-note {{in instantiation of}} + + struct B { + template <class T> operator T ***() { + const int ***p = 0; + return p; + } + }; + + // FIXME: This is invalid. + B b; + const int *const *const *p2 = b; +} + +// dr351: na + +namespace dr352 { // dr352: yes + namespace example1 { + namespace A { + enum E {}; + template<typename R, typename A> void foo(E, R (*)(A)); // expected-note 2{{couldn't infer template argument 'R'}} + } + + template<typename T> void arg(T); + template<typename T> int arg(T) = delete; // expected-note {{here}} expected-error 0-1{{extension}} + + void f(A::E e) { + foo(e, &arg); // expected-error {{no matching function}} + + using A::foo; + foo<int, int>(e, &arg); // expected-error {{deleted}} + } + + int arg(int); + + void g(A::E e) { + foo(e, &arg); // expected-error {{no matching function}} + + using A::foo; + foo<int, int>(e, &arg); // ok, uses non-template + } + } + + namespace contexts { + template<int I> void f1(int (&)[I]); + template<int I> void f2(int (&)[I+1]); // expected-note {{couldn't infer}} + template<int I> void f3(int (&)[I+1], int (&)[I]); + void f() { + int a[4]; + int b[3]; + f1(a); + f2(a); // expected-error {{no matching function}} + f3(a, b); + } + + template<int I> struct S {}; + template<int I> void g1(S<I>); + template<int I> void g2(S<I+1>); // expected-note {{couldn't infer}} + template<int I> void g3(S<I+1>, S<I>); + void g() { + S<4> a; + S<3> b; + g1(a); + g2(a); // expected-error {{no matching function}} + g3(a, b); + } + + template<typename T> void h1(T = 0); // expected-note {{couldn't infer}} + template<typename T> void h2(T, T = 0); + void h() { + h1(); // expected-error {{no matching function}} + h1(0); + h1<int>(); + h2(0); + } + + template<typename T> int tmpl(T); + template<typename R, typename A> void i1(R (*)(A)); // expected-note 3{{couldn't infer}} + template<typename R, typename A> void i2(R, A, R (*)(A)); // expected-note {{not viable}} + void i() { + extern int single(int); + i1(single); + i2(0, 0, single); + + extern int ambig(float), ambig(int); + i1(ambig); // expected-error {{no matching function}} + i2(0, 0, ambig); + + extern void no_match(float), no_match(int); + i1(no_match); // expected-error {{no matching function}} + i2(0, 0, no_match); // expected-error {{no matching function}} + + i1(tmpl); // expected-error {{no matching function}} + i2(0, 0, tmpl); + } + } + + template<typename T> struct is_int; + template<> struct is_int<int> {}; + + namespace example2 { + template<typename T> int f(T (*p)(T)) { is_int<T>(); } + int g(int); + int g(char); + int i = f(g); + } + + namespace example3 { + template<typename T> int f(T, T (*p)(T)) { is_int<T>(); } + int g(int); + char g(char); + int i = f(1, g); + } + + namespace example4 { + template <class T> int f(T, T (*p)(T)) { is_int<T>(); } + char g(char); + template <class T> T g(T); + int i = f(1, g); + } + + namespace example5 { + template<int I> class A {}; + template<int I> void g(A<I+1>); // expected-note {{couldn't infer}} + template<int I> void f(A<I>, A<I+1>); + void h(A<1> a1, A<2> a2) { + g(a1); // expected-error {{no matching function}} + g<0>(a1); + f(a1, a2); + } + } +} + +// dr353 needs an IRGen test. + +namespace dr354 { // dr354: yes c++11 + // FIXME: Should we allow this in C++98 too? + struct S {}; + + template<int*> struct ptr {}; // expected-note +{{here}} + ptr<0> p0; + ptr<(int*)0> p1; + ptr<(float*)0> p2; + ptr<(int S::*)0> p3; +#if __cplusplus < 201103L + // expected-error@-5 {{does not refer to any decl}} + // expected-error@-5 {{does not refer to any decl}} + // expected-error@-5 {{does not refer to any decl}} + // expected-error@-5 {{does not refer to any decl}} +#else + // expected-error@-10 {{must be cast}} + // ok + // expected-error@-10 {{does not match}} + // expected-error@-10 {{does not match}} +#endif + + template<int*> int both(); + template<int> int both(); + int b0 = both<0>(); + int b1 = both<(int*)0>(); +#if __cplusplus < 201103L + // expected-error@-2 {{no matching function}} + // expected-note@-6 {{candidate}} + // expected-note@-6 {{candidate}} +#endif + + template<int S::*> struct ptr_mem {}; // expected-note +{{here}} + ptr_mem<0> m0; + ptr_mem<(int S::*)0> m1; + ptr_mem<(float S::*)0> m2; + ptr_mem<(int *)0> m3; +#if __cplusplus < 201103L + // expected-error@-5 {{cannot be converted}} + // expected-error@-5 {{is not a pointer to member constant}} + // expected-error@-5 {{cannot be converted}} + // expected-error@-5 {{cannot be converted}} +#else + // expected-error@-10 {{must be cast}} + // ok + // expected-error@-10 {{does not match}} + // expected-error@-10 {{does not match}} +#endif +} + +struct dr355_S; // dr355: yes +struct ::dr355_S {}; // expected-warning {{extra qualification}} +namespace dr355 { struct ::dr355_S s; } + +// dr356: na + +namespace dr357 { // dr357: yes + template<typename T> struct A { + void f() const; // expected-note {{const qualified}} + }; + template<typename T> void A<T>::f() {} // expected-error {{does not match}} + + struct B { + template<typename T> void f(); + }; + template<typename T> void B::f() const {} // expected-error {{does not match}} +} + +namespace dr358 { // dr358: yes + extern "C" void dr358_f(); + namespace N { + int var; + extern "C" void dr358_f() { var = 10; } + } +} + +namespace dr359 { // dr359: yes + // Note, the example in the DR is wrong; it doesn't contain an anonymous + // union. + struct E { + union { + struct { + int x; + } s; + } v; + + union { + struct { // expected-error {{extension}} + int x; + } s; + + struct S { // expected-error {{types cannot be declared in an anonymous union}} + int x; + } t; + + union { // expected-error {{extension}} + int u; + }; + }; + }; +} + +// dr362: na +// dr363: na + +namespace dr364 { // dr364: yes + struct S { + static void f(int); + void f(char); + }; + + void g() { + S::f('a'); // expected-error {{call to non-static}} + S::f(0); + } +} + +#if "foo" // expected-error {{invalid token}} dr366: yes +#endif + +namespace dr367 { // dr367: yes + // FIXME: These diagnostics are terrible. Don't diagnose an ill-formed global + // array as being a VLA! + int a[true ? throw 0 : 4]; // expected-error 2{{variable length array}} + int b[true ? 4 : throw 0]; + int c[true ? *new int : 4]; // expected-error 2{{variable length array}} + int d[true ? 4 : *new int]; +#if __cplusplus < 201103L + // expected-error@-4 {{variable length array}} expected-error@-4 {{constant expression}} + // expected-error@-3 {{variable length array}} expected-error@-3 {{constant expression}} +#endif +} + +namespace dr368 { // dr368: yes + template<typename T, T> struct S {}; // expected-note {{here}} + template<typename T> int f(S<T, T()> *); // expected-error {{function type}} + //template<typename T> int g(S<T, (T())> *); // FIXME: crashes clang + template<typename T> int g(S<T, true ? T() : T()> *); // expected-note {{cannot have type 'dr368::X'}} + struct X {}; + int n = g<X>(0); // expected-error {{no matching}} +} + +// dr370: na + +namespace dr372 { // dr372: no + namespace example1 { + template<typename T> struct X { + protected: + typedef T Type; // expected-note 2{{protected}} + }; + template<typename T> struct Y {}; + + // FIXME: These two are valid; deriving from T1<T> gives Z1 access to + // the protected member T1<T>::Type. + template<typename T, + template<typename> class T1, + template<typename> class T2> struct Z1 : + T1<T>, + T2<typename T1<T>::Type> {}; // expected-error {{protected}} + + template<typename T, + template<typename> class T1, + template<typename> class T2> struct Z2 : + T2<typename T1<T>::Type>, // expected-error {{protected}} + T1<T> {}; + + Z1<int, X, Y> z1; // expected-note {{instantiation of}} + Z2<int, X, Y> z2; // expected-note {{instantiation of}} + } + + namespace example2 { + struct X { + private: + typedef int Type; // expected-note {{private}} + }; + template<typename T> struct A { + typename T::Type t; // expected-error {{private}} + }; + A<X> ax; // expected-note {{instantiation of}} + } + + namespace example3 { + struct A { + protected: + typedef int N; // expected-note 2{{protected}} + }; + + template<typename T> struct B {}; + template<typename U> struct C : U, B<typename U::N> {}; // expected-error {{protected}} + template<typename U> struct D : B<typename U::N>, U {}; // expected-error {{protected}} + + C<A> x; // expected-note {{instantiation of}} + D<A> y; // expected-note {{instantiation of}} + } + + namespace example4 { + class A { + class B {}; + friend class X; + }; + + struct X : A::B { + A::B mx; + class Y { + A::B my; + }; + }; + } +} + +namespace dr373 { // dr373: no + // FIXME: This is valid. + namespace X { int dr373; } // expected-note 2{{here}} + struct dr373 { // expected-note {{here}} + void f() { + using namespace dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}} + int k = dr373; // expected-error {{does not refer to a value}} + + namespace Y = dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}} + k = Y::dr373; + } + }; +} + +namespace dr374 { // dr374: yes c++11 + namespace N { + template<typename T> void f(); + template<typename T> struct A { void f(); }; + } + template<> void N::f<char>() {} + template<> void N::A<char>::f() {} + template<> struct N::A<int> {}; +#if __cplusplus < 201103L + // expected-error@-4 {{extension}} expected-note@-7 {{here}} + // expected-error@-4 {{extension}} expected-note@-7 {{here}} + // expected-error@-4 {{extension}} expected-note@-8 {{here}} +#endif +} + +// dr375: dup 345 +// dr376: na + +namespace dr377 { // dr377: yes + enum E { // expected-error {{enumeration values exceed range of largest integer}} + a = -__LONG_LONG_MAX__ - 1, // expected-error 0-1{{extension}} + b = 2 * (unsigned long long)__LONG_LONG_MAX__ // expected-error 0-2{{extension}} + }; +} + +// dr378: dup 276 +// dr379: na + +namespace dr381 { // dr381: yes + struct A { + int a; + }; + struct B : virtual A {}; + struct C : B {}; + struct D : B {}; + struct E : public C, public D {}; + struct F : public A {}; + void f() { + E e; + e.B::a = 0; // expected-error {{ambiguous conversion}} + F f; + f.A::a = 1; + } +} + +namespace dr382 { // dr382: yes c++11 + // FIXME: Should we allow this in C++98 mode? + struct A { typedef int T; }; + typename A::T t; + typename dr382::A a; +#if __cplusplus < 201103L + // expected-error@-3 {{occurs outside of a template}} + // expected-error@-3 {{occurs outside of a template}} +#endif + typename A b; // expected-error {{expected a qualified name}} +} + +namespace dr383 { // dr383: yes + struct A { A &operator=(const A&); }; + struct B { ~B(); }; + union C { C &operator=(const C&); }; + union D { ~D(); }; + int check[(__is_pod(A) || __is_pod(B) || __is_pod(C) || __is_pod(D)) ? -1 : 1]; +} + +namespace dr384 { // dr384: yes + namespace N1 { + template<typename T> struct Base {}; + template<typename T> struct X { + struct Y : public Base<T> { + Y operator+(int) const; + }; + Y f(unsigned i) { return Y() + i; } + }; + } + + namespace N2 { + struct Z {}; + template<typename T> int *operator+(T, unsigned); + } + + int main() { + N1::X<N2::Z> v; + v.f(0); + } +} + +namespace dr385 { // dr385: yes + struct A { protected: void f(); }; + struct B : A { using A::f; }; + struct C : A { void g(B b) { b.f(); } }; + void h(B b) { b.f(); } + + struct D { int n; }; // expected-note {{member}} + struct E : protected D {}; // expected-note 2{{protected}} + struct F : E { friend int i(E); }; + int i(E e) { return e.n; } // expected-error {{protected base}} expected-error {{protected member}} +} + +namespace dr387 { // dr387: yes + namespace old { + template<typename T> class number { + number(int); // expected-note 2{{here}} + friend number gcd(number &x, number &y) {} + }; + + void g() { + number<double> a(3), b(4); // expected-error 2{{private}} + a = gcd(a, b); + b = gcd(3, 4); // expected-error {{undeclared}} + } + } + + namespace newer { + template <typename T> class number { + public: + number(int); + friend number gcd(number x, number y) { return 0; } + }; + + void g() { + number<double> a(3), b(4); + a = gcd(a, b); + b = gcd(3, 4); // expected-error {{undeclared}} + } + } +} + +// FIXME: dr388 needs codegen test + +namespace dr389 { // dr389: no + struct S { + typedef struct {} A; + typedef enum {} B; + typedef struct {} const C; // expected-note 0-2{{here}} + typedef enum {} const D; // expected-note 0-1{{here}} + }; + template<typename> struct T {}; + + struct WithLinkage1 {}; + enum WithLinkage2 {}; + typedef struct {} *WithLinkage3a, WithLinkage3b; + typedef enum {} WithLinkage4a, *WithLinkage4b; + typedef S::A WithLinkage5; + typedef const S::B WithLinkage6; + typedef int WithLinkage7; + typedef void (*WithLinkage8)(WithLinkage2 WithLinkage1::*, WithLinkage5 *); + typedef T<WithLinkage5> WithLinkage9; + + typedef struct {} *WithoutLinkage1; // expected-note 0-1{{here}} + typedef enum {} const WithoutLinkage2; // expected-note 0-1{{here}} + // These two types don't have linkage even though they are externally visible + // and the ODR requires them to be merged across TUs. + typedef S::C WithoutLinkage3; + typedef S::D WithoutLinkage4; + typedef void (*WithoutLinkage5)(int (WithoutLinkage3::*)(char)); + +#if __cplusplus >= 201103L + // This has linkage even though its template argument does not. + // FIXME: This is probably a defect. + typedef T<WithoutLinkage1> WithLinkage10; +#else + typedef int WithLinkage10; // dummy + + typedef T<WithLinkage1> GoodArg1; + typedef T<WithLinkage2> GoodArg2; + typedef T<WithLinkage3a> GoodArg3a; + typedef T<WithLinkage3b> GoodArg3b; + typedef T<WithLinkage4a> GoodArg4a; + typedef T<WithLinkage4b> GoodArg4b; + typedef T<WithLinkage5> GoodArg5; + typedef T<WithLinkage6> GoodArg6; + typedef T<WithLinkage7> GoodArg7; + typedef T<WithLinkage8> GoodArg8; + typedef T<WithLinkage9> GoodArg9; + + typedef T<WithoutLinkage1> BadArg1; // expected-error{{template argument uses}} + typedef T<WithoutLinkage2> BadArg2; // expected-error{{template argument uses}} + typedef T<WithoutLinkage3> BadArg3; // expected-error{{template argument uses}} + typedef T<WithoutLinkage4> BadArg4; // expected-error{{template argument uses}} + typedef T<WithoutLinkage5> BadArg5; // expected-error{{template argument uses}} +#endif + + extern WithLinkage1 withLinkage1; + extern WithLinkage2 withLinkage2; + extern WithLinkage3a withLinkage3a; + extern WithLinkage3b withLinkage3b; + extern WithLinkage4a withLinkage4a; + extern WithLinkage4b withLinkage4b; + extern WithLinkage5 withLinkage5; + extern WithLinkage6 withLinkage6; + extern WithLinkage7 withLinkage7; + extern WithLinkage8 withLinkage8; + extern WithLinkage9 withLinkage9; + extern WithLinkage10 withLinkage10; + + // FIXME: These are all ill-formed. + extern WithoutLinkage1 withoutLinkage1; + extern WithoutLinkage2 withoutLinkage2; + extern WithoutLinkage3 withoutLinkage3; + extern WithoutLinkage4 withoutLinkage4; + extern WithoutLinkage5 withoutLinkage5; + + // OK, extern "C". + extern "C" { + extern WithoutLinkage1 dr389_withoutLinkage1; + extern WithoutLinkage2 dr389_withoutLinkage2; + extern WithoutLinkage3 dr389_withoutLinkage3; + extern WithoutLinkage4 dr389_withoutLinkage4; + extern WithoutLinkage5 dr389_withoutLinkage5; + } + + // OK, defined. + WithoutLinkage1 withoutLinkageDef1; + WithoutLinkage2 withoutLinkageDef2 = WithoutLinkage2(); + WithoutLinkage3 withoutLinkageDef3 = {}; + WithoutLinkage4 withoutLinkageDef4 = WithoutLinkage4(); + WithoutLinkage5 withoutLinkageDef5; + + void use(const void *); + void use_all() { + use(&withLinkage1); use(&withLinkage2); use(&withLinkage3a); use(&withLinkage3b); + use(&withLinkage4a); use(&withLinkage4b); use(&withLinkage5); use(&withLinkage6); + use(&withLinkage7); use(&withLinkage8); use(&withLinkage9); use(&withLinkage10); + + use(&withoutLinkage1); use(&withoutLinkage2); use(&withoutLinkage3); + use(&withoutLinkage4); use(&withoutLinkage5); + + use(&dr389_withoutLinkage1); use(&dr389_withoutLinkage2); + use(&dr389_withoutLinkage3); use(&dr389_withoutLinkage4); + use(&dr389_withoutLinkage5); + + use(&withoutLinkageDef1); use(&withoutLinkageDef2); use(&withoutLinkageDef3); + use(&withoutLinkageDef4); use(&withoutLinkageDef5); + } + + void local() { + // FIXME: This is ill-formed. + extern WithoutLinkage1 withoutLinkageLocal; + } +} + +namespace dr390 { // dr390: yes + template<typename T> + struct A { + A() { f(); } // expected-warning {{call to pure virt}} + virtual void f() = 0; // expected-note {{here}} + virtual ~A() = 0; + }; + template<typename T> A<T>::~A() { T::error; } // expected-error {{cannot be used prior to}} + template<typename T> void A<T>::f() { T::error; } // ok, not odr-used + struct B : A<int> { // expected-note 2{{in instantiation of}} + void f() {} + } b; +} + +namespace dr391 { // dr391: yes c++11 + // FIXME: Should this apply to C++98 too? + class A { A(const A&); }; // expected-note 0-1{{here}} + A fa(); + const A &a = fa(); +#if __cplusplus < 201103L + // expected-error@-2 {{C++98 requires an accessible copy constructor}} +#endif + + struct B { B(const B&) = delete; }; // expected-error 0-1{{extension}} expected-note 0-1{{here}} + B fb(); + const B &b = fb(); +#if __cplusplus < 201103L + // expected-error@-2 {{deleted}} +#endif + + template<typename T> + struct C { + C(const C&) { T::error; } + }; + C<int> fc(); + const C<int> &c = fc(); +} + +// dr392 FIXME write codegen test +// dr394: na + +namespace dr395 { // dr395: yes + struct S { + template <typename T, int N>(&operator T())[N]; // expected-error {{must use a typedef}} + template <typename T, int N> operator(T (&)[N])(); // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error +{{}} + template <typename T> operator T *() const { return 0; } + template <typename T, typename U> operator T U::*() const { return 0; } + template <typename T, typename U> operator T (U::*)()() const { return 0; } // expected-error +{{}} + }; + + struct null1_t { + template <class T, class U> struct ptr_mem_fun_t { + typedef T (U::*type)(); + }; + + template <class T, class U> + operator typename ptr_mem_fun_t<T, U>::type() const { // expected-note {{couldn't infer}} + return 0; + } + } null1; + int (S::*p)() = null1; // expected-error {{no viable conversion}} + + template <typename T> using id = T; // expected-error 0-1{{extension}} + + struct T { + template <typename T, int N> operator id<T[N]> &(); + template <typename T, typename U> operator id<T (U::*)()>() const; + }; + + struct null2_t { + template<class T, class U> using ptr_mem_fun_t = T (U::*)(); // expected-error 0-1{{extension}} + template<class T, class U> operator ptr_mem_fun_t<T, U>() const { return 0; }; + } null2; + int (S::*q)() = null2; +} + +namespace dr396 { // dr396: yes + void f() { + auto int a(); // expected-error {{storage class on function}} + int (i); // expected-note {{previous}} + auto int (i); // expected-error {{redefinition}} +#if __cplusplus >= 201103L + // expected-error@-4 {{'auto' storage class}} expected-error@-2 {{'auto' storage class}} +#endif + } +} + +// dr397: sup 1823 + +namespace dr398 { // dr398: yes + namespace example1 { + struct S { + static int const I = 42; + }; + template <int N> struct X {}; + template <typename T> void f(X<T::I> *) {} + template <typename T> void f(X<T::J> *) {} + void foo() { f<S>(0); } + } + + namespace example2 { + template <int I> struct X {}; + template <template <class T> class> struct Z {}; + template <class T> void f(typename T::Y *) {} // expected-note 2{{substitution failure}} + template <class T> void g(X<T::N> *) {} // expected-note {{substitution failure}} + template <class T> void h(Z<T::template TT> *) {} // expected-note {{substitution failure}} + struct A {}; + struct B { + int Y; + }; + struct C { + typedef int N; + }; + struct D { + typedef int TT; + }; + + void test() { + f<A>(0); // expected-error {{no matching function}} + f<B>(0); // expected-error {{no matching function}} + g<C>(0); // expected-error {{no matching function}} + h<D>(0); // expected-error {{no matching function}} + } + } +} diff --git a/test/CXX/drs/dr412.cpp b/test/CXX/drs/dr412.cpp new file mode 100644 index 0000000000000..cb33e206a632f --- /dev/null +++ b/test/CXX/drs/dr412.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT="throw()" -DBAD_ALLOC="throw(std::bad_alloc)" +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= +// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= + +// dr412: yes +// lwg404: yes +// lwg2340: yes + +// FIXME: __SIZE_TYPE__ expands to 'long long' on some targets. +__extension__ typedef __SIZE_TYPE__ size_t; +namespace std { struct bad_alloc {}; } + +inline void* operator new(size_t) BAD_ALLOC; // expected-error {{cannot be declared 'inline'}} +inline void* operator new[](size_t) BAD_ALLOC; // expected-error {{cannot be declared 'inline'}} +inline void operator delete(void*) NOEXCEPT; // expected-error {{cannot be declared 'inline'}} +inline void operator delete[](void*) NOEXCEPT; // expected-error {{cannot be declared 'inline'}} +#if __cplusplus >= 201402L +inline void operator delete(void*, size_t) NOEXCEPT; // expected-error {{cannot be declared 'inline'}} +inline void operator delete[](void*, size_t) NOEXCEPT; // expected-error {{cannot be declared 'inline'}} +#endif diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp index 1d3b94064cdda..815dbfc0b4010 100644 --- a/test/CXX/drs/dr4xx.cpp +++ b/test/CXX/drs/dr4xx.cpp @@ -1,6 +1,140 @@ -// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// expected-no-diagnostics +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +// FIXME: __SIZE_TYPE__ expands to 'long long' on some targets. +__extension__ typedef __SIZE_TYPE__ size_t; + +namespace std { struct type_info; } + +namespace dr400 { // dr400: yes + struct A { int a; struct a {}; }; // expected-note 2{{conflicting}} expected-note {{ambiguous}} + struct B { int a; struct a {}; }; // expected-note 2{{target}} expected-note {{ambiguous}} + struct C : A, B { using A::a; struct a b; }; + struct D : A, B { using A::a; using B::a; struct a b; }; // expected-error 2{{conflicts}} + struct E : A, B { struct a b; }; // expected-error {{found in multiple base classes}} +} + +namespace dr401 { // dr401: yes + template<class T, class U = typename T::type> class A : public T {}; // expected-error {{protected}} expected-error 2{{private}} + + class B { + protected: + typedef int type; // expected-note {{protected}} + }; + + class C { + typedef int type; // expected-note {{private}} + friend class A<C>; // expected-note {{default argument}} + }; + + class D { + typedef int type; // expected-note {{private}} + friend class A<D, int>; + }; + + A<B> *b; // expected-note {{default argument}} + // FIXME: We're missing the "in instantiation of" note for the default + // argument here. + A<D> *d; + + struct E { + template<class T, class U = typename T::type> class A : public T {}; + }; + class F { + typedef int type; + friend class E; + }; + E::A<F> eaf; // ok, default argument is in befriended context + + // FIXME: Why do we get different diagnostics in C++11 onwards here? We seem + // to not treat the default template argument as a SFINAE context in C++98. + template<class T, class U = typename T::type> void f(T) {} + void g(B b) { f(b); } +#if __cplusplus < 201103L + // expected-error@-3 0-1{{extension}} expected-error@-3 {{protected}} expected-note@-3 {{instantiation}} + // expected-note@-3 {{substituting}} +#else + // expected-error@-5 {{no matching}} expected-note@-6 {{protected}} +#endif +} + +namespace dr403 { // dr403: yes + namespace A { + struct S {}; + int f(void*); + } + template<typename T> struct X {}; + typedef struct X<A::S>::X XS; + XS *p; + int k = f(p); // ok, finds A::f, even though type XS is a typedef-name + // referring to an elaborated-type-specifier naming a + // injected-class-name, which is about as far from a + // template-id as we can make it. +} + +// dr404: na +// (NB: also sup 594) + +namespace dr406 { // dr406: yes + typedef struct { + static int n; // expected-error {{static data member 'n' not allowed in anonymous struct}} + } A; +} + +namespace dr407 { // dr407: no + struct S; + typedef struct S S; + void f() { + struct S *p; + { + typedef struct S S; // expected-note {{here}} + struct S *p; // expected-error {{refers to a typedef}} + } + } + struct S {}; + + namespace UsingDir { + namespace A { + struct S {}; // expected-note {{found}} + } + namespace B { + typedef int S; // expected-note {{found}} + } + namespace C { + using namespace A; + using namespace B; + struct S s; // expected-error {{ambiguous}} + } + namespace D { + // FIXME: This is valid. + using A::S; + typedef struct S S; // expected-note {{here}} + struct S s; // expected-error {{refers to a typedef}} + } + namespace E { + // FIXME: The standard doesn't say whether this is valid. + typedef A::S S; + using A::S; + struct S s; + } + namespace F { + typedef A::S S; // expected-note {{here}} + } + // FIXME: The standard doesn't say what to do in these cases, but + // our behavior should not depend on the order of the using-directives. + namespace G { + using namespace A; + using namespace F; + struct S s; + } + namespace H { + using namespace F; + using namespace A; + struct S s; // expected-error {{refers to a typedef}} + } + } +} namespace dr408 { // dr408: 3.4 template<int N> void g() { int arr[N != 1 ? 1 : -1]; } @@ -30,3 +164,1060 @@ namespace dr408 { // dr408: 3.4 template<> int R<int>::arr[2]; template void R<int>::f(); } + +namespace dr409 { // dr409: yes + template<typename T> struct A { + typedef int B; + B b1; + A::B b2; + A<T>::B b3; + A<T*>::B b4; // expected-error {{missing 'typename'}} + }; +} + +namespace dr410 { // dr410: no + template<class T> void f(T); + void g(int); + namespace M { + template<class T> void h(T); + template<class T> void i(T); + struct A { + friend void f<>(int); + friend void h<>(int); + friend void g(int); + template<class T> void i(T); + friend void i<>(int); + private: + static void z(); // expected-note {{private}} + }; + + template<> void h(int) { A::z(); } + // FIXME: This should be ill-formed. The member A::i<> is befriended, + // not this function. + template<> void i(int) { A::z(); } + } + template<> void f(int) { M::A::z(); } + void g(int) { M::A::z(); } // expected-error {{private}} +} + +// dr412 is in its own file. + +namespace dr413 { // dr413: yes + struct S { + int a; + int : 17; + int b; + }; + S s = { 1, 2, 3 }; // expected-error {{excess elements}} + + struct E {}; + struct T { // expected-note {{here}} + int a; + E e; + int b; + }; + T t1 = { 1, {}, 2 }; + T t2 = { 1, 2 }; // expected-error {{aggregate with no elements requires explicit braces}} +} + +namespace dr414 { // dr414: dup 305 + struct X {}; + void f() { + X x; + struct X {}; + x.~X(); + } +} + +namespace dr415 { // dr415: yes + template<typename T> void f(T, ...) { T::error; } + void f(int, int); + void g() { f(0, 0); } // ok +} + +namespace dr416 { // dr416: yes + extern struct A a; + int &operator+(const A&, const A&); + int &k = a + a; + struct A { float &operator+(A&); }; + float &f = a + a; +} + +namespace dr417 { // dr417: no + struct A; + struct dr417::A {}; // expected-warning {{extra qualification}} + struct B { struct X; }; + struct C : B {}; + struct C::X {}; // expected-error {{no struct named 'X' in 'dr417::C'}} + struct B::X { struct Y; }; + struct C::X::Y {}; // ok! + namespace N { + struct D; + struct E; + struct F; + struct H; + } + // FIXME: This is ill-formed. + using N::D; + struct dr417::D {}; // expected-warning {{extra qualification}} + using namespace N; + struct dr417::E {}; // expected-warning {{extra qualification}} expected-error {{no struct named 'E'}} + struct N::F {}; + struct G; + using N::H; + namespace M { + struct dr417::G {}; // expected-error {{namespace 'M' does not enclose}} + struct dr417::H {}; // expected-error {{namespace 'M' does not enclose}} + } +} + +namespace dr420 { // dr420: yes + template<typename T> struct ptr { + T *operator->() const; + T &operator*() const; + }; + template<typename T, typename P> void test(P p) { + p->~T(); + p->T::~T(); + (*p).~T(); + (*p).T::~T(); + } + struct X {}; + template void test<int>(int*); + template void test<int>(ptr<int>); + template void test<X>(X*); + template void test<X>(ptr<X>); + + template<typename T> + void test2(T p) { + p->template Y<int>::~Y<int>(); + p->~Y<int>(); + // FIXME: This is ill-formed, but this diagnostic is terrible. We should + // reject this in the parser. + p->template ~Y<int>(); // expected-error 2{{no member named '~typename Y<int>'}} + } + template<typename T> struct Y {}; + template void test2(Y<int>*); // expected-note {{instantiation}} + template void test2(ptr<Y<int> >); // expected-note {{instantiation}} + + void test3(int *p, ptr<int> q) { + typedef int Int; + p->~Int(); + q->~Int(); + p->Int::~Int(); + q->Int::~Int(); + } + +#if __cplusplus >= 201103L + template<typename T> using id = T; + struct A { template<typename T> using id = T; }; + void test4(int *p, ptr<int> q) { + p->~id<int>(); + q->~id<int>(); + p->id<int>::~id<int>(); + q->id<int>::~id<int>(); + p->template id<int>::~id<int>(); // expected-error {{expected unqualified-id}} + q->template id<int>::~id<int>(); // expected-error {{expected unqualified-id}} + p->A::template id<int>::~id<int>(); + q->A::template id<int>::~id<int>(); + } +#endif +} + +namespace dr421 { // dr421: yes + struct X { X(); int n; int &r; }; + int *p = &X().n; // expected-error {{taking the address of a temporary}} + int *q = &X().r; +} + +namespace dr422 { // dr422: yes + template<typename T, typename U> void f() { + typedef T type; // expected-note {{prev}} + typedef U type; // expected-error {{redef}} + } + template void f<int, int>(); + template void f<int, char>(); // expected-note {{instantiation}} +} + +namespace dr423 { // dr423: yes + template<typename T> struct X { operator T&(); }; + void f(X<int> x) { x += 1; } +} + +namespace dr424 { // dr424: yes + struct A { + typedef int N; // expected-note {{previous}} + typedef int N; // expected-error {{redefinition}} + + struct X; + typedef X X; // expected-note {{previous}} + struct X {}; + + struct X *p; + struct A::X *q; + X *r; + + typedef X X; // expected-error {{redefinition}} + }; + struct B { + typedef int N; + }; + struct C : B { + typedef int N; // expected-note {{previous}} + typedef int N; // expected-error {{redefinition}} + }; +} + +namespace dr425 { // dr425: yes + struct A { template<typename T> operator T() const; } a; + float f = 1.0f * a; // expected-error {{ambiguous}} expected-note 5+{{built-in candidate}} + + template<typename T> struct is_float; + template<> struct is_float<float> { typedef void type; }; + + struct B { + template<typename T, typename U = typename is_float<T>::type> operator T() const; // expected-error 0-1{{extension}} + } b; + float g = 1.0f * b; // ok +} + +namespace dr427 { // dr427: yes + struct B {}; + struct D : public B { + D(B &) = delete; // expected-error 0-1{{extension}} expected-note {{deleted}} + }; + + extern D d1; + B &b = d1; + const D &d2 = static_cast<const D&>(b); + const D &d3 = (const D&)b; + const D &d4(b); // expected-error {{deleted}} +} + +namespace dr428 { // dr428: yes + template<typename T> T make(); + extern struct X x; // expected-note 5{{forward declaration}} + void f() { + throw void(); // expected-error {{cannot throw}} + throw make<void*>(); + throw make<const volatile void*>(); + throw x; // expected-error {{cannot throw}} + throw make<X&>(); // expected-error {{cannot throw}} + throw make<X*>(); // expected-error {{cannot throw}} + throw make<const volatile X&>(); // expected-error {{cannot throw}} + throw make<const volatile X*>(); // expected-error {{cannot throw}} + } +} + +namespace dr429 { // dr429: yes c++11 + // FIXME: This rule is obviously intended to apply to C++98 as well. + struct A { + static void *operator new(size_t, size_t); + static void operator delete(void*, size_t); + } *a = new (0) A; +#if __cplusplus >= 201103L + // expected-error@-2 {{'new' expression with placement arguments refers to non-placement 'operator delete'}} + // expected-note@-4 {{here}} +#endif + struct B { + static void *operator new(size_t, size_t); + static void operator delete(void*); + static void operator delete(void*, size_t); + } *b = new (0) B; // ok, second delete is not a non-placement deallocation function +} + +namespace dr430 { // dr430: yes c++11 + // resolved by n2239 + // FIXME: This should apply in C++98 too. + void f(int n) { + int a[] = { n++, n++, n++ }; +#if __cplusplus < 201103L + // expected-warning@-2 {{multiple unsequenced modifications to 'n'}} +#endif + } +} + +namespace dr431 { // dr431: yes + struct A { + template<typename T> T *get(); + template<typename T> struct B { + template<typename U> U *get(); + }; + }; + + template<typename T> void f(A a) { + a.get<A>()->get<T>(); + a.get<T>() + ->get<T>(); // expected-error {{use 'template'}} + a.get<T>()->template get<T>(); + a.A::get<T>(); + A::B<int> *b = a.get<A::B<int> >(); + b->get<int>(); + b->A::B<int>::get<int>(); + b->A::B<int>::get<T>(); + b->A::B<T>::get<int>(); // expected-error {{use 'template'}} + b->A::B<T>::template get<int>(); + b->A::B<T>::get<T>(); // expected-error {{use 'template'}} + b->A::B<T>::template get<T>(); + A::B<T> *c = a.get<A::B<T> >(); + c->get<int>(); // expected-error {{use 'template'}} + c->template get<int>(); + } +} + +namespace dr432 { // dr432: yes + template<typename T> struct A {}; + template<typename T> struct B : A<B> {}; // expected-error {{requires template arguments}} expected-note {{declared}} + template<typename T> struct C : A<C<T> > {}; +#if __cplusplus >= 201103L + template<typename T> struct D : decltype(A<D>()) {}; // expected-error {{requires template arguments}} expected-note {{declared}} +#endif +} + +namespace dr433 { // dr433: yes + template<class T> struct S { + void f(union U*); + }; + U *p; + template<class T> void S<T>::f(union U*) {} + + S<int> s; +} + +namespace dr434 { // dr434: yes + void f() { + const int ci = 0; + int *pi = 0; + const int *&rpci = pi; // expected-error {{cannot bind}} + rpci = &ci; + *pi = 1; + } +} + +// dr435: na + +namespace dr436 { // dr436: yes + enum E { f }; // expected-note {{previous}} + void f(); // expected-error {{redefinition}} +} + +namespace dr437 { // dr437: no + // This is superseded by 1308, which is in turn superseded by 1330, + // which restores this rule. + template<typename U> struct T : U {}; // expected-error {{incomplete}} + struct S { // expected-note {{not complete}} + void f() throw(S); + void g() throw(T<S>); // expected-note {{in instantiation of}} + struct U; // expected-note {{forward}} + void h() throw(U); // expected-error {{incomplete}} + struct U {}; + }; +} + +// dr438 FIXME write a codegen test +// dr439 FIXME write a codegen test +// dr441 FIXME write a codegen test +// dr442: sup 348 +// dr443: na + +namespace dr444 { // dr444: yes + struct D; + struct B { // expected-note {{candidate is the implicit copy}} expected-note 0-1 {{implicit move}} + D &operator=(D &) = delete; // expected-error 0-1{{extension}} expected-note {{deleted}} + }; + struct D : B { // expected-note {{candidate is the implicit}} expected-note 0-1 {{implicit move}} + using B::operator=; + } extern d; + void f() { + d = d; // expected-error {{deleted}} + } +} + +namespace dr445 { // dr445: yes + class A { void f(); }; // expected-note {{private}} + struct B { + friend void A::f(); // expected-error {{private}} + }; +} + +namespace dr446 { // dr446: yes + struct C; + struct A { + A(); + A(const A&) = delete; // expected-error 0-1{{extension}} expected-note +{{deleted}} + A(const C&); + }; + struct C : A {}; + void f(A a, bool b, C c) { + void(b ? a : a); + b ? A() : a; // expected-error {{deleted}} + b ? a : A(); // expected-error {{deleted}} + b ? A() : A(); // expected-error {{deleted}} + + void(b ? a : c); + b ? a : C(); // expected-error {{deleted}} + b ? c : A(); // expected-error {{deleted}} + b ? A() : C(); // expected-error {{deleted}} + } +} + +namespace dr447 { // dr447: yes + struct A { int n; int a[4]; }; + template<int> struct U { + typedef int type; + template<typename V> static void h(); + }; + template<typename T> U<sizeof(T)> g(T); + template<typename T, int N> void f(int n) { + // ok, not type dependent + g(__builtin_offsetof(A, n)).h<int>(); + g(__builtin_offsetof(T, n)).h<int>(); + // value dependent if first argument is a dependent type + U<__builtin_offsetof(A, n)>::type a; + U<__builtin_offsetof(T, n)>::type b; // expected-error +{{}} expected-warning 0+{{}} + // as an extension, we allow the member-designator to include array indices + g(__builtin_offsetof(A, a[0])).h<int>(); // expected-error {{extension}} + g(__builtin_offsetof(A, a[N])).h<int>(); // expected-error {{extension}} + U<__builtin_offsetof(A, a[0])>::type c; // expected-error {{extension}} + U<__builtin_offsetof(A, a[N])>::type d; // expected-error {{extension}} expected-error +{{}} expected-warning 0+{{}} + } +} + +namespace dr448 { // dr448: yes + template<typename T = int> void f(int); // expected-error 0-1{{extension}} expected-note {{no known conversion}} + template<typename T> void g(T t) { + f<T>(t); // expected-error {{neither visible in the template definition nor found by argument-dependent lookup}} + dr448::f(t); // expected-error {{no matching function}} + } + template<typename T> void f(T); // expected-note {{should be declared prior to the call site}} + namespace HideFromADL { struct X {}; } + template void g(int); // ok + template void g(HideFromADL::X); // expected-note {{instantiation of}} +} + +// dr449: na + +namespace dr450 { // dr450: yes + typedef int A[3]; + void f1(const A &); + void f2(A &); // expected-note +{{not viable}} + struct S { A n; }; + void g() { + f1(S().n); + f2(S().n); // expected-error {{no match}}} + } +#if __cplusplus >= 201103L + void h() { + f1(A{}); + f2(A{}); // expected-error {{no match}} + } +#endif +} + +namespace dr451 { // dr451: yes + const int a = 1 / 0; // expected-warning {{undefined}} + const int b = 1 / 0; // expected-warning {{undefined}} + int arr[b]; // expected-error +{{variable length arr}} +} + +namespace dr452 { // dr452: yes + struct A { + int a, b, c; + A *p; + int f(); + A() : a(f()), b(this->f() + a), c(this->a), p(this) {} + }; +} + +// dr454 FIXME write a codegen test + +namespace dr456 { // dr456: yes + // sup 903 c++11 + const int null = 0; + void *p = null; +#if __cplusplus >= 201103L + // expected-error@-2 {{cannot initialize}} +#else + // expected-warning@-4 {{null}} +#endif + + const bool f = false; + void *q = f; +#if __cplusplus >= 201103L + // expected-error@-2 {{cannot initialize}} +#else + // expected-warning@-4 {{null}} +#endif +} + +namespace dr457 { // dr457: yes + const int a = 1; + const volatile int b = 1; + int ax[a]; + int bx[b]; // expected-error +{{variable length array}} + + enum E { + ea = a, + eb = b // expected-error {{not an integral constant}} expected-note {{read of volatile-qualified}} + }; +} + +namespace dr458 { // dr458: no + struct A { + int T; + int f(); + template<typename> int g(); + }; + + template<typename> struct B : A { + int f(); + template<typename> int g(); + template<typename> int h(); + }; + + int A::f() { + return T; + } + template<typename T> + int A::g() { + return T; // FIXME: this is invalid, it finds the template parameter + } + + template<typename T> + int B<T>::f() { + return T; + } + template<typename T> template<typename U> + int B<T>::g() { + return T; + } + template<typename U> template<typename T> + int B<U>::h() { + return T; // FIXME: this is invalid, it finds the template parameter + } +} + +namespace dr460 { // dr460: yes + namespace X { namespace Q { int n; } } + namespace Y { + using X; // expected-error {{requires a qualified name}} + using dr460::X; // expected-error {{cannot refer to namespace}} + using X::Q; // expected-error {{cannot refer to namespace}} + } +} + +// dr461: na +// dr462 FIXME write a codegen test +// dr463: na +// dr464: na +// dr465: na + +namespace dr466 { // dr466: no + typedef int I; + typedef const int CI; + typedef volatile int VI; + void f(int *a, CI *b, VI *c) { + a->~I(); + a->~CI(); + a->~VI(); + a->I::~I(); + a->CI::~CI(); + a->VI::~VI(); + + a->CI::~VI(); // FIXME: This is invalid; CI and VI are not the same scalar type. + + b->~I(); + b->~CI(); + b->~VI(); + b->I::~I(); + b->CI::~CI(); + b->VI::~VI(); + + c->~I(); + c->~CI(); + c->~VI(); + c->I::~I(); + c->CI::~CI(); + c->VI::~VI(); + } +} + +namespace dr467 { // dr467: yes + int stuff(); + + int f() { + static bool done; + if (done) + goto later; + static int k = stuff(); + done = true; + later: + return k; + } + int g() { + goto later; // expected-error {{protected scope}} + int k = stuff(); // expected-note {{bypasses variable initialization}} + later: + return k; + } +} + +namespace dr468 { // dr468: yes c++11 + // FIXME: Should we allow this in C++98 too? + template<typename> struct A { + template<typename> struct B { + static int C; + }; + }; + int k = dr468::template A<int>::template B<char>::C; +#if __cplusplus < 201103L + // expected-error@-2 2{{'template' keyword outside of a template}} +#endif +} + +namespace dr469 { // dr469: no + // FIXME: The core issue here didn't really answer the question. We don't + // deduce 'const T' from a function or reference type in a class template... + template<typename T> struct X; // expected-note 2{{here}} + template<typename T> struct X<const T> {}; + X<int&> x; // expected-error {{undefined}} + X<int()> y; // expected-error {{undefined}} + + // ... but we do in a function template. GCC and EDG fail deduction of 'f' + // and the second 'h'. + template<typename T> void f(const T *); + template<typename T> void g(T *, const T * = 0); + template<typename T> void h(T *) { T::error; } + template<typename T> void h(const T *); + void i() { + f(&i); + g(&i); + h(&i); + } +} + +namespace dr470 { // dr470: yes + template<typename T> struct A { + struct B {}; + }; + template<typename T> struct C { + }; + + template struct A<int>; // expected-note {{previous}} + template struct A<int>::B; // expected-error {{duplicate explicit instantiation}} + + // ok, instantiating C<char> doesn't instantiate base class members. + template struct A<char>; + template struct C<char>; +} + +namespace dr471 { // dr471: yes + struct A { int n; }; + struct B : private virtual A {}; + struct C : protected virtual A {}; + struct D : B, C { int f() { return n; } }; + struct E : private virtual A { + using A::n; + }; + struct F : E, B { int f() { return n; } }; + struct G : virtual A { + private: + using A::n; // expected-note {{here}} + }; + struct H : B, G { int f() { return n; } }; // expected-error {{private}} +} + +namespace dr474 { // dr474: yes + namespace N { + struct S { + void f(); + }; + } + void N::S::f() { + void g(); // expected-note {{previous}} + } + int g(); + namespace N { + int g(); // expected-error {{cannot be overloaded}} + } +} + +// dr475 FIXME write a codegen test + +namespace dr477 { // dr477: 3.5 + struct A { + explicit A(); + virtual void f(); + }; + struct B { + friend explicit A::A(); // expected-error {{'explicit' is invalid in friend declarations}} + friend virtual void A::f(); // expected-error {{'virtual' is invalid in friend declarations}} + }; + explicit A::A() {} // expected-error {{can only be specified inside the class definition}} + virtual void A::f() {} // expected-error {{can only be specified inside the class definition}} +} + +namespace dr478 { // dr478: yes + struct A { virtual void f() = 0; }; // expected-note {{unimplemented}} + void f(A *a); + void f(A a[10]); // expected-error {{array of abstract class type}} +} + +namespace dr479 { // dr479: yes + struct S { + S(); + private: + S(const S&); // expected-note +{{here}} + ~S(); // expected-note +{{here}} + }; + void f() { + throw S(); + // expected-error@-1 {{temporary of type 'dr479::S' has private destructor}} + // expected-error@-2 {{calling a private constructor}} + // expected-error@-3 {{exception object of type 'dr479::S' has private destructor}} +#if __cplusplus < 201103L + // expected-error@-5 {{C++98 requires an accessible copy constructor}} +#endif + } + void g() { + S s; // expected-error {{private destructor}}} + throw s; + // expected-error@-1 {{calling a private constructor}} + // expected-error@-2 {{exception object of type 'dr479::S' has private destructor}} + } + void h() { + try { + f(); + g(); + } catch (S s) { + // expected-error@-1 {{calling a private constructor}} + // expected-error@-2 {{variable of type 'dr479::S' has private destructor}} + } + } +} + +namespace dr480 { // dr480: yes + struct A { int n; }; + struct B : A {}; + struct C : virtual B {}; + struct D : C {}; + + int A::*a = &A::n; + int D::*b = a; // expected-error {{virtual base}} + + extern int D::*c; + int A::*d = static_cast<int A::*>(c); // expected-error {{virtual base}} + + D *e; + A *f = e; + D *g = static_cast<D*>(f); // expected-error {{virtual base}} + + extern D &i; + A &j = i; + D &k = static_cast<D&>(j); // expected-error {{virtual base}} +} + +namespace dr481 { // dr481: yes + template<class T, T U> class A { T *x; }; + T *x; // expected-error {{unknown type}} + + template<class T *U> class B { T *x; }; + T *y; // ok + + struct C { + template<class T> void f(class D *p); + }; + D *z; // ok + + template<typename A = C, typename C = A> struct E { + void f() { + typedef ::dr481::C c; // expected-note {{previous}} + typedef C c; // expected-error {{different type}} + } + }; + template struct E<>; // ok + template struct E<int>; // expected-note {{instantiation of}} + + template<template<typename U_no_typo_correction> class A, + A<int> *B, + U_no_typo_correction *C> // expected-error {{unknown type}} + struct F { + U_no_typo_correction *x; // expected-error {{unknown type}} + }; + + template<template<class H *> class> struct G { + H *x; + }; + H *q; + + typedef int N; + template<N X, typename N, template<N Y> class T> struct I; + template<char*> struct J; + I<123, char*, J> *j; +} + +namespace dr482 { // dr482: 3.5 + extern int a; + void f(); + + int dr482::a = 0; // expected-warning {{extra qualification}} + void dr482::f() {} // expected-warning {{extra qualification}} + + inline namespace X { // expected-error 0-1{{C++11 feature}} + extern int b; + void g(); + struct S; + } + int dr482::b = 0; // expected-warning {{extra qualification}} + void dr482::g() {} // expected-warning {{extra qualification}} + struct dr482::S {}; // expected-warning {{extra qualification}} + + void dr482::f(); // expected-warning {{extra qualification}} + void dr482::g(); // expected-warning {{extra qualification}} + + // FIXME: The following are valid in DR482's wording, but these are bugs in + // the wording which we deliberately don't implement. + namespace N { typedef int type; } + typedef int N::type; // expected-error {{typedef declarator cannot be qualified}} + struct A { + struct B; + struct A::B {}; // expected-error {{extra qualification}} + +#if __cplusplus >= 201103L + enum class C; + enum class A::C {}; // expected-error {{extra qualification}} +#endif + }; +} + +namespace dr483 { // dr483: yes + namespace climits { + int check1[__SCHAR_MAX__ >= 127 ? 1 : -1]; + int check2[__SHRT_MAX__ >= 32767 ? 1 : -1]; + int check3[__INT_MAX__ >= 32767 ? 1 : -1]; + int check4[__LONG_MAX__ >= 2147483647 ? 1 : -1]; + int check5[__LONG_LONG_MAX__ >= 9223372036854775807 ? 1 : -1]; +#if __cplusplus < 201103L + // expected-error@-2 {{extension}} +#endif + } + namespace cstdint { + int check1[__PTRDIFF_WIDTH__ >= 16 ? 1 : -1]; + int check2[__SIG_ATOMIC_WIDTH__ >= 8 ? 1 : -1]; + int check3[__SIZE_WIDTH__ >= 16 ? 1 : -1]; + int check4[__WCHAR_WIDTH__ >= 8 ? 1 : -1]; + int check5[__WINT_WIDTH__ >= 16 ? 1 : -1]; + } +} + +namespace dr484 { // dr484: yes + struct A { + A(); + void f(); + }; + typedef const A CA; + void CA::f() { + this->~CA(); + this->CA::~A(); + this->CA::A::~A(); + } + CA::A() {} + + struct B : CA { + B() : CA() {} + void f() { return CA::f(); } + }; + + struct C; + typedef C CT; // expected-note {{here}} + struct CT {}; // expected-error {{conflicts with typedef}} + + namespace N { + struct D; + typedef D DT; // expected-note {{here}} + } + struct N::DT {}; // expected-error {{conflicts with typedef}} + + typedef struct { + S(); // expected-error {{requires a type}} + } S; +} + +namespace dr485 { // dr485: yes + namespace N { + struct S {}; + int operator+(S, S); + template<typename T> int f(S); + } + template<typename T> int f(); + + N::S s; + int a = operator+(s, s); + int b = f<int>(s); +} + +namespace dr486 { // dr486: yes + template<typename T> T f(T *); // expected-note 2{{substitution failure}} + int &f(...); + + void g(); + int n[10]; + + void h() { + int &a = f(&g); + int &b = f(&n); + f<void()>(&g); // expected-error {{no match}} + f<int[10]>(&n); // expected-error {{no match}} + } +} + +namespace dr487 { // dr487: yes + enum E { e }; + int operator+(int, E); + int i[4 + e]; // expected-error 2{{variable length array}} +} + +namespace dr488 { // dr488: yes c++11 + template <typename T> void f(T); + void f(int); + void g() { + // FIXME: It seems CWG thought this should be a SFINAE failure prior to + // allowing local types as template arguments. In C++98, we should either + // allow local types as template arguments or treat this as a SFINAE + // failure. + enum E { e }; + f(e); +#if __cplusplus < 201103L + // expected-error@-2 {{local type}} +#endif + } +} + +// dr489: na + +namespace dr490 { // dr490: yes + template<typename T> struct X {}; + + struct A { + typedef int T; + struct K {}; // expected-note {{declared}} + + int f(T); + int g(T); + int h(X<T>); + int X<T>::*i(); // expected-note {{previous}} + int K::*j(); + + template<typename T> T k(); + + operator X<T>(); + }; + + struct B { + typedef char T; + typedef int U; + friend int A::f(T); + friend int A::g(U); + friend int A::h(X<T>); + + // FIXME: Per this DR, these two are valid! That is another defect + // (no number yet...) which will eventually supersede this one. + friend int X<T>::*A::i(); // expected-error {{return type}} + friend int K::*A::j(); // expected-error {{undeclared identifier 'K'; did you mean 'A::K'?}} + + // ok, lookup finds B::T, not A::T, so return type matches + friend char A::k<T>(); + friend int A::k<U>(); + + // A conversion-type-id in a conversion-function-id is always looked up in + // the class of the conversion function first. + friend A::operator X<T>(); + }; +} + +namespace dr491 { // dr491: dup 413 + struct A {} a, b[3] = { a, {} }; + A c[2] = { a, {}, b[1] }; // expected-error {{excess elements}} +} + +// dr492 FIXME write a codegen test + +namespace dr493 { // dr493: dup 976 + struct X { + template <class T> operator const T &() const; + }; + void f() { + if (X()) { + } + } +} + +namespace dr494 { // dr494: dup 372 + class A { + class B {}; + friend class C; + }; + class C : A::B { + A::B x; + class D : A::B { + A::B y; + }; + }; +} + +namespace dr495 { // dr495: 3.5 + template<typename T> + struct S { + operator int() { return T::error; } + template<typename U> operator U(); + }; + S<int> s; + long n = s; + + template<typename T> + struct S2 { + template<typename U> operator U(); + operator int() { return T::error; } + }; + S2<int> s2; + long n2 = s2; +} + +namespace dr496 { // dr496: no + struct A { int n; }; + struct B { volatile int n; }; + int check1[ __is_trivially_copyable(const int) ? 1 : -1]; + int check2[!__is_trivially_copyable(volatile int) ? 1 : -1]; + int check3[ __is_trivially_constructible(A, const A&) ? 1 : -1]; + // FIXME: This is wrong. + int check4[ __is_trivially_constructible(B, const B&) ? 1 : -1]; + int check5[ __is_trivially_assignable(A, const A&) ? 1 : -1]; + // FIXME: This is wrong. + int check6[ __is_trivially_assignable(B, const B&) ? 1 : -1]; +} + +namespace dr497 { // dr497: yes + void before() { + struct S { + mutable int i; + }; + const S cs; // expected-error {{default initialization}} + int S::*pm = &S::i; + cs.*pm = 88; + } + + void after() { + struct S { + S() : i(0) {} + mutable int i; + }; + const S cs; + int S::*pm = &S::i; + cs.*pm = 88; // expected-error {{not assignable}} + } +} + +namespace dr499 { // dr499: yes + extern char str[]; + void f() { throw str; } +} diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp new file mode 100644 index 0000000000000..0c0d451c4b222 --- /dev/null +++ b/test/CXX/drs/dr5xx.cpp @@ -0,0 +1,212 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +namespace dr500 { // dr500: dup 372 + class D; + class A { + class B; + class C; + friend class D; + }; + class A::B {}; + class A::C : public A::B {}; + class D : public A::B {}; +} + +namespace dr501 { // dr501: yes + struct A { + friend void f() {} + void g() { + void (*p)() = &f; // expected-error {{undeclared identifier}} + } + }; +} + +namespace dr502 { // dr502: yes + struct Q {}; + template<typename T> struct A { + enum E { e = 1 }; + void q1() { f(e); } + void q2() { Q arr[sizeof(E)]; f(arr); } + void q3() { Q arr[e]; f(arr); } + void sanity() { Q arr[1]; f(arr); } // expected-error {{undeclared identifier 'f'}} + }; + int f(A<int>::E); + template<int N> int f(Q (&)[N]); + template struct A<int>; +} + +namespace dr505 { // dr505: yes + const char *exts = "\e\(\{\[\%"; // expected-error 5{{use of non-standard escape}} + const char *unknown = "\Q"; // expected-error {{unknown escape sequence}} +} + +namespace dr506 { // dr506: yes + struct NonPod { ~NonPod(); }; + void f(...); + void g(NonPod np) { f(np); } // expected-error {{cannot pass}} +} + +// FIXME: Add tests here once DR260 is resolved. +// dr507: dup 260 + +// dr508: na +// dr509: na +// dr510: na + +namespace dr512 { // dr512: yes + struct A { + A(int); + }; + union U { A a; }; +#if __cplusplus < 201103L + // expected-error@-2 {{has a non-trivial constructor}} + // expected-note@-6 {{no default constructor}} + // expected-note@-6 {{suppressed by user-declared constructor}} +#endif +} + +// dr513: na + +namespace dr514 { // dr514: yes + namespace A { extern int x, y; } + int A::x = y; +} + +namespace dr515 { // dr515: sup 1017 + // FIXME: dr1017 reverses the wording of dr515, but the current draft has + // dr515's wording, with a different fix for dr1017. + + struct X { int n; }; + template<typename T> struct Y : T { + int f() { return X::n; } + }; + int k = Y<X>().f(); + + struct A { int a; }; + struct B { void f() { int k = sizeof(A::a); } }; +#if __cplusplus < 201103L + // expected-error@-2 {{invalid use of non-static data member}} +#endif +} + +// dr516: na + +namespace dr517 { // dr517: no + // This is NDR, but we should diagnose it anyway. + template<typename T> struct S {}; + template<typename T> int v = 0; // expected-error 0-1{{extension}} + + template struct S<int*>; + template int v<int*>; + + S<char&> s; + int k = v<char&>; + + // FIXME: These are both ill-formed. + template<typename T> struct S<T*> {}; + template<typename T> int v<T*> = 0; // expected-error 0-1{{extension}} + + // FIXME: These are both ill-formed. + template<typename T> struct S<T&> {}; + template<typename T> int v<T&> = 0; // expected-error 0-1{{extension}} +} + +namespace dr518 { // dr518: yes c++11 + enum E { e, }; +#if __cplusplus < 201103L + // expected-error@-2 {{C++11 extension}} +#endif +} + +namespace dr519 { // dr519: yes +// FIXME: Add a codegen test. +#if __cplusplus >= 201103L +#define fold(x) (__builtin_constant_p(x) ? (x) : (x)) + int test[fold((int*)(void*)0) ? -1 : 1]; +#undef fold +#endif +} + +// dr520: na + +// dr521: no +// FIXME: The wording here is broken. It's not reasonable to expect a +// diagnostic here. Once the relevant DR gets a number, mark this as a dup. + +namespace dr522 { // dr522: yes + struct S {}; + template<typename T> void b1(volatile T &); + template<typename T> void b2(volatile T * const *); + template<typename T> void b2(volatile T * const S::*); + template<typename T> void b2(volatile T * const S::* const *); + // FIXME: This diagnostic isn't very good. The problem is not substitution failure. + template<typename T> void b2a(volatile T *S::* const *); // expected-note {{substitution failure}} + + template<typename T> struct Base {}; + struct Derived : Base<int> {}; + template<typename T> void b3(Base<T>); + template<typename T> void b3(Base<T> *); + + void test(int n, const int cn, int **p, int *S::*pm) { + int *a[3], *S::*am[3]; + const Derived cd = Derived(); + Derived d[3]; + + b1(n); + b1(cn); + b2(p); + b2(pm); + b2(a); + b2(am); + b2a(am); // expected-error {{no matching function}} + b3(d); + b3(cd); + } +} + +namespace dr524 { // dr524: yes + template<typename T> void f(T a, T b) { operator+(a, b); } // expected-error {{call}} + + struct S {}; + void operator+(S, S); + template void f(S, S); + + namespace N { struct S {}; } + void operator+(N::S, N::S); // expected-note {{should be declared}} + template void f(N::S, N::S); // expected-note {{instantiation}} +} + +namespace dr525 { // dr525: yes + namespace before { + // Note, the example was correct prior to the change; instantiation is + // required for cases like this: + template <class T> struct D { operator T*(); }; + void g(D<double> ppp) { + delete ppp; + } + } + namespace after { + template <class T> struct D { typename T::error e; }; // expected-error {{prior to '::'}} + void g(D<double> *ppp) { + delete ppp; // expected-note {{instantiation of}} + } + } +} + +// PR8130 +namespace dr532 { // dr532: 3.5 + struct A { }; + + template<class T> struct B { + template<class R> int &operator*(R&); + }; + + template<class T, class R> float &operator*(T&, R&); + void test() { + A a; + B<A> b; + int &ir = b * a; + } +} diff --git a/test/CXX/drs/dr9xx.cpp b/test/CXX/drs/dr9xx.cpp new file mode 100644 index 0000000000000..40dc2821adc31 --- /dev/null +++ b/test/CXX/drs/dr9xx.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +#if __cplusplus < 201103L +// expected-no-diagnostics +#endif + +namespace std { + __extension__ typedef __SIZE_TYPE__ size_t; + + template<typename T> struct initializer_list { + const T *p; size_t n; + initializer_list(const T *p, size_t n); + }; +} + +namespace dr990 { // dr990: 3.5 +#if __cplusplus >= 201103L + struct A { // expected-note 2{{candidate}} + A(std::initializer_list<int>); // expected-note {{candidate}} + }; + struct B { + A a; + }; + B b1 { }; + B b2 { 1 }; // expected-error {{no viable conversion from 'int' to 'dr990::A'}} + B b3 { { 1 } }; + + struct C { + C(); + C(int); + C(std::initializer_list<int>) = delete; // expected-note {{here}} + }; + C c1[3] { 1 }; // ok + C c2[3] { 1, {2} }; // expected-error {{call to deleted}} + + struct D { + D(); + D(std::initializer_list<int>); + D(std::initializer_list<double>); + }; + D d{}; +#endif +} diff --git a/test/CXX/except/except.spec/canonical.cpp b/test/CXX/except/except.spec/canonical.cpp index b6d3e9c7aba1c..d6dc258892050 100644 --- a/test/CXX/except/except.spec/canonical.cpp +++ b/test/CXX/except/except.spec/canonical.cpp @@ -9,7 +9,7 @@ namespace std template <class _Tp> _Tp&& declval() noexcept; template <class _Tp, class... _Args> -struct __is_nothrow_constructible +struct _is_nothrow_constructible { static const bool value = noexcept(_Tp(declval<_Args>()...)); }; @@ -22,7 +22,7 @@ public: typedef _Allocator allocator_type; basic_string() - noexcept(__is_nothrow_constructible<allocator_type>::value); + noexcept(_is_nothrow_constructible<allocator_type>::value); }; template <class, class, class _Compare> @@ -30,7 +30,7 @@ struct __map_value_compare { public: __map_value_compare() - noexcept(__is_nothrow_constructible<_Compare>::value); + noexcept(_is_nothrow_constructible<_Compare>::value); }; struct less @@ -45,10 +45,10 @@ struct map template<class T, class _Traits, class _Allocator> -basic_string<T, _Traits, _Allocator>::basic_string() noexcept(__is_nothrow_constructible<allocator_type>::value) {} +basic_string<T, _Traits, _Allocator>::basic_string() noexcept(_is_nothrow_constructible<allocator_type>::value) {} template <class T, class Value, class _Compare> __map_value_compare<T, Value, _Compare>::__map_value_compare() - noexcept(__is_nothrow_constructible<_Compare>::value) {} + noexcept(_is_nothrow_constructible<_Compare>::value) {} } // std diff --git a/test/CXX/except/except.spec/p11.cpp b/test/CXX/except/except.spec/p11.cpp index 1f6bf2131cd6b..1d0a647fb4f49 100644 --- a/test/CXX/except/except.spec/p11.cpp +++ b/test/CXX/except/except.spec/p11.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s // expected-no-diagnostics -// This is the "let the user shoot himself in the foot" clause. +// This is the "let the user shoot themselves in the foot" clause. void f() noexcept { throw 0; // no-error } diff --git a/test/CXX/except/except.spec/p14-ir.cpp b/test/CXX/except/except.spec/p14-ir.cpp index 9b41f3d1bce92..e3b15e5bde9a6 100644 --- a/test/CXX/except/except.spec/p14-ir.cpp +++ b/test/CXX/except/except.spec/p14-ir.cpp @@ -26,12 +26,12 @@ struct X4 { struct X5 : X0, X4 { }; void test(X2 x2, X3 x3, X5 x5) { - // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2*) unnamed_addr + // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2* dereferenceable({{[0-9]+}})) unnamed_addr // CHECK: call void @_ZN2X2C2ERKS_({{.*}}) [[NUW:#[0-9]+]] // CHECK-NEXT: ret void // CHECK-NEXT: } X2 x2a(x2); - // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3*) unnamed_addr + // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3* dereferenceable({{[0-9]+}})) unnamed_addr // CHECK: call void @_ZN2X3C2ERKS_({{.*}}) [[NUW]] // CHECK-NEXT: ret void // CHECK-NEXT: } diff --git a/test/CXX/except/except.spec/p15.cpp b/test/CXX/except/except.spec/p15.cpp index fcf12357f9162..acf4426a8eb56 100644 --- a/test/CXX/except/except.spec/p15.cpp +++ b/test/CXX/except/except.spec/p15.cpp @@ -1,16 +1,20 @@ // RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s +// RUN: %clang_cc1 -DUSE -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Maybe force the implicit declaration of 'operator delete' and 'operator +// delete[]'. This should make no difference to anything! +#ifdef USE +void f(int *p) { + delete p; + delete [] p; +} +#endif // Deallocation functions are implicitly noexcept. // Thus, explicit specs aren't allowed to conflict. -void f() { - // Force implicit declaration of delete. - delete new int; - delete[] new int[1]; -} - -void operator delete(void*); -void operator delete[](void*); +void operator delete(void*); // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}} +void operator delete[](void*); // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}} static_assert(noexcept(operator delete(0)), ""); static_assert(noexcept(operator delete[](0)), ""); diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp index f0b53c7d3b5cc..bcf45a0c05b4d 100644 --- a/test/CXX/expr/expr.const/p2-0x.cpp +++ b/test/CXX/expr/expr.const/p2-0x.cpp @@ -138,7 +138,7 @@ namespace UndefinedBehavior { case (int)(unsigned)(long long)4.4e9: // ok case (int)(float)1e300: // expected-error {{constant expression}} expected-note {{value 1.0E+300 is outside the range of representable values of type 'float'}} expected-error {{duplicate case value '2147483647'}} expected-note {{previous case defined here}} case (int)((float)1e37 / 1e30): // ok - case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value 65536 is outside the range of representable values of type 'half'}} expected-error {{duplicate case value '2147483647'}} + case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value 65536 is outside the range of representable values of type '__fp16'}} expected-error {{duplicate case value '2147483647'}} break; } } @@ -202,7 +202,9 @@ namespace UndefinedBehavior { static_assert((A*)nb == 0, ""); static_assert((B*)na == 0, ""); constexpr const int &nf = nb->n; // expected-error {{constant expression}} expected-note {{cannot access field of null pointer}} - constexpr const int &np = (*(int(*)[4])nullptr)[2]; // expected-error {{constant expression}} expected-note {{cannot access array element of null pointer}} + constexpr const int *np1 = (int*)nullptr + 0; // ok + constexpr const int *np2 = &(*(int(*)[4])nullptr)[0]; // ok + constexpr const int *np3 = &(*(int(*)[4])nullptr)[2]; // expected-error {{constant expression}} expected-note {{cannot perform pointer arithmetic on null pointer}} struct C { constexpr int f() const { return 0; } diff --git a/test/CXX/expr/expr.const/p3-0x.cpp b/test/CXX/expr/expr.const/p3-0x.cpp index e3e32dfe09001..d9d84853ebae9 100644 --- a/test/CXX/expr/expr.const/p3-0x.cpp +++ b/test/CXX/expr/expr.const/p3-0x.cpp @@ -97,7 +97,7 @@ template <bool B> int f() { return B; } // expected-note {{candidate template ig template int f<&S::operator int>(); // expected-error {{does not refer to a function template}} template int f<(bool)&S::operator int>(); -int n = Val<bool, &S::operator int>::value; // expected-error {{conversion from 'int (S::*)() const' to 'bool' is not allowed in a converted constant expression}} +int n = Val<bool, &S::operator int>::value; // expected-error-re {{conversion from 'int (S::*)(){{( __attribute__\(\(thiscall\)\))?}} const' to 'bool' is not allowed in a converted constant expression}} namespace NonConstLValue { struct S { diff --git a/test/CXX/expr/expr.mptr.oper/p5.cpp b/test/CXX/expr/expr.mptr.oper/p5.cpp index 7380b5d4805d6..c26b30d43da19 100644 --- a/test/CXX/expr/expr.mptr.oper/p5.cpp +++ b/test/CXX/expr/expr.mptr.oper/p5.cpp @@ -24,19 +24,19 @@ void test_object_cvquals(void (X0::*pm)(), (p->*pmv)(); (p->*pmcv)(); - (pc->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const' qualifier}} + (pc->*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'const' qualifier}} (pc->*pmc)(); - (pc->*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}} + (pc->*pmv)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} volatile' drops 'const' qualifier}} (pc->*pmcv)(); - (pv->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'volatile' qualifier}} - (pv->*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}} + (pv->*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'volatile' qualifier}} + (pv->*pmc)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} const' drops 'volatile' qualifier}} (pv->*pmv)(); (pv->*pmcv)(); - (pcv->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const volatile' qualifiers}} - (pcv->*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}} - (pcv->*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}} + (pcv->*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'const volatile' qualifiers}} + (pcv->*pmc)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} const' drops 'volatile' qualifier}} + (pcv->*pmv)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} volatile' drops 'const' qualifier}} (pcv->*pmcv)(); (o.*pm)(); @@ -44,18 +44,18 @@ void test_object_cvquals(void (X0::*pm)(), (o.*pmv)(); (o.*pmcv)(); - (oc.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const' qualifier}} + (oc.*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'const' qualifier}} (oc.*pmc)(); - (oc.*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}} + (oc.*pmv)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} volatile' drops 'const' qualifier}} (oc.*pmcv)(); - (ov.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'volatile' qualifier}} - (ov.*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}} + (ov.*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'volatile' qualifier}} + (ov.*pmc)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} const' drops 'volatile' qualifier}} (ov.*pmv)(); (ov.*pmcv)(); - (ocv.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const volatile' qualifiers}} - (ocv.*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}} - (ocv.*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}} + (ocv.*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'const volatile' qualifiers}} + (ocv.*pmc)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} const' drops 'volatile' qualifier}} + (ocv.*pmv)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} volatile' drops 'const' qualifier}} (ocv.*pmcv)(); } diff --git a/test/CXX/expr/expr.mptr.oper/p6-0x.cpp b/test/CXX/expr/expr.mptr.oper/p6-0x.cpp index 917b2dab7c328..b1823e59fff28 100644 --- a/test/CXX/expr/expr.mptr.oper/p6-0x.cpp +++ b/test/CXX/expr/expr.mptr.oper/p6-0x.cpp @@ -22,13 +22,13 @@ void test(X *xp, int (X::*pmf)(int), int (X::*l_pmf)(int) &, // Lvalue ref-qualifier. (lvalue<X>().*l_pmf)(17); - (xvalue<X>().*l_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &' can only be called on an lvalue}} - (prvalue<X>().*l_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &' can only be called on an lvalue}} + (xvalue<X>().*l_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &' can only be called on an lvalue}} + (prvalue<X>().*l_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &' can only be called on an lvalue}} (xp->*l_pmf)(17); // Rvalue ref-qualifier. - (lvalue<X>().*r_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &&' can only be called on an rvalue}} + (lvalue<X>().*r_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &&' can only be called on an rvalue}} (xvalue<X>().*r_pmf)(17); (prvalue<X>().*r_pmf)(17); - (xp->*r_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &&' can only be called on an rvalue}} + (xp->*r_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &&' can only be called on an rvalue}} } diff --git a/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp b/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp index 4e57b74f08a08..54b2ff52895a0 100644 --- a/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp @@ -6,6 +6,8 @@ struct S { int arr[sizeof(this)]; // expected-error {{invalid use of 'this' outside of a non-static member function}} int sz = sizeof(this); // ok + + typedef auto f() -> decltype(this); // expected-error {{invalid use of 'this' outside of a non-static member function}} }; namespace CaptureThis { diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm index 0db2bf5646ff4..96e8fcd8d3717 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fblocks %s -verify +// RUN: %clang_cc1 -triple i686-pc-linux -std=c++11 -fblocks %s -verify void block_capture_errors() { __block int var; // expected-note 2{{'var' declared here}} @@ -85,6 +85,24 @@ namespace overloading { void call_with_lambda() { int &ir = accept_lambda_conv([](int x) { return x + 1; }); } + + template<typename T> using id = T; + + auto a = [](){}; + struct C : decltype(a) { + using decltype(a)::operator id<void(*)()>; + private: + using decltype(a)::operator id<void(^)()>; + } extern c; + + struct D : decltype(a) { + using decltype(a)::operator id<void(^)()>; + private: + using decltype(a)::operator id<void(*)()>; // expected-note {{here}} + } extern d; + + bool r1 = c; + bool r2 = d; // expected-error {{private}} } namespace PR13117 { diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp deleted file mode 100644 index 7f42c396ee225..0000000000000 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify -//expected-no-diagnostics -namespace lambda_capturing { -// FIXME: Once return type deduction is implemented for generic lambdas -// this will need to be updated. -void test() { - int i = 10; - { - auto L = [=](auto a) -> int { - return i + a; - }; - L(3); - } - { - auto L = [i](auto a) -> int { - return i + a; - }; - L(3); - } - { - auto L = [i=i](auto a) -> int { - return i + a; - }; - L(3); - } - - -} - -} - diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp index 2ddcf18409e98..551c100ff7af3 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp @@ -100,3 +100,12 @@ namespace rdar14468891 { [x]() {}(); // expected-error{{by-copy capture of value of abstract type 'rdar14468891::X'}} } } + +namespace rdar15560464 { + struct X; // expected-note{{forward declaration of 'rdar15560464::X'}} + void foo(const X& param) { + auto x = ([=]() { + auto& y = param; // expected-error{{by-copy capture of variable 'param' with incomplete type 'const rdar15560464::X'}} + }); + } +} diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp index 8a6e79273d55f..35b77896c868e 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp @@ -10,7 +10,7 @@ void test_special_member_functions(MoveOnly mo, int i) { auto lambda1 = [i]() { }; // expected-note 2 {{lambda expression begins here}} // Default constructor - decltype(lambda1) lambda2; // expected-error{{call to implicitly-deleted default constructor of 'decltype(lambda1)' (aka '<lambda}} + decltype(lambda1) lambda2; // expected-error{{call to implicitly-deleted default constructor of 'decltype(lambda1)' (aka '(lambda}} // Copy assignment operator lambda1 = lambda1; // expected-error{{copy assignment operator is implicitly deleted}} diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp index d41c4507a8502..03147a692dd54 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp @@ -1,25 +1,25 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y
-
-// prvalue
-void prvalue() {
- auto&& x = [](auto a)->void { };
- auto& y = [](auto *a)->void { }; // expected-error{{cannot bind to a temporary of type}}
-}
-
-namespace std {
- class type_info;
-}
-
-struct P {
- virtual ~P();
-};
-
-void unevaluated_operand(P &p, int i) { //expected-note{{declared here}}
- // FIXME: this should only emit one error.
- int i2 = sizeof([](auto a, auto b)->void{}(3, '4')); // expected-error{{lambda expression in an unevaluated operand}} \
- // expected-error{{invalid application of 'sizeof'}}
- const std::type_info &ti1 = typeid([](auto &a) -> P& { static P p; return p; }(i));
- const std::type_info &ti2 = typeid([](auto) -> int { return i; }(i)); // expected-error{{lambda expression in an unevaluated operand}}\
- // expected-error{{cannot be implicitly captured}}\
- // expected-note{{begins here}}
-}
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y + +// prvalue +void prvalue() { + auto&& x = [](auto a)->void { }; + auto& y = [](auto *a)->void { }; // expected-error{{cannot bind to a temporary of type}} +} + +namespace std { + class type_info; +} + +struct P { + virtual ~P(); +}; + +void unevaluated_operand(P &p, int i) { //expected-note{{declared here}} + // FIXME: this should only emit one error. + int i2 = sizeof([](auto a, auto b)->void{}(3, '4')); // expected-error{{lambda expression in an unevaluated operand}} \ + // expected-error{{invalid application of 'sizeof'}} + const std::type_info &ti1 = typeid([](auto &a) -> P& { static P p; return p; }(i)); + const std::type_info &ti2 = typeid([](auto) -> int { return i; }(i)); // expected-error{{lambda expression in an unevaluated operand}}\ + // expected-error{{cannot be implicitly captured}}\ + // expected-note{{begins here}} +} diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp index c5d3bf6d1bcf9..415c3d84560ef 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp @@ -1,131 +1,131 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y
-
-namespace test_factorial {
-
-auto Fact = [](auto Self, unsigned n) -> unsigned {
- return !n ? 1 : Self(Self, n - 1) * n;
-};
-
-auto six = Fact(Fact, 3);
-
-}
-
-namespace overload_generic_lambda {
- template <class F1, class F2> struct overload : F1, F2 {
- using F1::operator();
- using F2::operator();
- overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }
- };
-
- auto NumParams = [](auto Self, auto h, auto ... rest) -> unsigned {
- return 1 + Self(Self, rest...);
- };
- auto Base = [](auto Self, auto h) -> unsigned {
- return 1;
- };
- overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);
- int num_params = O(O, 5, 3, "abc", 3.14, 'a');
-}
-
-
-namespace overload_generic_lambda_return_type_deduction {
- template <class F1, class F2> struct overload : F1, F2 {
- using F1::operator();
- using F2::operator();
- overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }
- };
-
- auto NumParams = [](auto Self, auto h, auto ... rest) {
- return 1 + Self(Self, rest...);
- };
- auto Base = [](auto Self, auto h) {
- return 1;
- };
- overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);
- int num_params = O(O, 5, 3, "abc", 3.14, 'a');
-}
-
-namespace test_standard_p5 {
-// FIXME: This test should eventually compile without an explicit trailing return type
-auto glambda = [](auto a, auto&& b) ->bool { return a < b; };
-bool b = glambda(3, 3.14); // OK
-
-}
-namespace test_deduction_failure {
- int test() {
- auto g = [](auto *a) { //expected-note{{candidate template ignored}}
- return a;
- };
- struct X { };
- X *x;
- g(x);
- g(3); //expected-error{{no matching function}}
- return 0;
- }
-
-}
-
-namespace test_instantiation_or_sfinae_failure {
-int test2() {
- {
- auto L = [](auto *a) {
- return (*a)(a); }; //expected-error{{called object type 'double' is not a function}}
- double d;
- L(&d); //expected-note{{in instantiation of}}
- auto M = [](auto b) { return b; };
- L(&M); // ok
- }
- {
- auto L = [](auto *a) ->decltype (a->foo()) { //expected-note2{{candidate template ignored:}}
- return (*a)(a); };
- double d;
- L(&d); //expected-error{{no matching function for call}}
- auto M = [](auto b) { return b; };
- L(&M); //expected-error{{no matching function for call}}
-
- }
- return 0;
-}
-
-
-}
-
-namespace test_misc {
-auto GL = [](auto a, decltype(a) b) //expected-note{{candidate function}}
- -> int { return a + b; };
-
-void test() {
- struct X { };
- GL(3, X{}); //expected-error{{no matching function}}
-}
-
-void test2() {
- auto l = [](auto *a) -> int {
- (*a)(a); return 0; }; //expected-error{{called object type 'double' is not a function}}
- l(&l);
- double d;
- l(&d); //expected-note{{in instantiation of}}
-}
-
-}
-
-namespace nested_lambdas {
- int test() {
- auto L = [](auto a) {
- return [=](auto b) {
- return a + b;
- };
- };
- }
- auto get_lambda() {
- return [](auto a) {
- return a;
- };
- };
-
- int test2() {
- auto L = get_lambda();
- L(3);
- }
-}
-
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y + +namespace test_factorial { + +auto Fact = [](auto Self, unsigned n) -> unsigned { + return !n ? 1 : Self(Self, n - 1) * n; +}; + +auto six = Fact(Fact, 3); + +} + +namespace overload_generic_lambda { + template <class F1, class F2> struct overload : F1, F2 { + using F1::operator(); + using F2::operator(); + overload(F1 f1, F2 f2) : F1(f1), F2(f2) { } + }; + + auto NumParams = [](auto Self, auto h, auto ... rest) -> unsigned { + return 1 + Self(Self, rest...); + }; + auto Base = [](auto Self, auto h) -> unsigned { + return 1; + }; + overload<decltype(Base), decltype(NumParams)> O(Base, NumParams); + int num_params = O(O, 5, 3, "abc", 3.14, 'a'); +} + + +namespace overload_generic_lambda_return_type_deduction { + template <class F1, class F2> struct overload : F1, F2 { + using F1::operator(); + using F2::operator(); + overload(F1 f1, F2 f2) : F1(f1), F2(f2) { } + }; + + auto NumParams = [](auto Self, auto h, auto ... rest) { + return 1 + Self(Self, rest...); + }; + auto Base = [](auto Self, auto h) { + return 1; + }; + overload<decltype(Base), decltype(NumParams)> O(Base, NumParams); + int num_params = O(O, 5, 3, "abc", 3.14, 'a'); +} + +namespace test_standard_p5 { +// FIXME: This test should eventually compile without an explicit trailing return type +auto glambda = [](auto a, auto&& b) ->bool { return a < b; }; +bool b = glambda(3, 3.14); // OK + +} +namespace test_deduction_failure { + int test() { + auto g = [](auto *a) { //expected-note{{candidate template ignored}} + return a; + }; + struct X { }; + X *x; + g(x); + g(3); //expected-error{{no matching function}} + return 0; + } + +} + +namespace test_instantiation_or_sfinae_failure { +int test2() { + { + auto L = [](auto *a) { + return (*a)(a); }; //expected-error{{called object type 'double' is not a function}} + double d; + L(&d); //expected-note{{in instantiation of}} + auto M = [](auto b) { return b; }; + L(&M); // ok + } + { + auto L = [](auto *a) ->decltype (a->foo()) { //expected-note2{{candidate template ignored:}} + return (*a)(a); }; + double d; + L(&d); //expected-error{{no matching function for call}} + auto M = [](auto b) { return b; }; + L(&M); //expected-error{{no matching function for call}} + + } + return 0; +} + + +} + +namespace test_misc { +auto GL = [](auto a, decltype(a) b) //expected-note{{candidate function}} + -> int { return a + b; }; + +void test() { + struct X { }; + GL(3, X{}); //expected-error{{no matching function}} +} + +void test2() { + auto l = [](auto *a) -> int { + (*a)(a); return 0; }; //expected-error{{called object type 'double' is not a function}} + l(&l); + double d; + l(&d); //expected-note{{in instantiation of}} +} + +} + +namespace nested_lambdas { + int test() { + auto L = [](auto a) { + return [=](auto b) { + return a + b; + }; + }; + } + auto get_lambda() { + return [](auto a) { + return a; + }; + }; + + int test2() { + auto L = get_lambda(); + L(3); + } +} + diff --git a/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp b/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp index 2e99b525b4431..7305bd1f53e29 100644 --- a/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp +++ b/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp @@ -13,6 +13,8 @@ void f() { new auto; // expected-error{{new expression for type 'auto' requires a constructor argument}} new (const auto)(); // expected-error{{new expression for type 'const auto' requires a constructor argument}} new (auto) (1,2,3); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}} + new auto {1,2,3}; // expected-error{{new expression for type 'auto' cannot use list-initialization}} + new auto ({1,2,3}); // expected-error{{new expression for type 'auto' cannot use list-initialization}} } void p2example() { diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp index cd55cc2441a23..9babf8728cc06 100644 --- a/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp +++ b/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp @@ -7,7 +7,7 @@ namespace test0 { template<typename T> void g(T); void test() { - foo(&g<int>); // expected-error {{can't form member pointer of type 'void (test0::A::*)(int)' without '&' and class name}} + foo(&g<int>); // expected-error-re {{can't form member pointer of type 'void (test0::A::*)(int){{( __attribute__\(\(thiscall\)\))?}}' without '&' and class name}} } }; } diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp index 2646264273ebe..833a4014e8686 100644 --- a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp +++ b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp @@ -15,7 +15,7 @@ bool b4 = !E; bool b5 = !F; // -- pointer, -bool b6 = !&b4; +bool b6 = !&b4; // expected-warning{{address of 'b4' will always evaluate to 'true'}} void f(); bool b61 = !&f; diff --git a/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp b/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp index 35f8808fff88c..d88d5beb4e99e 100644 --- a/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp +++ b/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp @@ -1,5 +1,27 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -// expected-no-diagnostics + +namespace bullet2 { + +// For non-member candidates, if no operand has a class type, only those +// non-member functions that have a matching enumeration parameter are +// candidates. + +struct B { template<typename T> B(T); }; +int operator~(B); +template<typename T> int operator%(B, T); +enum class E { e }; + +template<typename T> int f(T t) { return ~t; } // expected-error {{invalid argument type}} +template<typename T, typename U> int f(T t, U u) { return t % u; } // expected-error {{invalid operands to}} + +int b1 = ~E::e; // expected-error {{invalid argument type}} +int b2 = f(E::e); // expected-note {{in instantiation of}} +int b3 = f(0, E::e); +int b4 = f(E::e, 0); // expected-note {{in instantiation of}} + +} + +namespace bullet3 { // This is specifically testing the bullet: // "do not have the same parameter-type-list as any non-template @@ -26,4 +48,6 @@ extern bool test2; extern decltype(a <= a) test2; extern A test3; -extern decltype(a <= b) test3;
\ No newline at end of file +extern decltype(a <= b) test3; + +} diff --git a/test/CXX/special/class.copy/implicit-move-def.cpp b/test/CXX/special/class.copy/implicit-move-def.cpp index 5696d1f57982a..880268d55ac49 100644 --- a/test/CXX/special/class.copy/implicit-move-def.cpp +++ b/test/CXX/special/class.copy/implicit-move-def.cpp @@ -1,6 +1,6 @@ -// FIXME: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK %s -// RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-ASSIGN %s -// RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-CTOR %s +// FIXME: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - -std=c++11 %s | FileCheck -check-prefix=CHECK %s +// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-ASSIGN %s +// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-CTOR %s // construct diff --git a/test/CXX/special/class.copy/implicit-move.cpp b/test/CXX/special/class.copy/implicit-move.cpp index 23ecf2e7d95ab..a10d139fe3cd9 100644 --- a/test/CXX/special/class.copy/implicit-move.cpp +++ b/test/CXX/special/class.copy/implicit-move.cpp @@ -258,8 +258,8 @@ namespace DR1402 { template<typename T> struct F : - E<T, 0>, // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}} - E<T, 1> {}; // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}} + E<T, 0>, // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}} + E<T, 1> {}; // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}} template<typename T> struct G : E<T, 0, true>, E<T, 0> {}; @@ -272,11 +272,11 @@ namespace DR1402 { template<typename T> struct J : - E<T, 0>, // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}} - virtual T {}; // expected-note-re 2{{virtual base class '[BD]' declared here}} + E<T, 0>, // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}} + virtual T {}; // expected-note-re 2{{virtual base class '{{[BD]}}' declared here}} template<typename T> void move(T t) { t = static_cast<T&&>(t); } - // expected-warning-re@-1 4{{defaulted move assignment operator of .* will move assign virtual base class '[BD]' multiple times}} + // expected-warning-re@-1 4{{defaulted move assignment operator of {{.*}} will move assign virtual base class '{{[BD]}}' multiple times}} template void move(F<A>); template void move(F<B>); // expected-note {{in instantiation of}} template void move(F<C>); diff --git a/test/CXX/special/class.copy/p11.0x.copy.cpp b/test/CXX/special/class.copy/p11.0x.copy.cpp index a334c50e9fdae..1ca0143d0930f 100644 --- a/test/CXX/special/class.copy/p11.0x.copy.cpp +++ b/test/CXX/special/class.copy/p11.0x.copy.cpp @@ -139,3 +139,22 @@ namespace PR13381 { T &f(); T t = f(); // expected-error{{call to implicitly-deleted copy constructor}} } + +namespace Mutable { + struct A { + A(const A &); + A(A &) = delete; // expected-note {{deleted here}} + }; + + struct B { + A a; + B(const B &); + }; + B::B(const B &) = default; + + struct C { + mutable A a; // expected-note {{deleted because field 'a' has a deleted copy constructor}} + C(const C &); + }; + C::C(const C &) = default; // expected-error{{would delete}} +} diff --git a/test/CXX/special/class.copy/p11.0x.move.cpp b/test/CXX/special/class.copy/p11.0x.move.cpp index 1dce27a832901..514817d2b71c7 100644 --- a/test/CXX/special/class.copy/p11.0x.move.cpp +++ b/test/CXX/special/class.copy/p11.0x.move.cpp @@ -2,21 +2,21 @@ struct Trivial {}; struct NonTrivial { - NonTrivial(NonTrivial&&); + NonTrivial(NonTrivial&&); // expected-note{{copy constructor is implicitly deleted}} }; // A defaulted move constructor for a class X is defined as deleted if X has: // -- a variant member with a non-trivial corresponding constructor union DeletedNTVariant { - NonTrivial NT; + NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}} DeletedNTVariant(DeletedNTVariant&&); }; DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}} struct DeletedNTVariant2 { union { - NonTrivial NT; + NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}} }; DeletedNTVariant2(DeletedNTVariant2&&); }; @@ -34,7 +34,7 @@ private: }; struct HasNoAccess { - NoAccess NA; + NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}} HasNoAccess(HasNoAccess&&); }; HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}} @@ -51,13 +51,16 @@ struct Ambiguity { }; struct IsAmbiguous { - Ambiguity A; - IsAmbiguous(IsAmbiguous&&); + Ambiguity A; // expected-note{{deleted because field 'A' has multiple move constructors}} + IsAmbiguous(IsAmbiguous&&); // expected-note{{copy constructor is implicitly deleted because 'IsAmbiguous' has a user-declared move constructor}} }; IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}} struct Deleted { - IsAmbiguous IA; + // FIXME: This diagnostic is slightly wrong: the constructor we select to move + // 'IA' is deleted, but we select the copy constructor (we ignore the move + // constructor, because it was defaulted and deleted). + IsAmbiguous IA; // expected-note{{deleted because field 'IA' has a deleted move constructor}} Deleted(Deleted&&); }; Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}} @@ -70,12 +73,15 @@ struct ConstMember { }; ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor struct ConstMoveOnlyMember { - const NonTrivial cnt; + // FIXME: This diagnostic is slightly wrong: the constructor we select to move + // 'cnt' is deleted, but we select the copy constructor, because the object is + // const. + const NonTrivial cnt; // expected-note{{deleted because field 'cnt' has a deleted move constructor}} ConstMoveOnlyMember(ConstMoveOnlyMember&&); }; ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}} struct VolatileMember { - volatile Trivial vt; + volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}} VolatileMember(VolatileMember&&); }; VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}} @@ -83,17 +89,17 @@ VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{w // -- a direct or virtual base class B that cannot be moved because overload // resolution results in an ambiguity or a function that is deleted or // inaccessible -struct AmbiguousMoveBase : Ambiguity { - AmbiguousMoveBase(AmbiguousMoveBase&&); +struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}} + AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}} }; AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}} -struct DeletedMoveBase : AmbiguousMoveBase { +struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}} DeletedMoveBase(DeletedMoveBase&&); }; DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}} -struct InaccessibleMoveBase : NoAccess { +struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}} InaccessibleMoveBase(InaccessibleMoveBase&&); }; InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}} @@ -108,7 +114,7 @@ private: }; struct HasNoAccessDtor { - NoAccessDtor NAD; + NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}} HasNoAccessDtor(HasNoAccessDtor&&); }; HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}} diff --git a/test/CXX/special/class.copy/p13-0x.cpp b/test/CXX/special/class.copy/p13-0x.cpp index 5d436016a056f..16c8a4029cbac 100644 --- a/test/CXX/special/class.copy/p13-0x.cpp +++ b/test/CXX/special/class.copy/p13-0x.cpp @@ -114,3 +114,18 @@ namespace PR13052 { friend constexpr S<W>::S(const S<W>&) noexcept; }; } + +namespace Mutable { + struct A { + constexpr A(A &); + A(const A &); + }; + struct B { + constexpr B(const B &) = default; // ok + mutable A a; + }; + struct C { + constexpr C(const C &) = default; // expected-error {{not constexpr}} + A a; + }; +} diff --git a/test/CXX/special/class.copy/p23-cxx11.cpp b/test/CXX/special/class.copy/p23-cxx11.cpp index de071f050f016..ac21cc61a2c55 100644 --- a/test/CXX/special/class.copy/p23-cxx11.cpp +++ b/test/CXX/special/class.copy/p23-cxx11.cpp @@ -30,8 +30,8 @@ struct NonTrivialMoveAssign { NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&); }; struct AmbiguousCopyAssign { - AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &); - AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &); + AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) volatile; + AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) const; }; struct AmbiguousMoveAssign { AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&); @@ -174,3 +174,18 @@ namespace PR13381 { t = T(); // expected-error{{object of type 'PR13381::T' cannot be assigned because its copy assignment operator is implicitly deleted}} } } + +namespace Mutable { + struct AmbiguousCopyAssign { + AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &); + AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &); + }; + struct X { + AmbiguousCopyAssign a; + }; + struct Y { + mutable AmbiguousCopyAssign a; // expected-note {{multiple copy assignment operators}} + }; +} +template struct CopyAssign<Mutable::X>; +template struct CopyAssign<Mutable::Y>; // expected-note {{here}} diff --git a/test/CXX/special/class.copy/p33-0x.cpp b/test/CXX/special/class.copy/p33-0x.cpp index b66e19ab4c4f9..28cd4f33a8aa6 100644 --- a/test/CXX/special/class.copy/p33-0x.cpp +++ b/test/CXX/special/class.copy/p33-0x.cpp @@ -27,7 +27,7 @@ namespace PR10142 { struct X { X(); X(X&&); - X(const X&) = delete; // expected-note 2{{function has been explicitly marked deleted here}} + X(const X&) = delete; // expected-note 2{{'X' has been explicitly marked deleted here}} }; void f(int i) { diff --git a/test/CXX/special/class.dtor/p10-0x.cpp b/test/CXX/special/class.dtor/p10-0x.cpp index e10afb52e2b4b..029cbd6cebb5c 100644 --- a/test/CXX/special/class.dtor/p10-0x.cpp +++ b/test/CXX/special/class.dtor/p10-0x.cpp @@ -7,7 +7,7 @@ template<typename T> void b(const T *x, const A *y) { x->~decltype(T())(); x->~decltype(*x)(); // expected-error{{the type of object expression ('const int') does not match the type being destroyed ('decltype(*x)' (aka 'const int &')) in pseudo-destructor expression}} \ - expected-error{{no member named '~const struct A &' in 'A'}} + expected-error{{no member named '~const A &' in 'A'}} x->~decltype(int())(); // expected-error{{no member named '~int' in 'A'}} y->~decltype(*y)(); // expected-error{{destructor type 'decltype(*y)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}} diff --git a/test/CXX/special/class.dtor/p3-0x.cpp b/test/CXX/special/class.dtor/p3-0x.cpp index dc76e00308209..2d7eba490bc8e 100644 --- a/test/CXX/special/class.dtor/p3-0x.cpp +++ b/test/CXX/special/class.dtor/p3-0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s struct A { ~A(); diff --git a/test/CXX/special/class.dtor/p9.cpp b/test/CXX/special/class.dtor/p9.cpp index 8b76a15078b76..a03fcdb24952b 100644 --- a/test/CXX/special/class.dtor/p9.cpp +++ b/test/CXX/special/class.dtor/p9.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s +// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %s typedef typeof(sizeof(int)) size_t; @@ -74,7 +75,13 @@ namespace test2 { // PR7346 namespace test3 { struct A { +#ifdef MSABI + // expected-error@+2 {{no suitable member 'operator delete' in 'A'}} +#endif virtual ~A(); +#ifdef MSABI + // expected-note@+2 {{declared here}} +#endif static void operator delete(void*, const int &); }; diff --git a/test/CXX/special/class.inhctor/elsewhere.cpp b/test/CXX/special/class.inhctor/elsewhere.cpp index b986f65824950..c042834b2147b 100644 --- a/test/CXX/special/class.inhctor/elsewhere.cpp +++ b/test/CXX/special/class.inhctor/elsewhere.cpp @@ -9,7 +9,7 @@ struct B1 { B1(int); }; -using B1::B1; // expected-error {{using declaration can not refer to class member}} +using B1::B1; // expected-error {{using declaration cannot refer to class member}} // C++11 [namespace.udecl]p10: // A using-declaration is a declaration and can therefore be used repeatedly @@ -27,7 +27,7 @@ struct I1 : B1 { // shall name a direct base class of the class being defined. struct D1 : I1 { - using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}} + using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', cannot inherit constructors}} }; template<typename T> struct A {}; @@ -47,7 +47,7 @@ C<char> cc; // expected-note {{here}} template<typename T> struct D : A<T> {}; template<typename T> struct E : D<T> { - using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}} + using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', cannot inherit}} }; E<bool> eb; // expected-note {{here}} diff --git a/test/CXX/special/class.inhctor/p4.cpp b/test/CXX/special/class.inhctor/p4.cpp index 356cdef687fb8..ae1f7a57031f1 100644 --- a/test/CXX/special/class.inhctor/p4.cpp +++ b/test/CXX/special/class.inhctor/p4.cpp @@ -43,8 +43,8 @@ FA fa2{X<2>{}}; // expected-error {{calling a private constructor}} // It is deleted if the corresponding constructor [...] is deleted. struct G { - G(int) = delete; // expected-note {{function has been explicitly marked deleted here}} - template<typename T> G(T*) = delete; // expected-note {{function has been explicitly marked deleted here}} + G(int) = delete; // expected-note {{'G' has been explicitly marked deleted here}} + template<typename T> G(T*) = delete; // expected-note {{'G<const char>' has been explicitly marked deleted here}} }; struct H : G { using G::G; // expected-note 2{{deleted constructor was inherited here}} diff --git a/test/CXX/special/class.init/class.base.init/p8-0x.cpp b/test/CXX/special/class.init/class.base.init/p8-0x.cpp index a108533beddb1..45755caa8ecb2 100644 --- a/test/CXX/special/class.init/class.base.init/p8-0x.cpp +++ b/test/CXX/special/class.init/class.base.init/p8-0x.cpp @@ -16,16 +16,13 @@ struct S { } s(0); union U { - int a = 0; // desired-note 5 {{previous initialization is here}} - char b = 'x'; + int a = 0; // expected-note {{previous initialization}} + char b = 'x'; // expected-error {{initializing multiple members of union}} - // FIXME: these should all be rejected - U() {} // desired-error {{initializing multiple members of union}} - U(int) : a(1) {} // desired-error {{initializing multiple members of union}} - U(char) : b('y') {} // desired-error {{initializing multiple members of union}} - // this expected note should be removed & the note should appear on the - // declaration of 'a' when this set of cases is handled correctly. - U(double) : a(1), // expected-note{{previous initialization is here}} desired-error {{initializing multiple members of union}} + U() {} + U(int) : a(1) {} + U(char) : b('y') {} + U(double) : a(1), // expected-note{{previous initialization is here}} b('y') {} // expected-error{{initializing multiple members of union}} }; diff --git a/test/CXX/special/class.temporary/p1.cpp b/test/CXX/special/class.temporary/p1.cpp index 4f6ac0a0029ed..75a56df1e9c32 100644 --- a/test/CXX/special/class.temporary/p1.cpp +++ b/test/CXX/special/class.temporary/p1.cpp @@ -6,7 +6,7 @@ namespace test0 { int x; int y; - A(const A&) = delete; // expected-note {{function has been explicitly marked deleted here}} + A(const A&) = delete; // expected-note {{'A' has been explicitly marked deleted here}} }; void foo(...); diff --git a/test/CXX/temp/p3.cpp b/test/CXX/temp/p3.cpp index 11f72de918cb9..e9fd8a3090e86 100644 --- a/test/CXX/temp/p3.cpp +++ b/test/CXX/temp/p3.cpp @@ -8,7 +8,8 @@ template<typename T> int S<T>::a, S<T>::b; // expected-error {{can only declare template<typename T> struct A { static A a; } A<T>::a; // expected-error {{expected ';' after struct}} \ expected-error {{use of undeclared identifier 'T'}} \ - expected-error{{extra qualification}} + expected-error {{no member named 'a'}} \ + expected-warning {{extra qualification}} template<typename T> struct B { } f(); // expected-error {{expected ';' after struct}} \ expected-error {{requires a type specifier}} diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp index 9b9b532ff1344..e87153b9efe2e 100644 --- a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp +++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp @@ -184,7 +184,7 @@ namespace pointer_to_member_function { template<int (Y::*)(int)> struct X0 {}; // expected-note{{template parameter is declared here}} X0<&Y::f> x0a; X0<&Y::g> x0b; - X0<&Y::h> x0c; // expected-error{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float)' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int)'}} + X0<&Y::h> x0c; // expected-error-re{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float){{( __attribute__\(\(thiscall\)\))?}}' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}} } // -- For a non-type template-parameter of type pointer to data member, diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp index a49db5166a459..2651f9942091a 100644 --- a/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp +++ b/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp @@ -21,10 +21,10 @@ template<template<typename> class...X> int v4<X...>; template<typename Outer> struct X { template<typename Inner> static int y; - template<typename Inner> static int y<Outer>; // expected-warning {{can not be deduced}} expected-note {{'Inner'}} + template<typename Inner> static int y<Outer>; // expected-warning {{cannot be deduced}} expected-note {{'Inner'}} template<typename Inner> static int y<Inner>; // expected-error {{does not specialize}} }; -template<typename Outer> template<typename Inner> int X<Outer>::y<Outer>; // expected-warning {{can not be deduced}} expected-note {{'Inner'}} +template<typename Outer> template<typename Inner> int X<Outer>::y<Outer>; // expected-warning {{cannot be deduced}} expected-note {{'Inner'}} template<typename Outer> template<typename Inner> int X<Outer>::y<Inner>; // expected-error {{does not specialize}} // FIXME: Merging this with the above class causes an assertion failure when diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp deleted file mode 100644 index 60c60cb0b28da..0000000000000 --- a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -// expected-no-diagnostics - -// Core DR 532. -namespace PR8130 { - struct A { }; - - template<class T> struct B { - template<class R> int &operator*(R&); - }; - - template<class T, class R> float &operator*(T&, R&); - void test() { - A a; - B<A> b; - int &ir = b * a; - } -} - -namespace OperatorWithRefQualifier { - struct A { }; - template<class T> struct B { - template<class R> int &operator*(R&) &&; - }; - - template<class T, class R> float &operator*(T&&, R&); - void test() { - A a; - B<A> b; - float &ir = b * a; - int &ir2 = B<A>() * a; - } -} - -namespace OrderWithStaticMember { - struct A { - template<class T> int g(T**, int=0) { return 0; } - template<class T> static int g(T*) { return 1; } - }; - void f() { - A a; - int **p; - a.g(p); - } -} - -namespace PR17075 { - template <typename T> struct V {}; - struct S { template<typename T> S &operator>>(T &t) = delete; }; - template<typename T> S &operator>>(S &s, V<T> &v); - void f(S s, V<int> v) { s >> v; } -} diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp index 8212a125be600..db3952a388c2c 100644 --- a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp +++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp @@ -1,21 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // expected-no-diagnostics -namespace DeduceVsMember { - template<typename T> - struct X { - template<typename U> - int &operator==(const U& other) const; - }; - - template<typename T, typename U> - float &operator==(const T&, const X<U>&); - - void test(X<int> xi, X<float> xf) { - float& ir = (xi == xf); - } -} - namespace OrderWithStaticMember { struct A { template<class T> int g(T**, int=0) { return 0; } @@ -27,3 +13,27 @@ namespace OrderWithStaticMember { a.g(p); } } + +#if __cplusplus >= 201103L +namespace OperatorWithRefQualifier { + struct A { }; + template<class T> struct B { + template<class R> int &operator*(R&) &&; + }; + + template<class T, class R> float &operator*(T&&, R&); + void test() { + A a; + B<A> b; + float &ir = b * a; + int &ir2 = B<A>() * a; + } +} + +namespace PR17075 { + template <typename T> struct V {}; + struct S { template<typename T> S &operator>>(T &t) = delete; }; + template<typename T> S &operator>>(S &s, V<T> &v); + void f(S s, V<int> v) { s >> v; } +} +#endif diff --git a/test/CXX/temp/temp.decls/temp.mem/p3.cpp b/test/CXX/temp/temp.decls/temp.mem/p3.cpp index 0eb747be207d0..7e13f2a58ba0e 100644 --- a/test/CXX/temp/temp.decls/temp.mem/p3.cpp +++ b/test/CXX/temp/temp.decls/temp.mem/p3.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s template <class T> struct AA { - template <class C> virtual void g(C); // expected-error{{'virtual' can not be specified on member function templates}} + template <class C> virtual void g(C); // expected-error{{'virtual' cannot be specified on member function templates}} virtual void f(); }; diff --git a/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp b/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp index fb727543efa5b..a466be0a61de9 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp @@ -121,7 +121,16 @@ namespace PartialSpecialization { namespace FixedAliasTemplate { template<typename,typename,typename> struct S {}; - template<typename T, typename U> using U = S<T, int, U>; - template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...); - S<int, int, double> &s1 = f({}, 0, 0.0); + template<typename T, typename U> using U = S<T, int, U>; // expected-note 2{{template parameter is declared here}} + template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}} + S<int, int, double> &s1 = f({}, 0, 0.0); // expected-error {{no matching function}} +} + +namespace PR18401 { + template<typename... Args> struct foo { }; + template<typename T, typename... Args> using bar = foo<T, Args...>; // expected-note 2{{template parameter is declared here}} expected-note {{'bar' declared here}} + template<typename T, typename... Args> using baz = bar<Args..., T>; // expected-error {{pack expansion used as argument for non-pack parameter of alias template}} + // FIXME: We should still record the alias template, but mark it as invalid. + template<typename...T> void f(baz<T...>); // expected-error {{no template named 'baz'; did you mean 'bar'}} expected-error {{pack expansion used as argument for non-pack}} + void g() { f(foo<int, char, double>()); } // expected-error {{no matching function}} } diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp index 3681d7757e943..dae6865666916 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp @@ -310,10 +310,10 @@ void test_unexpanded_exprs(Types ...values) { t.~Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}} t.Types::~T(); // expected-error{{expression contains unexpanded parameter pack 'Types'}} - // UnaryTypeTraitExpr + // Unary TypeTraitExpr __is_pod(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}} - // BinaryTypeTraitExpr + // Binary TypeTraitExpr __is_base_of(Types, T); // expected-error{{expression contains unexpanded parameter pack 'Types'}} __is_base_of(T, Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}} diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp index d7989e305f025..782057d397b93 100644 --- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp @@ -32,7 +32,7 @@ namespace PackExpansionNotAtEnd { template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}} typename Tail> // expected-note{{non-deducible template parameter 'Tail'}} - struct UselessPartialSpec<Types..., Tail>; // expected-warning{{class template partial specialization contains template parameters that can not be deduced; this partial specialization will never be used}} + struct UselessPartialSpec<Types..., Tail>; // expected-warning{{class template partial specialization contains template parameters that cannot be deduced; this partial specialization will never be used}} } namespace DeduceNonTypeTemplateArgsInArray { diff --git a/test/CXX/temp/temp.param/p14.cpp b/test/CXX/temp/temp.param/p14.cpp deleted file mode 100644 index a6c53c1e64a61..0000000000000 --- a/test/CXX/temp/temp.param/p14.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -// XFAIL: * - -// A template-parameter shall not be used in its own default argument. -template<typename T = typename T::type> struct X; // expected-error{{default}} diff --git a/test/CXX/temp/temp.res/temp.local/p3.cpp b/test/CXX/temp/temp.res/temp.local/p3.cpp index 54da8856fe460..e29ced19bc4f5 100644 --- a/test/CXX/temp/temp.res/temp.local/p3.cpp +++ b/test/CXX/temp/temp.res/temp.local/p3.cpp @@ -15,7 +15,7 @@ template <class T> struct Derived: Base<int>, Base<char> { t->Base<T>::f(); t->Base::f(); // expected-error{{member 'Base' found in multiple base classes of different types}} \ // expected-error{{no member named 'f' in 'X0'}} \ - // expected-error{{expected a class or namespace}} + // expected-error{{'Base' is not a class, namespace, or scoped enumeration}} } }; diff --git a/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp b/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp index 93f8ff1697bff..7eb5e3744d189 100644 --- a/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp +++ b/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp @@ -24,14 +24,14 @@ template int pi0 = 10; // expected-error {{variable cannot be defined in an expl #endif template<typename T> -T pi1 = T(3.1415926535897932385); +T pi1 = T(3.1415926535897932385); // expected-note 0-2 {{here}} // Should recover as if specialization template float pi1<float> = 1.0; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} #ifndef FIXING namespace expected_global { - template<> double pi1<double> = 1.5; // expected-error {{no variable template matches specialization}} + template<> double pi1<double> = 1.5; // expected-error {{variable template specialization of 'pi1' must originally be declared in the global scope}} template int pi1<int> = 10; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \ - expected-error {{no variable template matches specialization}} + expected-error {{variable template specialization of 'pi1' must originally be declared in the global scope}} } #endif diff --git a/test/CXX/temp/temp.spec/no-body.cpp b/test/CXX/temp/temp.spec/no-body.cpp index a4d7914d9eb6d..61d285b27ed28 100644 --- a/test/CXX/temp/temp.spec/no-body.cpp +++ b/test/CXX/temp/temp.spec/no-body.cpp @@ -37,7 +37,7 @@ namespace noargs_body { namespace exp_spec { #ifndef FIXING template<> void f0<int>(int) { } // expected-error {{no function template matches function template specialization 'f0'}} - template<> struct x0<int> { }; // expected-error {{class template specialization of 'x0' must originally be declared in the global scope}} + template<> struct x0<int> { }; // expected-error {{class template specialization of 'x0' must occur at global scope}} #endif } @@ -51,7 +51,7 @@ namespace args_bad { template void f1<int>(int) { } // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \ expected-error {{no function template matches function template specialization 'f1'}} template struct x1<int> { }; // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \ - expected-error {{class template specialization of 'x1' must originally be declared in the global scope}} + expected-error {{class template specialization of 'x1' must occur at global scope}} #endif } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp index 75b198e47d13c..d0e24f5477232 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -Wno-c++1y-extensions // This test creates cases where implicit instantiations of various entities // would cause a diagnostic, but provides expliict specializations for those @@ -10,6 +10,8 @@ struct NonDefaultConstructible { NonDefaultConstructible(int); }; +// FIXME: The "must originally be declared in namespace" diagnostics throughout +// this file are wrong. // C++ [temp.expl.spec]p1: // An explicit specialization of any of the following: @@ -79,7 +81,7 @@ template<> struct N0::X0<void> { }; N0::X0<void> test_X0; namespace N1 { - template<> struct N0::X0<const void> { }; // expected-error{{class template specialization of 'X0' must originally be declared in namespace 'N0'}} + template<> struct N0::X0<const void> { }; // expected-error{{class template specialization of 'X0' not in a namespace enclosing 'N0'}} } namespace N0 { @@ -90,6 +92,44 @@ template<> struct N0::X0<volatile void> { void f1(void *); }; +// -- variable template [C++1y] +namespace N0 { +template<typename T> int v0; // expected-note +{{here}} +template<> extern int v0<char[1]>; +template<> extern int v0<char[2]>; +template<> extern int v0<char[5]>; +template<> extern int v0<char[6]>; +} +using N0::v0; + +template<typename T> int v1; // expected-note +{{here}} +template<> extern int v1<char[3]>; +template<> extern int v1<char[4]>; +template<> extern int v1<char[7]>; +template<> extern int v1<char[8]>; + +template<> int N0::v0<int[1]>; +template<> int v0<int[2]>; // FIXME: ill-formed +template<> int ::v1<int[3]>; // expected-warning {{extra qualification}} +template<> int v1<int[4]>; + +template<> int N0::v0<char[1]>; +template<> int v0<char[2]>; // FIXME: ill-formed +template<> int ::v1<char[3]>; // expected-warning {{extra qualification}} +template<> int v1<char[4]>; + +namespace N1 { +template<> int N0::v0<int[5]>; // expected-error {{must originally be declared in namespace 'N0'}} expected-error {{does not enclose namespace}} +template<> int v0<int[6]>; // expected-error {{must originally be declared in namespace 'N0'}} +template<> int ::v1<int[7]>; // expected-error {{must originally be declared in the global scope}} expected-error {{cannot name the global scope}} +template<> int v1<int[8]>; // expected-error {{must originally be declared in the global scope}} + +template<> int N0::v0<char[5]>; // expected-error {{does not enclose namespace 'N0'}} +template<> int v0<char[6]>; // FIXME: ill-formed +template<> int ::v1<char[7]>; // expected-error {{cannot name the global scope}} +template<> int v1<char[8]>; // FIXME: ill-formed +} + // -- member function of a class template template<> void N0::X0<void*>::f1(void *) { } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp index c972bf7c7d0aa..4fbc45a7d7dd5 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp @@ -80,7 +80,7 @@ template<> struct N0::X0<void> { }; // expected-warning{{C++11 extension}} N0::X0<void> test_X0; namespace N1 { - template<> struct N0::X0<const void> { }; // expected-error{{originally}} + template<> struct N0::X0<const void> { }; // expected-error{{not in a namespace enclosing 'N0'}} } namespace N0 { diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp index d0df305941d96..24f68a094e542 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp @@ -20,8 +20,8 @@ template int X<int>::member2; // For implicit instantiation of long& get(bool Cond1, bool Cond2) { - // CHECK: @_ZN1XIlE7member1E = weak_odr global i64 0 - // CHECK: @_ZN1XIlE7member2E = weak_odr global i64 17 + // CHECK: @_ZN1XIlE7member1E = linkonce_odr global i64 0 + // CHECK: @_ZN1XIlE7member2E = linkonce_odr global i64 17 // CHECK: @_ZN1XIlE7member3E = external global i64 return Cond1? X<long>::member1 : Cond2? X<long>::member2 |