summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-27 19:18:33 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-27 19:18:33 +0000
commit7197f3f8753ab4277784fe78a1590204bcf67901 (patch)
tree26a2642217c5dbb7712bd2dc421e2b6104e9661e
parentb5ba22d74eaa8531da4c51c0dc7ab4562f230f86 (diff)
downloadgcc-7197f3f8753ab4277784fe78a1590204bcf67901.tar.gz
PR c++/68949
* 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/branches/gcc-5-branch@232896 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/optimize.c2
-rw-r--r--gcc/cp/semantics.c5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-array15.C29
4 files changed, 38 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d80724b3959..0c21b216569 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2016-01-27 Jason Merrill <jason@redhat.com>
+ PR c++/68949
+ * 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.
+
PR c++/69131
* method.c (walk_field_subobs): Add dtor_from_ctor parm.
(process_subob_fn): Likewise. Don't consider triviality if true.
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index a2dd880ea49..e485a6da817 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -670,6 +670,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 feba03d1c7f..abd30e23ce8 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4104,9 +4104,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 00000000000..a59e6f5df14
--- /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();
+}