From 2166aeb3abcbfaba9beffd4a8a0923d27d551f6c Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 7 Apr 2017 18:09:55 +0000 Subject: [PATCH] re PR c++/80095 (ICE with this pointer in NSDMI) PR c++/80095 * call.c (build_over_call): Don't check cxx_dialect. * cp-gimplify.c (cp_gimplify_init_expr): Don't check cxx_dialect nor whether SUB is a CONSTRUCTOR. * init.c (build_new_1): Don't check cxx_dialect. * tree.c (replace_placeholders): Add a function comment. Return if not in C++14, or if the object isn't a (member of a) class. * typeck2.c (store_init_value): Don't check cxx_dialect nor whether TYPE is CLASS_TYPE_P. * g++.dg/cpp1y/nsdmi-aggr8.C: New test. From-SVN: r246772 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/call.c | 5 ++--- gcc/cp/cp-gimplify.c | 5 ++--- gcc/cp/init.c | 3 +-- gcc/cp/tree.c | 14 ++++++++++++++ gcc/cp/typeck2.c | 5 ++--- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr8.C | 16 ++++++++++++++++ 8 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr8.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5ffd1b74490..a31d114374f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -3,6 +3,16 @@ PR sanitizer/80348 * typeck.c (cp_build_binary_op): Convert COP[01] to ORIG_TYPE. + PR c++/80095 + * call.c (build_over_call): Don't check cxx_dialect. + * cp-gimplify.c (cp_gimplify_init_expr): Don't check cxx_dialect nor + whether SUB is a CONSTRUCTOR. + * init.c (build_new_1): Don't check cxx_dialect. + * tree.c (replace_placeholders): Add a function comment. Return if + not in C++14, or if the object isn't a (member of a) class. + * typeck2.c (store_init_value): Don't check cxx_dialect nor whether + TYPE is CLASS_TYPE_P. + 2017-04-05 Jakub Jelinek PR c++/80309 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 803fbd4197e..c15b8e46f34 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8047,9 +8047,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) { arg = cp_build_indirect_ref (arg, RO_NULL, complain); val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg); - if (cxx_dialect >= cxx14) - /* Handle NSDMI that refer to the object being initialized. */ - replace_placeholders (arg, to); + /* Handle NSDMI that refer to the object being initialized. */ + replace_placeholders (arg, to); } else { diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 6e49daf8499..f2c52963a9f 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -496,9 +496,8 @@ cp_gimplify_init_expr (tree *expr_p) TREE_TYPE (from) = void_type_node; } - if (cxx_dialect >= cxx14 && TREE_CODE (sub) == CONSTRUCTOR) - /* Handle aggregate NSDMI. */ - replace_placeholders (sub, to); + /* Handle aggregate NSDMI. */ + replace_placeholders (sub, to); if (t == sub) break; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 2015205efd6..bfa902050cb 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3373,8 +3373,7 @@ build_new_1 (vec **placement, tree type, tree nelts, object being initialized, replace them now and don't try to preevaluate. */ bool had_placeholder = false; - if (cxx_dialect >= cxx14 - && !processing_template_decl + if (!processing_template_decl && TREE_CODE (init_expr) == INIT_EXPR) TREE_OPERAND (init_expr, 1) = replace_placeholders (TREE_OPERAND (init_expr, 1), diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 2757af6691d..99391352e3a 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2813,9 +2813,23 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_) return NULL_TREE; } +/* Replace PLACEHOLDER_EXPRs in EXP with object OBJ. SEEN_P is set if + a PLACEHOLDER_EXPR has been encountered. */ + tree replace_placeholders (tree exp, tree obj, bool *seen_p) { + /* This is only relevant for C++14. */ + if (cxx_dialect < cxx14) + return exp; + + /* If the object isn't a (member of a) class, do nothing. */ + tree op0 = obj; + while (TREE_CODE (op0) == COMPONENT_REF) + op0 = TREE_OPERAND (op0, 0); + if (!CLASS_TYPE_P (strip_array_types (TREE_TYPE (op0)))) + return exp; + tree *tp = &exp; replace_placeholders_t data = { obj, false }; if (TREE_CODE (exp) == TARGET_EXPR) diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index d1a393059a4..1f0eb454754 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -840,9 +840,8 @@ store_init_value (tree decl, tree init, vec** cleanups, int flags) } value = cp_fully_fold (value); - if (cxx_dialect >= cxx14 && CLASS_TYPE_P (strip_array_types (type))) - /* Handle aggregate NSDMI in non-constant initializers, too. */ - value = replace_placeholders (value, decl); + /* Handle aggregate NSDMI in non-constant initializers, too. */ + value = replace_placeholders (value, decl); /* DECL may change value; purge caches. */ clear_cv_and_fold_caches (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fbaef7a35ae..6150f746229 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -3,6 +3,9 @@ PR sanitizer/80348 * g++.dg/ubsan/div-by-zero-2.C: New test. + PR c++/80095 + * g++.dg/cpp1y/nsdmi-aggr8.C: New test. + 2017-04-07 Vladimir Makarov PR rtl-optimization/70478 diff --git a/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr8.C b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr8.C new file mode 100644 index 00000000000..8c99ffbc4c1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr8.C @@ -0,0 +1,16 @@ +// PR c++/80095 +// { dg-do compile { target c++14 } } + +struct A +{ + void* p = this; +}; + +void +foo () +{ + const A& a = A{}; + A&& a2 = A{}; + const A& a3{}; + A&& a4{}; +} -- 2.30.2