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 | |
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')
-rw-r--r-- | gcc/cp/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 4 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 75 |
4 files changed, 70 insertions, 27 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cf04f0d..84996a4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +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. + 2014-10-09 Jason Merrill <jason@redhat.com> PR c++/63309 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index cdc8927..3787c4a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5823,7 +5823,7 @@ extern void finish_handler (tree); extern void finish_cleanup (tree, tree); extern bool literal_type_p (tree); extern tree register_constexpr_fundef (tree, tree); -extern bool check_constexpr_ctor_body (tree, tree); +extern bool check_constexpr_ctor_body (tree, tree, bool); extern tree ensure_literal_type_for_constexpr_object (tree); extern bool potential_constant_expression (tree); extern bool potential_rvalue_constant_expression (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a9edcd5..c6218af 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -9891,7 +9891,7 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr, if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE)) return error_mark_node; if (DECL_DECLARED_CONSTEXPR_P (current_function_decl) - && !function_body) + && !function_body && cxx_dialect < cxx14) pedwarn (input_location, OPT_Wpedantic, "compound-statement in constexpr function"); /* Begin the compound-statement. */ @@ -19015,7 +19015,7 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser, /* Parse the function-body. */ cp_parser_function_body (parser, in_function_try_block); if (check_body_p) - check_constexpr_ctor_body (last, list); + check_constexpr_ctor_body (last, list, /*complain=*/true); /* Finish the function body. */ finish_function_body (body); 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; |