From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2122) id AAD153858421; Wed, 21 Dec 2022 02:04:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AAD153858421 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1671588272; bh=MSyAnCQtRU/AH654h1QydPuJasn6sbhifG3ZanD/9zQ=; h=From:To:Subject:Date:From; b=kqbbBQgfOZu4XBkP5/zCX43am/XjACipx8qa7WBjERPE/law0kATBSLa1zS3yVhdu Bs495bPRDgQBIaVCzJuabS/ys5VLshmdhh246TejdwoAr8axYnPPYYr89isJQLaKQe 74lc3CIBhrXI9DNfijBlhhyvkm+ijw8a70dZmFLg= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jason Merrill To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-4812] c++: source position of lambda captures [PR84471] X-Act-Checkin: gcc X-Git-Author: Jason Merrill X-Git-Refname: refs/heads/master X-Git-Oldrev: a996888327c2248b59db7244333740c2b51578c9 X-Git-Newrev: 302485a70a33f3a86e85ad9051de2b51c5dc0bc0 Message-Id: <20221221020432.AAD153858421@sourceware.org> Date: Wed, 21 Dec 2022 02:04:32 +0000 (GMT) List-Id: https://gcc.gnu.org/g:302485a70a33f3a86e85ad9051de2b51c5dc0bc0 commit r13-4812-g302485a70a33f3a86e85ad9051de2b51c5dc0bc0 Author: Jason Merrill Date: Thu Dec 1 22:58:28 2022 -0500 c++: source position of lambda captures [PR84471] If the DECL_VALUE_EXPR of a VAR_DECL has EXPR_LOCATION set, then any use of that variable looks like it has that location, which leads to the debugger jumping back and forth for both lambdas and structured bindings. Rather than fix all the uses, it seems simplest to remove any EXPR_LOCATION when setting DECL_VALUE_EXPR. So the cp/ hunks aren't necessary, but they avoid the need to unshare to remove the location. PR c++/84471 PR c++/107504 gcc/cp/ChangeLog: * coroutines.cc (transform_local_var_uses): Don't specify a location for DECL_VALUE_EXPR. * decl.cc (cp_finish_decomp): Likewise. gcc/ChangeLog: * fold-const.cc (protected_set_expr_location_unshare): Not static. * tree.h: Declare it. * tree.cc (decl_value_expr_insert): Use it. include/ChangeLog: * ansidecl.h (ATTRIBUTE_WARN_UNUSED_RESULT): Add __. gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/value-expr1.C: New test. * g++.dg/tree-ssa/value-expr2.C: New test. * g++.dg/analyzer/pr93212.C: Move warning. Diff: --- gcc/tree.h | 2 ++ include/ansidecl.h | 2 +- gcc/cp/coroutines.cc | 4 ++-- gcc/cp/decl.cc | 12 +++--------- gcc/fold-const.cc | 2 +- gcc/testsuite/g++.dg/analyzer/pr93212.C | 4 ++-- gcc/testsuite/g++.dg/tree-ssa/value-expr1.C | 16 ++++++++++++++++ gcc/testsuite/g++.dg/tree-ssa/value-expr2.C | 26 ++++++++++++++++++++++++++ gcc/tree.cc | 3 +++ 9 files changed, 56 insertions(+), 15 deletions(-) diff --git a/gcc/tree.h b/gcc/tree.h index 31d0dcaf249..64a241f51e2 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1289,6 +1289,8 @@ get_expr_source_range (tree expr) extern void protected_set_expr_location (tree, location_t); extern void protected_set_expr_location_if_unset (tree, location_t); +ATTRIBUTE_WARN_UNUSED_RESULT +extern tree protected_set_expr_location_unshare (tree, location_t); WARN_UNUSED_RESULT extern tree maybe_wrap_with_location (tree, location_t); diff --git a/include/ansidecl.h b/include/ansidecl.h index 056a03ebb6e..4da8069f171 100644 --- a/include/ansidecl.h +++ b/include/ansidecl.h @@ -279,7 +279,7 @@ So instead we use the macro below and test it against specific values. */ /* Attribute `warn_unused_result' was valid as of gcc 3.3. */ #ifndef ATTRIBUTE_WARN_UNUSED_RESULT # if GCC_VERSION >= 3003 -# define ATTRIBUTE_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) +# define ATTRIBUTE_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) # else # define ATTRIBUTE_WARN_UNUSED_RESULT # endif diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 88d6c30d8b1..77e2a90f0f9 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -2047,8 +2047,8 @@ transform_local_var_uses (tree *stmt, int *do_subtree, void *d) = lookup_member (lvd->coro_frame_type, local_var.field_id, /*protect=*/1, /*want_type=*/0, tf_warning_or_error); - tree fld_idx = build3_loc (lvd->loc, COMPONENT_REF, TREE_TYPE (lvar), - lvd->actor_frame, fld_ref, NULL_TREE); + tree fld_idx = build3 (COMPONENT_REF, TREE_TYPE (lvar), + lvd->actor_frame, fld_ref, NULL_TREE); local_var.field_idx = fld_idx; SET_DECL_VALUE_EXPR (lvar, fld_idx); DECL_HAS_VALUE_EXPR_P (lvar) = true; diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index df74d886b28..3c0355a1c39 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -9137,9 +9137,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) if (processing_template_decl) continue; tree t = unshare_expr (dexp); - t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, - eltype, t, size_int (i), NULL_TREE, - NULL_TREE); + t = build4 (ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE); SET_DECL_VALUE_EXPR (v[i], t); DECL_HAS_VALUE_EXPR_P (v[i]) = 1; } @@ -9158,9 +9156,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) if (processing_template_decl) continue; tree t = unshare_expr (dexp); - t = build1_loc (DECL_SOURCE_LOCATION (v[i]), - i ? IMAGPART_EXPR : REALPART_EXPR, eltype, - t); + t = build1 (i ? IMAGPART_EXPR : REALPART_EXPR, eltype, t); SET_DECL_VALUE_EXPR (v[i], t); DECL_HAS_VALUE_EXPR_P (v[i]) = 1; } @@ -9184,9 +9180,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) tree t = unshare_expr (dexp); convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]), &t, size_int (i)); - t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, - eltype, t, size_int (i), NULL_TREE, - NULL_TREE); + t = build4 (ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE); SET_DECL_VALUE_EXPR (v[i], t); DECL_HAS_VALUE_EXPR_P (v[i]) = 1; } diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index e4c43fbe8cb..42547f433ed 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -164,7 +164,7 @@ expr_location_or (tree t, location_t loc) /* Similar to protected_set_expr_location, but never modify x in place, if location can and needs to be set, unshare it. */ -static inline tree +tree protected_set_expr_location_unshare (tree x, location_t loc) { if (CAN_HAVE_LOCATION_P (x) diff --git a/gcc/testsuite/g++.dg/analyzer/pr93212.C b/gcc/testsuite/g++.dg/analyzer/pr93212.C index 41507e2b837..1029e8d547b 100644 --- a/gcc/testsuite/g++.dg/analyzer/pr93212.C +++ b/gcc/testsuite/g++.dg/analyzer/pr93212.C @@ -4,8 +4,8 @@ auto lol() { int aha = 3; - return [&aha] { // { dg-warning "dereferencing pointer '.*' to within stale stack frame" } - return aha; + return [&aha] { + return aha; // { dg-warning "dereferencing pointer '.*' to within stale stack frame" } }; /* TODO: may be worth special-casing the reporting of dangling references from lambdas, to highlight the declaration, and maybe fix diff --git a/gcc/testsuite/g++.dg/tree-ssa/value-expr1.C b/gcc/testsuite/g++.dg/tree-ssa/value-expr1.C new file mode 100644 index 00000000000..946ccc3bd97 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/value-expr1.C @@ -0,0 +1,16 @@ +// PR c++/84471 +// { dg-do compile { target c++11 } } +// { dg-additional-options -fdump-tree-gimple-lineno } +// { dg-final { scan-tree-dump-not {value-expr: \[} "gimple" } } + +int main(int argc, char**) +{ + int x = 1; + auto f = [&x, &argc](const char* i) { + i += x; + i -= argc; + i += argc - x; + return i; + }; + f(" "); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/value-expr2.C b/gcc/testsuite/g++.dg/tree-ssa/value-expr2.C new file mode 100644 index 00000000000..4d00498f214 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/value-expr2.C @@ -0,0 +1,26 @@ +// PR c++/107504 +// { dg-do compile { target c++17 } } +// { dg-additional-options -fdump-tree-gimple-lineno } +// { dg-final { scan-tree-dump-not {value-expr: \[} "gimple" } } + +struct S +{ + void* i; + int j; +}; + +S f(char* p) +{ + return {p, 1}; +} + +int main() +{ + char buf[1]; + auto [x, y] = f(buf); + if (x != buf) + throw 1; + if (y != 1) + throw 2; + return 0; +} diff --git a/gcc/tree.cc b/gcc/tree.cc index 92199bb6503..581d4489438 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -5862,6 +5862,9 @@ decl_value_expr_insert (tree from, tree to) { struct tree_decl_map *h; + /* Uses of FROM shouldn't look like they happen at the location of TO. */ + to = protected_set_expr_location_unshare (to, UNKNOWN_LOCATION); + h = ggc_alloc (); h->base.from = from; h->to = to;