From: jason Date: Tue, 26 Jan 2016 21:34:16 +0000 (+0000) Subject: PR c++/68949 X-Git-Tag: upstream/6.1~1444 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6a3851501b462a14d3b16353369db157b732a1a6;p=platform%2Fupstream%2Flinaro-gcc.git PR c++/68949 * constexpr.c (register_constexpr_fundef): Keep the un-massaged body. (cxx_eval_call_expression): Don't look through clones. * optimize.c (maybe_clone_body): Clear DECL_SAVED_TREE of the alias. * semantics.c (expand_or_defer_fn_1): Keep DECL_SAVED_TREE of maybe-in-charge *tor. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232848 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dee9e4d..0c490d5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2016-01-26 Jason Merrill + PR c++/68949 + * constexpr.c (register_constexpr_fundef): Keep the un-massaged body. + (cxx_eval_call_expression): Don't look through clones. + * optimize.c (maybe_clone_body): Clear DECL_SAVED_TREE of the alias. + * semantics.c (expand_or_defer_fn_1): Keep DECL_SAVED_TREE of + maybe-in-charge *tor. + +2016-01-26 Jason Merrill + PR c++/68782 * constexpr.c (cxx_eval_bare_aggregate): Update TREE_CONSTANT and TREE_SIDE_EFFECTS. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index eed7308..bbb8ccf 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -769,23 +769,23 @@ register_constexpr_fundef (tree fun, tree body) if (!is_valid_constexpr_fn (fun, !DECL_GENERATED_P (fun))) return NULL; - body = massage_constexpr_body (fun, body); - if (body == NULL_TREE || body == error_mark_node) + tree massaged = massage_constexpr_body (fun, body); + if (massaged == NULL_TREE || massaged == error_mark_node) { if (!DECL_CONSTRUCTOR_P (fun)) error ("body of constexpr function %qD not a return-statement", fun); return NULL; } - if (!potential_rvalue_constant_expression (body)) + if (!potential_rvalue_constant_expression (massaged)) { if (!DECL_GENERATED_P (fun)) - require_potential_rvalue_constant_expression (body); + require_potential_rvalue_constant_expression (massaged); return NULL; } if (DECL_CONSTRUCTOR_P (fun) - && cx_check_missing_mem_inits (fun, body, !DECL_GENERATED_P (fun))) + && cx_check_missing_mem_inits (fun, massaged, !DECL_GENERATED_P (fun))) return NULL; /* Create the constexpr function table if necessary. */ @@ -1340,15 +1340,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, { if (!result || result == error_mark_node) { - if (DECL_SAVED_TREE (fun) == NULL_TREE - && (DECL_CONSTRUCTOR_P (fun) || DECL_DESTRUCTOR_P (fun))) - /* The maybe-in-charge 'tor had its DECL_SAVED_TREE - cleared, try a clone. */ - for (fun = DECL_CHAIN (fun); - fun && DECL_CLONED_FUNCTION_P (fun); - fun = DECL_CHAIN (fun)) - if (DECL_SAVED_TREE (fun)) - break; gcc_assert (DECL_SAVED_TREE (fun)); tree parms, res; diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index 9d3e2c3..6f80b3d 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -646,6 +646,8 @@ maybe_clone_body (tree fn) { if (expand_or_defer_fn_1 (clone)) emit_associated_thunks (clone); + /* We didn't generate a body, so remove the empty one. */ + DECL_SAVED_TREE (clone) = NULL_TREE; } else expand_or_defer_fn (clone); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index f0e530d..95c4f19 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4163,9 +4163,8 @@ expand_or_defer_fn_1 (tree fn) /* We don't want to process FN again, so pretend we've written it out, even though we haven't. */ TREE_ASM_WRITTEN (fn) = 1; - /* If this is an instantiation of a constexpr function, keep - DECL_SAVED_TREE for explain_invalid_constexpr_fn. */ - if (!is_instantiation_of_constexpr (fn)) + /* If this is a constexpr function, keep DECL_SAVED_TREE. */ + if (!DECL_DECLARED_CONSTEXPR_P (fn)) DECL_SAVED_TREE (fn) = NULL_TREE; return false; } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array15.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array15.C new file mode 100644 index 0000000..a59e6f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array15.C @@ -0,0 +1,29 @@ +// PR c++/68949 +// { dg-do run { target c++11 } } + +struct Sub { + int i; + + constexpr Sub() : i(-1) {} // remove constexpr and it works as expected + Sub(Sub&& rhs); // remove this constructor and it works as epxected. +}; + +// v-- move this inline and it works as expected +// v-- remove ': Sub()' and it works as expected +Sub::Sub(Sub&& rhs) : Sub() { int tmp = i; i = rhs.i; rhs.i = tmp; } + +struct Class { + // v-- remove '[1]' and it works as expected + // v-- add '= {}' and it works as expected + Sub s[1]; + + // v-- add ': s{}' and it works as expected + // v-- removing this constructor makes it work as expected + Class() {} +}; + +int main() { + Class c; + if (c.s[0].i != -1) + __builtin_abort(); +}