DR 1518
authorJason Merrill <jason@redhat.com>
Wed, 28 Oct 2015 18:55:38 +0000 (14:55 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 28 Oct 2015 18:55:38 +0000 (14:55 -0400)
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
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/testsuite/g++.dg/cpp0x/explicit10.C

index c7aaa2771a186c412f806933043d58f658d2c462..d4c9a4f613dce2761254656de33b8bab3ce930a7 100644 (file)
@@ -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>
index 685b7b3fc18dda8b2bd2da4d34f8d1fdd72ad349..4465963523f77d36ee35087bbae9dcafc8a15e94 100644 (file)
@@ -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)
index af2ba64409c4a5597cf704561b5228e6d271b5b7..acdd71ccc2e2cc12a044b66974849eda9899f1ec 100644 (file)
@@ -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);
index f31f85640bb8eb8d0c72c3dc9934c8946dd89d77..f9f8925d3483f4987bb0e9ef511adbeef7d6e175 100644 (file)
@@ -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" }