tree convfn = cand->fn;
unsigned i;
- /* If we're initializing from {}, it's value-initialization. Note
- that under the resolution of core 1630, value-initialization can
- use explicit constructors. */
+ /* When converting from an init list we consider explicit
+ constructors, but actually trying to call one is an error. */
+ if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
+ /* Unless this is for direct-list-initialization. */
+ && !DIRECT_LIST_INIT_P (expr)
+ /* And in C++98 a default constructor can't be explicit. */
+ && cxx_dialect >= cxx11)
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+ location_t loc = location_of (expr);
+ if (CONSTRUCTOR_NELTS (expr) == 0
+ && FUNCTION_FIRST_USER_PARMTYPE (convfn) != void_list_node)
+ {
+ if (pedwarn (loc, 0, "converting to %qT from initializer list "
+ "would use explicit constructor %qD",
+ totype, convfn))
+ inform (loc, "in C++11 and above a default constructor "
+ "can be explicit");
+ }
+ else
+ error ("converting to %qT from initializer list would use "
+ "explicit constructor %qD", totype, convfn);
+ }
+
+ /* If we're initializing from {}, it's value-initialization. */
if (BRACE_ENCLOSED_INITIALIZER_P (expr)
&& CONSTRUCTOR_NELTS (expr) == 0
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
return expr;
}
- /* When converting from an init list we consider explicit
- constructors, but actually trying to call one is an error. */
- if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
- /* Unless this is for direct-list-initialization. */
- && !DIRECT_LIST_INIT_P (expr))
- {
- if (!(complain & tf_error))
- return error_mark_node;
- error ("converting to %qT from initializer list would use "
- "explicit constructor %qD", totype, convfn);
- }
-
expr = mark_rvalue_use (expr);
/* Set user_conv_p on the argument conversions, so rvalue/base
--- /dev/null
+// DR 1518
+// { dg-do compile { target c++11 } }
+
+struct A {
+ explicit A() = default;
+};
+
+struct B : A {
+ explicit B() = default;
+};
+
+struct C {
+ explicit C();
+};
+
+struct D : A {
+ C c;
+ explicit D() = default;
+};
+
+template<typename T> void f() {
+ T t = {}; // { dg-error "explicit" }
+}
+template<typename T> void g() {
+ void x(T t);
+ x({}); // { dg-error "explicit" }
+}
+
+int main()
+{
+ f<A>(); // { dg-bogus "required from here" }
+ f<B>(); // { dg-message "required from here" }
+ f<C>(); // { dg-message "required from here" }
+ f<D>(); // { dg-message "required from here" }
+
+ g<A>(); // { dg-bogus "required from here" }
+ g<B>(); // { dg-message "required from here" }
+ g<C>(); // { dg-message "required from here" }
+ g<D>(); // { dg-message "required from here" }
+}