re PR c++/46382 (constexpr vs. static_assert in constexpr ctors)
authorJason Merrill <jason@redhat.com>
Tue, 9 Nov 2010 03:54:24 +0000 (22:54 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 9 Nov 2010 03:54:24 +0000 (22:54 -0500)
PR c++/46382
* semantics.c (check_constexpr_ctor_body): New fn.
* parser.c (cp_parser_ctor_initializer_opt_and_function_body): Call it.
* cp-tree.h: Declare it.

From-SVN: r166471

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

index 2408adb..7223529 100644 (file)
@@ -1,5 +1,10 @@
 2010-11-08  Jason Merrill  <jason@redhat.com>
 
+       PR c++/46382
+       * semantics.c (check_constexpr_ctor_body): New fn.
+       * parser.c (cp_parser_ctor_initializer_opt_and_function_body): Call it.
+       * cp-tree.h: Declare it.
+
        PR c++/46335
        * tree.c (bot_manip): Check TREE_SIDE_EFFECTS as well.
 
index 241805c..67f4f93 100644 (file)
@@ -5249,6 +5249,7 @@ extern void finish_cleanup                        (tree, tree);
 extern bool literal_type_p (tree);
 extern tree validate_constexpr_fundecl (tree);
 extern tree register_constexpr_fundef (tree, tree);
+extern bool check_constexpr_ctor_body (tree, tree);
 extern tree ensure_literal_type_for_constexpr_object (tree);
 extern bool potential_constant_expression (tree, tsubst_flags_t);
 extern tree cxx_constant_value (tree);
index 6a9e4d7..4897941 100644 (file)
@@ -16347,14 +16347,8 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser)
     }
   /* Parse the function-body.  */
   cp_parser_function_body (parser);
-  if (check_body_p
-      && (TREE_CODE (list) != STATEMENT_LIST
-         || (last == NULL && STATEMENT_LIST_TAIL (list) != NULL)
-         || (last != NULL && last != STATEMENT_LIST_TAIL (list)->stmt)))
-    {
-      error ("constexpr constructor does not have empty body");
-      DECL_DECLARED_CONSTEXPR_P (current_function_decl) = false;
-    }
+  if (check_body_p)
+    check_constexpr_ctor_body (last, list);
   /* Finish the function body.  */
   finish_function_body (body);
 
index 494247e..b48559e 100644 (file)
@@ -5522,6 +5522,48 @@ build_data_member_initialization (tree t, VEC(constructor_elt,gc) **vec)
   return true;
 }
 
+/* Make sure that there are no statements after LAST in the constructor
+   body represented by LIST.  */
+
+bool
+check_constexpr_ctor_body (tree last, tree list)
+{
+  bool ok = true;
+  if (TREE_CODE (list) == STATEMENT_LIST)
+    {
+      tree_stmt_iterator i = tsi_last (list);
+      for (; !tsi_end_p (i); tsi_prev (&i))
+       {
+         tree t = tsi_stmt (i);
+         if (t == last)
+           break;
+         if (TREE_CODE (t) == BIND_EXPR)
+           {
+             if (!check_constexpr_ctor_body (last, BIND_EXPR_BODY (t)))
+               return false;
+             else
+               continue;
+           }
+         /* We currently allow typedefs and static_assert.
+            FIXME allow them in the standard, too.  */
+         if (TREE_CODE (t) != STATIC_ASSERT)
+           {
+             ok = false;
+             break;
+           }
+       }
+    }
+  else if (list != last
+          && TREE_CODE (list) != STATIC_ASSERT)
+    ok = false;
+  if (!ok)
+    {
+      error ("constexpr constructor does not have empty body");
+      DECL_DECLARED_CONSTEXPR_P (current_function_decl) = false;
+    }
+  return ok;
+}
+
 /* Build compile-time evalable representations of member-initializer list
    for a constexpr constructor.  */
 
index 1211aa2..3f992d9 100644 (file)
@@ -1,5 +1,9 @@
 2010-11-08  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/constexpr-sassert.C: New.
+
+2010-11-08  Jason Merrill  <jason@redhat.com>
+
        * g++.dg/cpp0x/constexpr-defarg.C: New.
 
 2010-11-08  Xinliang David Li  <davidxl@google.com>
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-sassert.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-sassert.C
new file mode 100644 (file)
index 0000000..3e08fb0
--- /dev/null
@@ -0,0 +1,13 @@
+// Allow static_assert in constexpr constructors, too.
+// { dg-options -std=c++0x }
+
+template<typename T>
+struct A
+{
+  int i;
+
+  constexpr A(int i) : i(i)
+  {
+    static_assert(sizeof(T) == 1, "");
+  }
+};