From a3320d62af202fc82ffd12d36a02af5d4a694a56 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 28 Oct 2015 14:55:38 -0400 Subject: [PATCH] DR 1518 DR 1518 * class.c (type_has_user_provided_or_explicit_constructor): New. (check_bases_and_members): Use it. * cp-tree.h: Declare it. From-SVN: r229501 --- gcc/cp/ChangeLog | 7 ++++++ gcc/cp/class.c | 30 ++++++++++++++++++++++++- gcc/cp/cp-tree.h | 1 + gcc/testsuite/g++.dg/cpp0x/explicit10.C | 4 ++-- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c7aaa2771a1..d4c9a4f613d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2015-10-28 Jason Merrill + + DR 1518 + * class.c (type_has_user_provided_or_explicit_constructor): New. + (check_bases_and_members): Use it. + * cp-tree.h: Declare it. + 2015-10-27 Cesar Philippidis Thomas Schwinge James Norris diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 685b7b3fc18..4465963523f 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5150,6 +5150,33 @@ type_has_user_provided_constructor (tree t) return false; } +/* Returns true iff class T has a user-provided or explicit constructor. */ + +bool +type_has_user_provided_or_explicit_constructor (tree t) +{ + tree fns; + + if (!CLASS_TYPE_P (t)) + return false; + + if (!TYPE_HAS_USER_CONSTRUCTOR (t)) + return false; + + /* This can happen in error cases; avoid crashing. */ + if (!CLASSTYPE_METHOD_VEC (t)) + return false; + + for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns)) + { + tree fn = OVL_CURRENT (fns); + if (user_provided_p (fn) || DECL_NONCONVERTING_P (fn)) + return true; + } + + return false; +} + /* Returns true iff class T has a non-user-provided (i.e. implicitly declared or explicitly defaulted in the class body) default constructor. */ @@ -5735,7 +5762,8 @@ check_bases_and_members (tree t) Again, other conditions for being an aggregate are checked elsewhere. */ CLASSTYPE_NON_AGGREGATE (t) - |= (type_has_user_provided_constructor (t) || TYPE_POLYMORPHIC_P (t)); + |= (type_has_user_provided_or_explicit_constructor (t) + || TYPE_POLYMORPHIC_P (t)); /* This is the C++98/03 definition of POD; it changed in C++0x, but we retain the old definition internally for ABI reasons. */ CLASSTYPE_NON_LAYOUT_POD_P (t) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index af2ba64409c..acdd71ccc2e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5574,6 +5574,7 @@ extern bool type_has_user_nondefault_constructor (tree); extern tree in_class_defaulted_default_constructor (tree); extern bool user_provided_p (tree); extern bool type_has_user_provided_constructor (tree); +extern bool type_has_user_provided_or_explicit_constructor (tree); extern bool type_has_non_user_provided_default_constructor (tree); extern bool vbase_has_user_provided_move_assign (tree); extern tree default_init_uninitialized_part (tree); diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit10.C b/gcc/testsuite/g++.dg/cpp0x/explicit10.C index f31f85640bb..f9f8925d348 100644 --- a/gcc/testsuite/g++.dg/cpp0x/explicit10.C +++ b/gcc/testsuite/g++.dg/cpp0x/explicit10.C @@ -28,12 +28,12 @@ template void g() { int main() { - f(); // { dg-bogus "required from here" } + f(); // { dg-message "required from here" } f(); // { dg-message "required from here" } f(); // { dg-message "required from here" } f(); // { dg-message "required from here" } - g(); // { dg-bogus "required from here" } + g(); // { dg-message "required from here" } g(); // { dg-message "required from here" } g(); // { dg-message "required from here" } g(); // { dg-message "required from here" } -- 2.30.2