cp-tree.h (DECL_DEFERRED_CONSTEXPR_CHECK): New.
authorJason Merrill <jason@redhat.com>
Thu, 12 May 2011 17:33:53 +0000 (13:33 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 12 May 2011 17:33:53 +0000 (13:33 -0400)
* cp-tree.h (DECL_DEFERRED_CONSTEXPR_CHECK): New.
* semantics.c (validate_constexpr_fundecl): Set it.
(check_deferred_constexpr_decls): Clear it.
(register_constexpr_fundef): Make sure it isn't set.
* decl.c (grok_special_member_properties): Check it.

From-SVN: r173707

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

index 94f218179d68f29f02c9c22a34a10aa32f9c7ce2..6ca367103e08ffc841d30074182d095c2874dfbc 100644 (file)
@@ -1,3 +1,11 @@
+2011-05-12  Jason Merrill  <jason@redhat.com>
+
+       * cp-tree.h (DECL_DEFERRED_CONSTEXPR_CHECK): New.
+       * semantics.c (validate_constexpr_fundecl): Set it.
+       (check_deferred_constexpr_decls): Clear it.
+       (register_constexpr_fundef): Make sure it isn't set.
+       * decl.c (grok_special_member_properties): Check it.
+
 2011-05-11  Jason Merrill  <jason@redhat.com>
 
        PR c++/48948
index ec59346be45778499039eb9464c0bbf9fb5770f2..bcf78f8f14e26aacd9848272e873264dcf4dd6fa 100644 (file)
@@ -93,6 +93,7 @@ c-common.h, not after.
       TYPENAME_IS_RESOLVING_P (in TYPE_NAME_TYPE)
       LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (in LAMBDA_EXPR)
       TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR)
+      DECL_DEFERRED_CONSTEXPR_CHECK (in FUNCTION_DECL)
    3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
       ICS_BAD_FLAG (in _CONV)
       FN_TRY_BLOCK_P (in TRY_BLOCK)
@@ -2338,6 +2339,11 @@ struct GTY((variable_size)) lang_decl {
 #define DECL_DECLARED_CONSTEXPR_P(DECL) \
   DECL_LANG_FLAG_8 (VAR_OR_FUNCTION_DECL_CHECK (STRIP_TEMPLATE (DECL)))
 
+/* True if we can't tell yet whether the argument/return types of DECL
+   are literal because one is still being defined.  */
+#define DECL_DEFERRED_CONSTEXPR_CHECK(DECL) \
+  TREE_LANG_FLAG_2 (FUNCTION_DECL_CHECK (STRIP_TEMPLATE (DECL)))
+
 /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
    template function.  */
 #define DECL_PRETTY_FUNCTION_P(NODE) \
index 87be1120e54448995a5a54eedf6fd276afbcbd8c..793914002fe2cbbaca942fbd46c9bd7208a9ddbb 100644 (file)
@@ -10681,6 +10681,9 @@ grok_special_member_properties (tree decl)
        TYPE_HAS_LIST_CTOR (class_type) = 1;
 
       if (DECL_DECLARED_CONSTEXPR_P (decl)
+         /* It doesn't count if we can't tell yet whether or not
+            the constructor is actually constexpr.  */
+         && !DECL_DEFERRED_CONSTEXPR_CHECK (decl)
          && !copy_fn_p (decl) && !move_fn_p (decl))
        TYPE_HAS_CONSTEXPR_CTOR (class_type) = 1;
     }
index ffabad1802ca66d5b29615b8a7721634dc108d1e..f1f31219e5f3a509df227df851bcc21b7d4d83a7 100644 (file)
@@ -5483,7 +5483,10 @@ check_deferred_constexpr_decls (void)
   deferred_constexpr_decls = NULL;
 
   FOR_EACH_VEC_ELT (tree, vec, i, fn)
-    validate_constexpr_fundecl (fn);
+    {
+      DECL_DEFERRED_CONSTEXPR_CHECK (fn) = false;
+      validate_constexpr_fundecl (fn);
+    }
 
   if (deferred_constexpr_decls == NULL)
     {
@@ -5516,6 +5519,7 @@ validate_constexpr_fundecl (tree fun)
                                 /*defer_ok=*/true);
   if (valid < 0)
     {
+      DECL_DEFERRED_CONSTEXPR_CHECK (fun) = true;
       VEC_safe_push (tree, gc, deferred_constexpr_decls, fun);
       return NULL;
     }
@@ -5764,6 +5768,9 @@ register_constexpr_fundef (tree fun, tree body)
   constexpr_fundef entry;
   constexpr_fundef **slot;
 
+  gcc_assert (DECL_DECLARED_CONSTEXPR_P (fun)
+             && !DECL_DEFERRED_CONSTEXPR_CHECK (fun));
+
   if (DECL_CONSTRUCTOR_P (fun))
     body = build_constexpr_constructor_member_initializers
       (DECL_CONTEXT (fun), body);
index e09ae2e91c9a9f236b56c7d84b1dd5a655f5d0f4..f609bbaf2f0ab2fa2ce961a4c58cdaad530ad8d0 100644 (file)
@@ -1,3 +1,7 @@
+2011-05-12  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/constexpr-incomplete2.C: New.
+
 2011-05-12  Geert Bosch  <bosch@adacore.com>
 
        * gnat.dg/view_conversion1.adb: New test.
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete2.C
new file mode 100644 (file)
index 0000000..7a9a24d
--- /dev/null
@@ -0,0 +1,31 @@
+// A constructor that might or might not be constexpr doesn't make
+// its class literal.
+// { dg-options -std=c++0x }
+
+template <class T>
+struct B
+{
+  constexpr B(T) { }
+  constexpr B() {}
+};
+
+struct A
+{
+  B<A> b;
+};
+
+constexpr A a {};
+
+template <class T>
+struct C
+{
+  constexpr C(T) { }
+  C() {}
+};
+
+struct D
+{
+  C<D> c;
+};
+
+constexpr D d {};              // { dg-error "not literal" }