aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.c
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2014-10-09 19:22:53 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2014-10-09 19:22:53 +0000
commit3369b9193606b86677e65bc96699939fb6a8d13e (patch)
tree4553766deb632f48b011e507c8e87b13c5f4fcbf /gcc/cp/semantics.c
parent5f60643158669361212ef79bfec16e8c73f4c138 (diff)
downloadgcc-3369b9193606b86677e65bc96699939fb6a8d13e.zip
gcc-3369b9193606b86677e65bc96699939fb6a8d13e.tar.gz
gcc-3369b9193606b86677e65bc96699939fb6a8d13e.tar.bz2
semantics.c (check_constexpr_ctor_body_1): New.
/cp 2014-10-09 Paolo Carlini <paolo.carlini@oracle.com> * semantics.c (check_constexpr_ctor_body_1): New. (check_constexpr_ctor_body): Use it; add bool parameter. (build_data_member_initialization): Handle BIND_EXPR and USING_STMT in the main conditional. (build_constexpr_constructor_member_initializers): Do not handle BIND_EXPR here. (constexpr_fn_retval): Handle BIND_EXPR in the switch. (massage_constexpr_body): Don't do it here. * parser.c (cp_parser_ctor_initializer_opt_and_function_body): Adjust check_constexpr_ctor_body call. (cp_parser_compound_statement): Do not pedwarn for compound-statement in constexpr function in C++14 mode. * cp-tree.h (check_constexpr_ctor_body): Update declaration. /testsuite 2014-10-09 Paolo Carlini <paolo.carlini@oracle.com> * g++.dg/cpp0x/constexpr-using3.C: New. * g++.dg/cpp1y/constexpr-local-compound1.C: Likewise. * g++.dg/cpp1y/constexpr-type-def-compound1.C: Likewise. * g++.dg/cpp1y/constexpr-local1.C: Extend. * g++.dg/cpp0x/constexpr-compound.C: Specify expected error. From-SVN: r216049
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r--gcc/cp/semantics.c75
1 files changed, 51 insertions, 24 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index ba09e72..3ca91d8 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7781,8 +7781,12 @@ build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
wrong type, but cxx_eval_constant_expression doesn't care. */
init = break_out_target_exprs (t);
}
- else if (TREE_CODE (t) == DECL_EXPR)
- /* Declaring a temporary, don't add it to the CONSTRUCTOR. */
+ else if (TREE_CODE (t) == BIND_EXPR)
+ return build_data_member_initialization (BIND_EXPR_BODY (t), vec);
+ else if (TREE_CODE (t) == DECL_EXPR
+ || TREE_CODE (t) == USING_STMT)
+ /* Declaring a temporary, don't add it to the CONSTRUCTOR.
+ Likewise for using directives. */
return true;
else
gcc_unreachable ();
@@ -7835,7 +7839,7 @@ build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
return true;
}
-/* Subroutine of check_constexpr_ctor_body and massage_constexpr_body.
+/* Subroutine of check_constexpr_ctor_body_1 and constexpr_fn_retval.
In C++11 mode checks that the TYPE_DECLs in the BIND_EXPR_VARS of a
BIND_EXPR conform to 7.1.5/3/4 on typedef and alias declarations. */
@@ -7854,11 +7858,45 @@ check_constexpr_bind_expr_vars (tree t)
return true;
}
+/* Subroutine of check_constexpr_ctor_body. */
+
+static bool
+check_constexpr_ctor_body_1 (tree last, tree list)
+{
+ switch (TREE_CODE (list))
+ {
+ case DECL_EXPR:
+ if (TREE_CODE (DECL_EXPR_DECL (list)) == USING_DECL)
+ return true;
+ if (cxx_dialect >= cxx14)
+ return true;
+ return false;
+
+ case CLEANUP_POINT_EXPR:
+ return check_constexpr_ctor_body (last, TREE_OPERAND (list, 0),
+ /*complain=*/false);
+
+ case BIND_EXPR:
+ if (!check_constexpr_bind_expr_vars (list)
+ || !check_constexpr_ctor_body (last, BIND_EXPR_BODY (list),
+ /*complain=*/false))
+ return false;
+ return true;
+
+ case USING_STMT:
+ case STATIC_ASSERT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* 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)
+check_constexpr_ctor_body (tree last, tree list, bool complain)
{
bool ok = true;
if (TREE_CODE (list) == STATEMENT_LIST)
@@ -7869,19 +7907,7 @@ check_constexpr_ctor_body (tree last, tree list)
tree t = tsi_stmt (i);
if (t == last)
break;
- if (TREE_CODE (t) == BIND_EXPR)
- {
- if (!check_constexpr_bind_expr_vars (t))
- {
- ok = false;
- break;
- }
- if (!check_constexpr_ctor_body (last, BIND_EXPR_BODY (t)))
- return false;
- else
- continue;
- }
- if (TREE_CODE (t) != STATIC_ASSERT)
+ if (!check_constexpr_ctor_body_1 (last, t))
{
ok = false;
break;
@@ -7889,11 +7915,12 @@ check_constexpr_ctor_body (tree last, tree list)
}
}
else if (list != last
- && TREE_CODE (list) != STATIC_ASSERT)
+ && !check_constexpr_ctor_body_1 (last, list))
ok = false;
if (!ok)
{
- error ("constexpr constructor does not have empty body");
+ if (complain)
+ error ("constexpr constructor does not have empty body");
DECL_DECLARED_CONSTEXPR_P (current_function_decl) = false;
}
return ok;
@@ -7983,8 +8010,6 @@ build_constexpr_constructor_member_initializers (tree type, tree body)
"a function-try-block");
return error_mark_node;
}
- else if (TREE_CODE (body) == BIND_EXPR)
- ok = build_data_member_initialization (BIND_EXPR_BODY (body), &vec);
else if (EXPR_P (body))
ok = build_data_member_initialization (body, &vec);
else
@@ -8052,6 +8077,11 @@ constexpr_fn_retval (tree body)
case CLEANUP_POINT_EXPR:
return constexpr_fn_retval (TREE_OPERAND (body, 0));
+ case BIND_EXPR:
+ if (!check_constexpr_bind_expr_vars (body))
+ return error_mark_node;
+ return constexpr_fn_retval (BIND_EXPR_BODY (body));
+
case USING_STMT:
return NULL_TREE;
@@ -8076,9 +8106,6 @@ massage_constexpr_body (tree fun, tree body)
body = EH_SPEC_STMTS (body);
if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
body = TREE_OPERAND (body, 0);
- if (TREE_CODE (body) == BIND_EXPR
- && check_constexpr_bind_expr_vars (body))
- body = BIND_EXPR_BODY (body);
body = constexpr_fn_retval (body);
}
return body;