re PR c++/49528 (g++ fails to destroy temporary object when subobject is used to...
authorJason Merrill <jason@redhat.com>
Sun, 26 Jun 2011 14:00:33 +0000 (10:00 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 26 Jun 2011 14:00:33 +0000 (10:00 -0400)
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

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-cleanup.C [new file with mode: 0644]
gcc/testsuite/g++.dg/init/ref19.C [new file with mode: 0644]

index 3840f370ccf079aa7ef575764a27c72dc4bcc7c3..117c13e98673f2a789ddb3d55add5a2ff5a67cae 100644 (file)
@@ -1,3 +1,11 @@
+2011-06-26  Jason Merrill  <jason@redhat.com>
+
+       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  <jakub@redhat.com>
 
        PR c++/46400
index 3c347a4521f983a2c84914731bf5f0185c9a1754..3ceed90f3b5c49b177bb9c81d43a8c52fff9cad5 100644 (file)
@@ -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);
        }
index f4aa350cb7c7cafdaee8b14d6a1f151efbeed4bb..5404c9f2a56995210e1c4b9544b48493bff5c6c4 100644 (file)
@@ -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);
 
index 01ef0d9544f02fc726f742c5f9efbad4a563694b..01b111cef6b2a7340509b0c0c4902dadf75bfd5c 100644 (file)
@@ -1,3 +1,9 @@
+2011-06-26  Jason Merrill  <jason@redhat.com>
+
+       PR c++/49528
+       * g++.dg/init/ref19.C: New.
+       * g++.dg/cpp0x/constexpr-cleanup.C: New.
+
 2011-06-26  Jakub Jelinek  <jakub@redhat.com>
 
        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 (file)
index 0000000..b3fb9a8
--- /dev/null
@@ -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 (file)
index 0000000..ed78c93
--- /dev/null
@@ -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;
+}