aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/parser.c10
-rw-r--r--gcc/cp/semantics.c42
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-sassert.C13
6 files changed, 67 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2408adb..7223529d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 241805c..67f4f93 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 6a9e4d7..4897941 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 494247e7..b48559e 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1211aa2..3f992d9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..3e08fb0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-sassert.C
@@ -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, "");
+ }
+};