aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-16 19:29:09 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-16 19:29:09 +0000
commit8b54dd2e6bc8b8eac24d4dd6615574d7d1b21e16 (patch)
treed77d596beeabd917886f711d575dd0ddf4ed8cf2
parent8154a3514d5fc8067a6928531d5f61cd768bd62c (diff)
PR c++/58063
* tree.c (bot_manip): Remap SAVE_EXPR. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@224533 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/tree.c23
-rw-r--r--gcc/testsuite/g++.dg/overload/defarg10.C28
3 files changed, 54 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1ab5e8f2c3f..5c85c5d1524 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2015-06-16 Jason Merrill <jason@redhat.com>
+ PR c++/58063
+ * tree.c (bot_manip): Remap SAVE_EXPR.
+
PR c++/66387
* pt.c (tsubst_copy) [VAR_DECL]: Use process_outer_var_ref.
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 3553d7c2c9d..a52e6f4367f 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2423,6 +2423,29 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
*walk_subtrees = 0;
return NULL_TREE;
}
+ if (TREE_CODE (*tp) == SAVE_EXPR)
+ {
+ t = *tp;
+ splay_tree_node n = splay_tree_lookup (target_remap,
+ (splay_tree_key) t);
+ if (n)
+ {
+ *tp = (tree)n->value;
+ *walk_subtrees = 0;
+ }
+ else
+ {
+ copy_tree_r (tp, walk_subtrees, NULL);
+ splay_tree_insert (target_remap,
+ (splay_tree_key)t,
+ (splay_tree_value)*tp);
+ /* Make sure we don't remap an already-remapped SAVE_EXPR. */
+ splay_tree_insert (target_remap,
+ (splay_tree_key)*tp,
+ (splay_tree_value)*tp);
+ }
+ return NULL_TREE;
+ }
/* Make a copy of this node. */
t = copy_tree_r (tp, walk_subtrees, NULL);
diff --git a/gcc/testsuite/g++.dg/overload/defarg10.C b/gcc/testsuite/g++.dg/overload/defarg10.C
new file mode 100644
index 00000000000..b8275d60453
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/defarg10.C
@@ -0,0 +1,28 @@
+// PR c++/58063
+// { dg-do run }
+
+struct basic_ios
+{
+ bool operator!() const { return false; }
+};
+
+struct ostream : virtual basic_ios
+{
+};
+
+int i;
+
+ostream& operator<<(ostream& os, const char* s) {
+ ++i;
+ return os;
+}
+
+ostream cout;
+
+void f(bool x = !(cout << "hi!\n")) { }
+
+int main() {
+ f();
+ if (i != 1)
+ __builtin_abort();
+}