DR 1518 DR 1630 PR c++/54835 PR c++/60417
DR 1518 DR 1630 PR c++/54835 PR c++/60417 * call.c (convert_like_real): Value-initialization can't use explicit constructors in C++11 and up. From-SVN: r229283
This commit is contained in:
parent
a8c6dabc47
commit
e7838ec9d2
6 changed files with 78 additions and 18 deletions
|
@ -1,5 +1,12 @@
|
|||
2015-10-23 Jason Merrill <jason@redhat.com>
|
||||
|
||||
DR 1518
|
||||
DR 1630
|
||||
PR c++/54835
|
||||
PR c++/60417
|
||||
* call.c (convert_like_real): Value-initialization can't use
|
||||
explicit constructors in C++11 and up.
|
||||
|
||||
PR c++/67813
|
||||
* constexpr.c (cxx_eval_store_expression): Always use *valp if
|
||||
set.
|
||||
|
|
|
@ -6341,9 +6341,32 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
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))
|
||||
|
@ -6359,18 +6382,6 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
|||
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
|
||||
|
|
40
gcc/testsuite/g++.dg/cpp0x/explicit10.C
Normal file
40
gcc/testsuite/g++.dg/cpp0x/explicit10.C
Normal file
|
@ -0,0 +1,40 @@
|
|||
// 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" }
|
||||
}
|
|
@ -8,6 +8,6 @@ struct A
|
|||
|
||||
int main()
|
||||
{
|
||||
A a1 = { };
|
||||
A a1 = { }; // { dg-error "explicit" }
|
||||
A a2 = { 24 }; // { dg-error "explicit" }
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// PR c++/60417
|
||||
// { dg-options -pedantic }
|
||||
|
||||
struct A { explicit A(int = 0); };
|
||||
struct B { A a; };
|
||||
|
||||
int main()
|
||||
{
|
||||
B b = {};
|
||||
B b = {}; // { dg-warning "explicit" "" { target c++11 } }
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// PR c++/60417
|
||||
// { dg-options -pedantic }
|
||||
|
||||
struct A { explicit A(int = 0); };
|
||||
|
||||
int main()
|
||||
{
|
||||
A a[1] = { };
|
||||
A a[1] = { }; // { dg-warning "explicit" "" { target c++11 } }
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue