} else if (Constructor->isMoveConstructor())
SMKind |= SMF_MoveConstructor;
}
+
+ // C++ [dcl.init.aggr]p1:
+ // An aggregate is an array or a class with no user-declared
+ // constructors [...].
+ // C++11 [dcl.init.aggr]p1: DR1518
+ // An aggregate is an array or a class with no user-provided, explicit, or
+ // inherited constructors
+ if (getASTContext().getLangOpts().CPlusPlus11
+ ? (Constructor->isUserProvided() || Constructor->isExplicit())
+ : !Constructor->isImplicit())
+ data().Aggregate = false;
}
// Handle constructors, including those inherited from base classes.
// constructor [...]
if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor())
data().HasConstexprNonCopyMoveConstructor = true;
-
- // C++ [dcl.init.aggr]p1:
- // An aggregate is an array or a class with no user-declared
- // constructors [...].
- // C++11 [dcl.init.aggr]p1:
- // An aggregate is an array or a class with no user-provided
- // constructors [...].
- // C++11 [dcl.init.aggr]p1:
- // An aggregate is an array or a class with no user-provided
- // constructors (including those inherited from a base class) [...].
- if (getASTContext().getLangOpts().CPlusPlus11
- ? Constructor->isUserProvided()
- : !Constructor->isImplicit())
- data().Aggregate = false;
}
// Handle destructors.
if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
if (Using->getDeclName().getNameKind() ==
- DeclarationName::CXXConstructorName)
+ DeclarationName::CXXConstructorName) {
data().HasInheritedConstructor = true;
+ // C++1z [dcl.init.aggr]p1:
+ // An aggregate is [...] a class [...] with no inherited constructors
+ data().Aggregate = false;
+ }
if (Using->getDeclName().getCXXOverloadedOperator() == OO_Equal)
data().HasInheritedAssignment = true;
~DefaultedAggr() = default;
};
DefaultedAggr da = { 42 } ;
+
+struct ExplicitDefaultedAggr {
+ int n;
+ explicit ExplicitDefaultedAggr() = default; // expected-note {{candidate}}
+ ExplicitDefaultedAggr(const ExplicitDefaultedAggr &) = default; // expected-note {{candidate}}
+ ExplicitDefaultedAggr(ExplicitDefaultedAggr &&) = default; // expected-note {{candidate}}
+};
+ExplicitDefaultedAggr eda = { 42 }; // expected-error {{no matching constructor}}
+ExplicitDefaultedAggr eda2{};
+
+struct DefaultedBase {
+ int n;
+ DefaultedBase() = default; // expected-note 0+ {{candidate}}
+ DefaultedBase(DefaultedBase const&) = default; // expected-note 0+ {{candidate}}
+ DefaultedBase(DefaultedBase &&) = default; // expected-note 0+ {{candidate}}
+};
+
+struct InheritingConstructors : DefaultedBase { // expected-note 3 {{candidate}}
+ using DefaultedBase::DefaultedBase; // expected-note 2 {{inherited here}}
+};
+InheritingConstructors ic = { 42 }; // expected-error {{no matching constructor}}
+
+struct NonInheritingConstructors : DefaultedBase {}; // expected-note 0+ {{candidate}}
+NonInheritingConstructors nic = { 42 };
+#if __cplusplus <= 201402L
+// expected-error@-2 {{no matching constructor}}
+#endif
+
+struct NonAggrBase {
+ NonAggrBase(int) {}
+};
+struct HasNonAggrBase : NonAggrBase {}; // expected-note 0+ {{candidate}}
+HasNonAggrBase hnab = {42};
+#if __cplusplus <= 201402L
+// expected-error@-2 {{no matching constructor}}
+#endif
explicit B() = default; // expected-note {{here}}
};
B b = {}; // expected-error {{chosen constructor is explicit}}
+B b2{};
+B b3;
}
}
+namespace dr1518 { // dr1518: 4.0
+#if __cplusplus >= 201103L
+struct Z0 { // expected-note 0+ {{candidate}}
+ explicit Z0() = default; // expected-note 0+ {{here}}
+};
+struct Z { // expected-note 0+ {{candidate}}
+ explicit Z(); // expected-note 0+ {{here}}
+ explicit Z(int);
+ explicit Z(int, int); // expected-note 0+ {{here}}
+};
+template <class T> int Eat(T); // expected-note 0+ {{candidate}}
+Z0 a;
+Z0 b{};
+Z0 c = {}; // expected-error {{explicit in copy-initialization}}
+int i = Eat<Z0>({}); // expected-error {{no matching function for call to 'Eat'}}
+
+Z c2 = {}; // expected-error {{explicit in copy-initialization}}
+int i2 = Eat<Z>({}); // expected-error {{no matching function for call to 'Eat'}}
+Z a1 = 1; // expected-error {{no viable conversion}}
+Z a3 = Z(1);
+Z a2(1);
+Z *p = new Z(1);
+Z a4 = (Z)1;
+Z a5 = static_cast<Z>(1);
+Z a6 = {4, 3}; // expected-error {{explicit in copy-initialization}}
+
+struct UserProvidedBaseCtor { // expected-note 0+ {{candidate}}
+ UserProvidedBaseCtor() {}
+};
+struct DoesntInheritCtor : UserProvidedBaseCtor { // expected-note 0+ {{candidate}}
+ int x;
+};
+DoesntInheritCtor I{{}, 42};
+#if __cplusplus <= 201402L
+// expected-error@-2 {{no matching constructor}}
+#endif
+
+struct BaseCtor { BaseCtor() = default; }; // expected-note 0+ {{candidate}}
+struct InheritsCtor : BaseCtor { // expected-note 1+ {{candidate}}
+ using BaseCtor::BaseCtor; // expected-note 2 {{inherited here}}
+ int x;
+};
+InheritsCtor II = {{}, 42}; // expected-error {{no matching constructor}}
+
+#endif // __cplusplus >= 201103L
+}
+
namespace dr1550 { // dr1550: yes
int f(bool b, int n) {
return (b ? (throw 0) : n) + (b ? n : (throw 0));