From: Jason Merrill Date: Sun, 26 Jun 2011 14:00:33 +0000 (-0400) Subject: re PR c++/49528 (g++ fails to destroy temporary object when subobject is used to... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=07a9e891c9cbb1df6aa33edbe39c21d948da2301;p=gcc.git re PR c++/49528 (g++ fails to destroy temporary object when subobject is used to initialize a reference) PR c++/49528 * semantics.c (potential_constant_expression_1): A TARGET_EXPR with a cleanup isn't constant. (cxx_eval_constant_expression): Likewise. * init.c (expand_default_init): Use maybe_constant_init. From-SVN: r175409 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3840f370ccf..117c13e9867 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2011-06-26 Jason Merrill + + PR c++/49528 + * semantics.c (potential_constant_expression_1): A TARGET_EXPR + with a cleanup isn't constant. + (cxx_eval_constant_expression): Likewise. + * init.c (expand_default_init): Use maybe_constant_init. + 2011-06-24 Jakub Jelinek PR c++/46400 diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 3c347a4521f..3ceed90f3b5 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1514,7 +1514,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags, tree fn = get_callee_fndecl (rval); if (fn && DECL_DECLARED_CONSTEXPR_P (fn)) { - tree e = maybe_constant_value (rval); + tree e = maybe_constant_init (rval); if (TREE_CONSTANT (e)) rval = build2 (INIT_EXPR, type, exp, e); } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index f4aa350cb7c..5404c9f2a56 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -7020,6 +7020,16 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t, break; case TARGET_EXPR: + /* A cleanup isn't constant. */ + if (TARGET_EXPR_CLEANUP (t)) + { + if (!allow_non_constant) + error ("temporary of type %qT needing destruction in a " + "constant expression", TREE_TYPE (t)); + *non_constant_p = true; + break; + } + /* else fall through. */ case INIT_EXPR: /* Pass false for 'addr' because these codes indicate initialization of a temporary. */ @@ -7840,8 +7850,16 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags) return potential_constant_expression_1 (TREE_OPERAND (t, 1), want_rval, flags); - case INIT_EXPR: case TARGET_EXPR: + /* A cleanup isn't constant. */ + if (TARGET_EXPR_CLEANUP (t)) + { + if (flags & tf_error) + error ("temporary of type %qT needing destruction in a " + "constant expression", TREE_TYPE (t)); + return false; + } + case INIT_EXPR: return potential_constant_expression_1 (TREE_OPERAND (t, 1), rval, flags); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 01ef0d9544f..01b111cef6b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-06-26 Jason Merrill + + PR c++/49528 + * g++.dg/init/ref19.C: New. + * g++.dg/cpp0x/constexpr-cleanup.C: New. + 2011-06-26 Jakub Jelinek PR tree-optimization/48377 diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-cleanup.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-cleanup.C new file mode 100644 index 00000000000..b3fb9a8deca --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-cleanup.C @@ -0,0 +1,9 @@ +// { dg-options -std=c++0x } + +struct A +{ + int i; + ~A(); +}; + +constexpr int i = A().i; // { dg-error "destruction" } diff --git a/gcc/testsuite/g++.dg/init/ref19.C b/gcc/testsuite/g++.dg/init/ref19.C new file mode 100644 index 00000000000..ed78c939ba6 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/ref19.C @@ -0,0 +1,17 @@ +// PR c++/49528 +// { dg-do run } + +int d; + +struct A +{ + int i; + ~A() { ++d; }; +}; + +int main() +{ + const int &r = A().i; + if (d != 1) + return 1; +}