summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-28 18:55:38 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-28 18:55:38 +0000
commit96b973c7fa6169c83bc6530f1589a9ccf8a20d70 (patch)
tree17eb39bfae398799fc8f39adbe4dd62f9f8edaa4
parentf576a2e4a07174b4080ea634f52bf48c6cfee7c3 (diff)
downloadgcc-96b973c7fa6169c83bc6530f1589a9ccf8a20d70.tar.gz
DR 1518
* class.c (type_has_user_provided_or_explicit_constructor): New. (check_bases_and_members): Use it. * cp-tree.h: Declare it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@229501 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/class.c30
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/explicit10.C4
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 <jason@redhat.com>
+
+ 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 <cesar@codesourcery.com>
Thomas Schwinge <thomas@codesourcery.com>
James Norris <jnorris@codesourcery.com>
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<typename T> void g() {
int main()
{
- f<A>(); // { dg-bogus "required from here" }
+ f<A>(); // { dg-message "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<A>(); // { dg-message "required from here" }
g<B>(); // { dg-message "required from here" }
g<C>(); // { dg-message "required from here" }
g<D>(); // { dg-message "required from here" }