diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2014-10-09 19:22:53 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2014-10-09 19:22:53 +0000 |
commit | 3369b9193606b86677e65bc96699939fb6a8d13e (patch) | |
tree | 4553766deb632f48b011e507c8e87b13c5f4fcbf /gcc/cp/semantics.c | |
parent | 5f60643158669361212ef79bfec16e8c73f4c138 (diff) | |
download | gcc-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.c | 75 |
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; |