diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 55cf4a02e82..26b51ec3b16 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2017-09-05 Paolo Carlini + + PR c++/81942 + * cp-tree.h (LABEL_DECL_CDTOR): Add and document. + * decl.c (start_preparsed_function): Set LABEL_DECL_CDTOR when + creating cdtor_label. + * constexpr.c (returns): Add the case of a constructor/destructor + returning via a LABEL_DECL_CDTOR label. + (cxx_eval_constant_expression, case [GOTO_EXPR]): Likewise. + 2017-09-01 Nathan Sidwell * cp-tree.h (resort_type_method_vec): Move declaration to ... diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index f3e868cff02..a5692fb3b3a 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3671,7 +3671,9 @@ static bool returns (tree *jump_target) { return *jump_target - && TREE_CODE (*jump_target) == RETURN_EXPR; + && (TREE_CODE (*jump_target) == RETURN_EXPR + || (TREE_CODE (*jump_target) == LABEL_DECL + && LABEL_DECL_CDTOR (*jump_target))); } static bool @@ -4554,7 +4556,9 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case GOTO_EXPR: *jump_target = TREE_OPERAND (t, 0); - gcc_assert (breaks (jump_target) || continues (jump_target)); + gcc_assert (breaks (jump_target) || continues (jump_target) + /* Allow for jumping to a cdtor_label. */ + || returns (jump_target)); break; case LOOP_EXPR: diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 432faa9da14..7dc20b1649b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -456,6 +456,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; DECL_CONSTRAINT_VAR_P (in a PARM_DECL) TEMPLATE_DECL_COMPLEX_ALIAS_P (in TEMPLATE_DECL) DECL_INSTANTIATING_NSDMI_P (in a FIELD_DECL) + LABEL_DECL_CDTOR (in LABEL_DECL) 3: DECL_IN_AGGR_P. 4: DECL_C_BIT_FIELD (in a FIELD_DECL) DECL_ANON_UNION_VAR_P (in a VAR_DECL) @@ -3833,6 +3834,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define LABEL_DECL_CONTINUE(NODE) \ DECL_LANG_FLAG_1 (LABEL_DECL_CHECK (NODE)) +/* Nonzero if NODE is the target for genericization of 'return' stmts + in constructors/destructors of targetm.cxx.cdtor_returns_this targets. */ +#define LABEL_DECL_CDTOR(NODE) \ + DECL_LANG_FLAG_2 (LABEL_DECL_CHECK (NODE)) + /* True if NODE was declared with auto in its return type, but it has started compilation and so the return type might have been changed by return type deduction; its declared return type should be found in diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d6b80c604c8..861dfcfd828 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -15072,7 +15072,10 @@ start_preparsed_function (tree decl1, tree attrs, int flags) if (DECL_DESTRUCTOR_P (decl1) || (DECL_CONSTRUCTOR_P (decl1) && targetm.cxx.cdtor_returns_this ())) - cdtor_label = create_artificial_label (input_location); + { + cdtor_label = create_artificial_label (input_location); + LABEL_DECL_CDTOR (cdtor_label) = true; + } start_fname_decls (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0ef3da8691b..690bc5bacce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-09-05 Paolo Carlini + + PR c++/81942 + * g++.dg/cpp1y/constexpr-return3.C: New. + 2017-09-05 Eric Botcazou * gnat.dg/incomplete5.ad[sb]: New test. diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-return3.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-return3.C new file mode 100644 index 00000000000..4cf4128e9eb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-return3.C @@ -0,0 +1,11 @@ +// PR c++/81942 +// { dg-do compile { target c++14 } } + +class A { +public: + constexpr A() { + return; + } +}; + +A mwi;