// RUN: %clang_cc1 -std=c++1z -verify %s struct Noncopyable { Noncopyable(); Noncopyable(const Noncopyable &) = delete; // expected-note 1+{{deleted}} expected-note 1+ {{not viable}} virtual ~Noncopyable(); }; struct Derived : Noncopyable {}; struct NoncopyableAggr { // expected-note 3{{candidate}} Noncopyable nc; }; struct Indestructible { Indestructible(); ~Indestructible() = delete; // expected-note 1+{{deleted}} }; struct Incomplete; // expected-note 1+{{declar}} Noncopyable make(int kind = 0) { switch (kind) { case 0: return {}; case 1: return Noncopyable(); case 2: return Noncopyable{}; case 3: return make(); } __builtin_unreachable(); } Indestructible make_indestructible(); Incomplete make_incomplete(); // expected-note 1+{{here}} void take(Noncopyable nc) {} Noncopyable nrvo() { Noncopyable nrvo; return nrvo; // expected-error {{deleted constructor}} } Noncopyable nc1 = make(); Noncopyable nc2 = Noncopyable(); Noncopyable nc3 = Derived(); // expected-error {{deleted constructor}} Noncopyable nc4((Noncopyable())); Noncopyable nc5 = {Noncopyable()}; Noncopyable nc6{Noncopyable()}; NoncopyableAggr nca1 = NoncopyableAggr{}; NoncopyableAggr nca2 = NoncopyableAggr{{}}; NoncopyableAggr nca3 = NoncopyableAggr{NoncopyableAggr{Noncopyable()}}; template struct Convert { operator T(); }; // expected-note 1+{{candidate}} Noncopyable conv1 = Convert(); Noncopyable conv2((Convert())); Noncopyable conv3 = {Convert()}; Noncopyable conv4{Convert()}; Noncopyable ref_conv1 = Convert(); // expected-error {{deleted constructor}} Noncopyable ref_conv2((Convert())); // expected-error {{deleted constructor}} Noncopyable ref_conv3 = {Convert()}; // expected-error {{deleted constructor}} Noncopyable ref_conv4{Convert()}; // expected-error {{deleted constructor}} Noncopyable derived_conv1 = Convert(); // expected-error {{deleted constructor}} Noncopyable derived_conv2((Convert())); // expected-error {{deleted constructor}} Noncopyable derived_conv3 = {Convert()}; // expected-error {{deleted constructor}} Noncopyable derived_conv4{Convert()}; // expected-error {{deleted constructor}} NoncopyableAggr nc_aggr1 = Convert(); NoncopyableAggr nc_aggr2((Convert())); NoncopyableAggr nc_aggr3 = {Convert()}; // expected-error {{no viable conversion}} NoncopyableAggr nc_aggr4{Convert()}; // expected-error {{no viable conversion}} NoncopyableAggr nc_aggr5 = Convert(); // expected-error {{no viable}} NoncopyableAggr nc_aggr6((Convert())); // expected-error {{no matching constructor}} NoncopyableAggr nc_aggr7 = {Convert()}; NoncopyableAggr nc_aggr8{Convert()}; void test_expressions(bool b) { auto lambda = [a = make()] {}; take({}); take(Noncopyable()); take(Noncopyable{}); take(make()); Noncopyable &&dc1 = dynamic_cast(Noncopyable()); Noncopyable &&dc2 = dynamic_cast(nc1); Noncopyable &&dc3 = dynamic_cast(Derived()); Noncopyable sc1 = static_cast(Noncopyable()); Noncopyable sc2 = static_cast(nc1); // expected-error {{deleted}} Noncopyable sc3 = static_cast(Noncopyable()); // expected-error {{deleted}} Noncopyable sc4 = static_cast(static_cast(Noncopyable())); // expected-error {{deleted}} Noncopyable cc1 = (Noncopyable)Noncopyable(); Noncopyable cc2 = (Noncopyable)Derived(); // expected-error {{deleted}} Noncopyable fc1 = Noncopyable(Noncopyable()); Noncopyable fc2 = Noncopyable(Derived()); // expected-error {{deleted}} // We must check for a complete type for every materialized temporary. (Note // that in the special case of the top level of a decltype, no temporary is // materialized.) make_incomplete(); // expected-error {{incomplete}} make_incomplete().a; // expected-error {{incomplete}} make_incomplete().*(int Incomplete::*)nullptr; // expected-error {{incomplete}} dynamic_cast(make_incomplete()); // expected-error {{incomplete}} const_cast(make_incomplete()); // expected-error {{incomplete}} sizeof(Indestructible{}); // expected-error {{deleted}} sizeof(make_indestructible()); // expected-error {{deleted}} sizeof(make_incomplete()); // expected-error {{incomplete}} typeid(Indestructible{}); // expected-error {{deleted}} typeid(make_indestructible()); // expected-error {{deleted}} typeid(make_incomplete()); // expected-error {{incomplete}} // FIXME: The first two cases here are now also valid in C++17 onwards. using I = decltype(Indestructible()); // expected-error {{deleted}} using I = decltype(Indestructible{}); // expected-error {{deleted}} using I = decltype(make_indestructible()); using J = decltype(make_incomplete()); Noncopyable cond1 = b ? Noncopyable() : make(); Noncopyable cond2 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}} Noncopyable cond3 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}} Noncopyable cond4 = b ? Noncopyable() : nc1; // expected-error {{deleted}} Noncopyable cond5 = b ? nc1 : Noncopyable(); // expected-error {{deleted}} // Could convert both to an xvalue of type Noncopyable here, but we're not // permitted to consider that. Noncopyable &&cond6 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}} Noncopyable &&cond7 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}} // Could convert both to a const lvalue of type Noncopyable here, but we're // not permitted to consider that, either. const Noncopyable cnc; const Noncopyable &cond8 = b ? cnc : Derived(); // expected-error {{incompatible}} const Noncopyable &cond9 = b ? Derived() : cnc; // expected-error {{incompatible}} extern const volatile Noncopyable make_cv(); Noncopyable cv_difference1 = make_cv(); const volatile Noncopyable cv_difference2 = make(); } template struct ConversionFunction { operator T(); }; Noncopyable cf1 = ConversionFunction(); Noncopyable cf2 = ConversionFunction(); // expected-error {{deleted}} Noncopyable cf3 = ConversionFunction(); const volatile Noncopyable cf4 = ConversionFunction(); Noncopyable cf5 = ConversionFunction(); // expected-error {{deleted}} struct AsMember { Noncopyable member; AsMember() : member(make()) {} }; // FIXME: DR (no number yet): we still get a copy for base or delegating construction. struct AsBase : Noncopyable { AsBase() : Noncopyable(make()) {} // expected-error {{deleted}} }; struct AsDelegating final { AsDelegating(const AsDelegating &) = delete; // expected-note {{deleted}} static AsDelegating make(int); // The base constructor version of this is problematic; the complete object // version would be OK. Perhaps we could allow copy omission here for final // classes? AsDelegating(int n) : AsDelegating(make(n)) {} // expected-error {{deleted}} }; namespace CtorTemplateBeatsNonTemplateConversionFn { struct Foo { template Foo(const Derived &); }; template struct Base { operator Foo() const = delete; }; // expected-note {{deleted}} struct Derived : Base {}; Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}} Foo g(Derived d) { return Foo(d); } // ok, calls constructor }