PR c++/68949
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Jan 2016 21:34:16 +0000 (21:34 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Jan 2016 21:34:16 +0000 (21:34 +0000)
* 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

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

index dee9e4d..0c490d5 100644 (file)
@@ -1,5 +1,14 @@
 2016-01-26  Jason Merrill  <jason@redhat.com>
 
+       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  <jason@redhat.com>
+
        PR c++/68782
        * constexpr.c (cxx_eval_bare_aggregate): Update TREE_CONSTANT
        and TREE_SIDE_EFFECTS.
index eed7308..bbb8ccf 100644 (file)
@@ -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;
 
index 9d3e2c3..6f80b3d 100644 (file)
@@ -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);
index f0e530d..95c4f19 100644 (file)
@@ -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 (file)
index 0000000..a59e6f5
--- /dev/null
@@ -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();
+}