aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJunMa <JunMa@linux.alibaba.com>2020-02-11 16:01:08 +0800
committerJunMa <JunMa@linux.alibaba.com>2020-03-04 09:08:37 +0800
commit7f327e8765c25552a1a6ae7d8747f74786f243dd (patch)
treeab2c915a426775274fcd03f91a690721d686fdb7 /gcc/cp
parentc46da87b9d35f709dea8d569cdb9a23dec8a4c04 (diff)
downloadgcc-7f327e8765c25552a1a6ae7d8747f74786f243dd.zip
gcc-7f327e8765c25552a1a6ae7d8747f74786f243dd.tar.gz
gcc-7f327e8765c25552a1a6ae7d8747f74786f243dd.tar.bz2
coroutines: Handle component_ref in captures_temporary
gcc/cp * coroutines.cc (captures_temporary): Strip component_ref to its base object. gcc/testsuite * g++.dg/coroutines/torture/co-await-15-capture-comp-ref.C: New test.
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/coroutines.cc20
2 files changed, 20 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e776110..7c22aea 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -7,6 +7,11 @@
2020-03-03 Jun Ma <JunMa@linux.alibaba.com>
+ * coroutines.cc (captures_temporary): Strip component_ref
+ to its base object.
+
+2020-03-03 Jun Ma <JunMa@linux.alibaba.com>
+
* coroutines.cc (finish_co_await_expr): Build co_await_expr
with unknown_type_node.
(finish_co_yield_expr): Ditto.
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 966ec05..bca4f1e 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -2613,12 +2613,22 @@ captures_temporary (tree *stmt, int *do_subtree, void *d)
continue;
parm = TREE_OPERAND (parm, 0);
- if (TREE_CODE (parm) == VAR_DECL && !DECL_ARTIFICIAL (parm))
- /* This isn't a temporary... */
- continue;
- if (TREE_CODE (parm) == PARM_DECL)
- /* .. nor is this... */
+ /* In case of component_ref, we need to capture the object of base
+ class as if it is temporary object. There are two possibilities:
+ (*base).field and base->field. */
+ while (TREE_CODE (parm) == COMPONENT_REF)
+ {
+ parm = TREE_OPERAND (parm, 0);
+ if (TREE_CODE (parm) == INDIRECT_REF)
+ parm = TREE_OPERAND (parm, 0);
+ parm = STRIP_NOPS (parm);
+ }
+
+ /* This isn't a temporary. */
+ if ((TREE_CODE (parm) == VAR_DECL && !DECL_ARTIFICIAL (parm))
+ || TREE_CODE (parm) == PARM_DECL
+ || TREE_CODE (parm) == NON_LVALUE_EXPR)
continue;
if (TREE_CODE (parm) == TARGET_EXPR)