class.c (trivial_default_constructor_is_constexpr): Rename from synthesized_default_c...
authorJason Merrill <jason@redhat.com>
Mon, 5 Sep 2011 04:33:40 +0000 (00:33 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 5 Sep 2011 04:33:40 +0000 (00:33 -0400)
* class.c (trivial_default_constructor_is_constexpr): Rename from
synthesized_default_constructor_is_constexpr.
(type_has_constexpr_default_constructor): Adjust.
(add_implicitly_declared_members): Call it instead.
(explain_non_literal_class): Explain about non-constexpr default ctor.
* cp-tree.h: Adjust.
* method.c (synthesized_method_walk): Adjust.
* semantics.c (explain_invalid_constexpr_fn): Handle defaulted
functions, too.

From-SVN: r178519

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/method.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C [new file with mode: 0644]

index a83d19ba665c878d011f25ccb0365ba5fcfc1aa5..d61f5f782b702e2370bdeac7fa07b169e2bb13df 100644 (file)
@@ -1,5 +1,15 @@
 2011-09-04  Jason Merrill  <jason@redhat.com>
 
+       * class.c (trivial_default_constructor_is_constexpr): Rename from
+       synthesized_default_constructor_is_constexpr.
+       (type_has_constexpr_default_constructor): Adjust.
+       (add_implicitly_declared_members): Call it instead.
+       (explain_non_literal_class): Explain about non-constexpr default ctor.
+       * cp-tree.h: Adjust.
+       * method.c (synthesized_method_walk): Adjust.
+       * semantics.c (explain_invalid_constexpr_fn): Handle defaulted
+       functions, too.
+
        PR c++/50248
        Core 1358
        * init.c (perform_member_init): Don't diagnose missing inits here.
index 2a4bc77aa5ee430bec7833930d6c1a543f8f4e65..a4a7468bad1cb74edaaf264c25549ac597d63503 100644 (file)
@@ -2726,7 +2726,8 @@ add_implicitly_declared_members (tree t,
       CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
       if (cxx_dialect >= cxx0x)
        TYPE_HAS_CONSTEXPR_CTOR (t)
-         = synthesized_default_constructor_is_constexpr (t);
+         /* This might force the declaration.  */
+         = type_has_constexpr_default_constructor (t);
     }
 
   /* [class.ctor]
@@ -4355,15 +4356,15 @@ type_has_user_provided_default_constructor (tree t)
   return false;
 }
 
-/* Returns true iff for class T, a synthesized default constructor
+/* Returns true iff for class T, a trivial synthesized default constructor
    would be constexpr.  */
 
 bool
-synthesized_default_constructor_is_constexpr (tree t)
+trivial_default_constructor_is_constexpr (tree t)
 {
-  /* A defaulted default constructor is constexpr
+  /* A defaulted trivial default constructor is constexpr
      if there is nothing to initialize.  */
-  /* FIXME adjust for non-static data member initializers.  */
+  gcc_assert (!TYPE_HAS_COMPLEX_DFLT (t));
   return is_really_empty_class (t);
 }
 
@@ -4381,7 +4382,12 @@ type_has_constexpr_default_constructor (tree t)
       return false;
     }
   if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
-    return synthesized_default_constructor_is_constexpr (t);
+    {
+      if (!TYPE_HAS_COMPLEX_DFLT (t))
+       return trivial_default_constructor_is_constexpr (t);
+      /* Non-trivial, we need to check subobject constructors.  */
+      lazily_declare_fn (sfk_constructor, t);
+    }
   fns = locate_ctor (t);
   return (fns && DECL_DECLARED_CONSTEXPR_P (fns));
 }
@@ -4608,9 +4614,14 @@ explain_non_literal_class (tree t)
   else if (CLASSTYPE_NON_AGGREGATE (t)
           && !TYPE_HAS_TRIVIAL_DFLT (t)
           && !TYPE_HAS_CONSTEXPR_CTOR (t))
-    inform (0, "  %q+T is not an aggregate, does not have a trivial "
-           "default constructor, and has no constexpr constructor that "
-           "is not a copy or move constructor", t);
+    {
+      inform (0, "  %q+T is not an aggregate, does not have a trivial "
+             "default constructor, and has no constexpr constructor that "
+             "is not a copy or move constructor", t);
+      if (TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
+         && !type_has_user_provided_default_constructor (t))
+       explain_invalid_constexpr_fn (locate_ctor (t));
+    }
   else
     {
       tree binfo, base_binfo, field; int i;
index d18599b0c53292528f92d9bb099691006cbe44de..cf6c056e4e554b699607d2a8fd58edc6a1ca75dd 100644 (file)
@@ -4823,7 +4823,7 @@ 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_default_constructor (tree);
-extern bool synthesized_default_constructor_is_constexpr (tree);
+extern bool trivial_default_constructor_is_constexpr (tree);
 extern bool type_has_constexpr_default_constructor (tree);
 extern bool type_has_virtual_destructor                (tree);
 extern bool type_has_move_constructor          (tree);
index 74a3bdbd83961d51099ed48941b1e1439356f3eb..5b24f8f02858fa771b7a31f4a995bd65333624d2 100644 (file)
@@ -1187,7 +1187,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
       && (!copy_arg_p || cxx_dialect < cxx0x))
     {
       if (constexpr_p && sfk == sfk_constructor)
-       *constexpr_p = synthesized_default_constructor_is_constexpr (ctype);
+       *constexpr_p = trivial_default_constructor_is_constexpr (ctype);
       return;
     }
 
index fd96d706c89e26deb89cec9325baad9ee87d500f..bdc4cf29e34458b2555755c578b305ed2a4e9420 100644 (file)
@@ -5881,8 +5881,9 @@ explain_invalid_constexpr_fn (tree fun)
   static struct pointer_set_t *diagnosed;
   tree body;
   location_t save_loc;
-  /* Only diagnose instantiations of constexpr templates.  */
-  if (!is_instantiation_of_constexpr (fun))
+  /* Only diagnose defaulted functions or instantiations.  */
+  if (!DECL_DEFAULTED_FN (fun)
+      && !is_instantiation_of_constexpr (fun))
     return;
   if (diagnosed == NULL)
     diagnosed = pointer_set_create ();
index 19441c44b790633aa58e7d0607f56f9b0a83de6e..2f149c4d42cb0dba2df2d258eab9059fa76e579c 100644 (file)
@@ -1,5 +1,7 @@
 2011-09-04  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/constexpr-default-ctor.C: New.
+
        PR c++/50248
        Core 1358
        * g++.dg/cpp0x/constexpr-template1.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-default-ctor.C
new file mode 100644 (file)
index 0000000..d3868b5
--- /dev/null
@@ -0,0 +1,12 @@
+// { dg-options -std=c++0x }
+
+struct A {
+  int i;
+  constexpr A():i(42) { };
+};
+struct B: A { };
+constexpr int f(B b) { return b.i; }
+
+struct C { C(); };            // { dg-message "calls non-constexpr" }
+struct D: C { };              // { dg-message "no constexpr constructor" }
+constexpr int g(D d) { return 42; } // { dg-error "invalid type" }