From 6952bd117784373d77512b32aadb0273744f8df6 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 2 Aug 2019 17:05:34 +0000 Subject: [PATCH] backport: PR c/90737 - [8/9/10 Regression] inconsistent address of a local converted to intptr_t between callee and caller Backport from mainline PR c/90737 - [8/9/10 Regression] inconsistent address of a local converted to intptr_t between callee and caller gcc/c/ChangeLog: PR c/90737 * c-typeck.c (c_finish_return): Only consider functions returning pointers as candidates for -Wreturn-local-addr. gcc/cp/ChangeLog: PR c/90737 * typeck.c (maybe_warn_about_returning_address_of_local): Only consider functions returning pointers as candidates for -Wreturn-local-addr. gcc/testsuite/ChangeLog: PR c/90737 * c-c++-common/Wreturn-local-addr.c: New test. * g++.dg/warn/Wreturn-local-addr-6.C: New test. From-SVN: r274022 --- gcc/c/ChangeLog | 9 ++++ gcc/c/c-typeck.c | 3 +- gcc/cp/ChangeLog | 10 ++++ gcc/cp/typeck.c | 5 +- gcc/testsuite/ChangeLog | 9 ++++ .../c-c++-common/Wreturn-local-addr.c | 47 +++++++++++++++++++ .../g++.dg/warn/Wreturn-local-addr-6.C | 29 ++++++++++++ 7 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wreturn-local-addr.c create mode 100644 gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 9455a8f68e10..d63517774011 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,12 @@ +2019-08-02 Martin Sebor + + Backport from mainline + 2019-06-05 Martin Sebor + + PR c/90737 + * c-typeck.c (c_finish_return): Only consider functions returning + pointers as candidates for -Wreturn-local-addr. + 2019-08-01 Jakub Jelinek Backported from mainline diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 4e4437540028..4a4eb08b73f9 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -10627,7 +10627,8 @@ c_finish_return (location_t loc, tree retval, tree origtype) if (DECL_P (inner) && !DECL_EXTERNAL (inner) && !TREE_STATIC (inner) - && DECL_CONTEXT (inner) == current_function_decl) + && DECL_CONTEXT (inner) == current_function_decl + && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) { if (TREE_CODE (inner) == LABEL_DECL) warning_at (loc, OPT_Wreturn_local_addr, diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4f04385b5906..af1dfe322b7d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2019-08-02 Martin Sebor + + Backport from mainline + 2019-06-05 Martin Sebor + + PR c/90737 + * typeck.c (maybe_warn_about_returning_address_of_local): Only + consider functions returning pointers as candidates for + -Wreturn-local-addr. + 2019-08-02 Marek Polacek Backported from mainline diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 71daf32733a3..3255af58a25e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -9311,11 +9311,12 @@ maybe_warn_about_returning_address_of_local (tree retval) "returning local initializer_list variable %qD " "does not extend the lifetime of the underlying array", whats_returned); - else if (TREE_CODE (whats_returned) == LABEL_DECL) + else if (POINTER_TYPE_P (valtype) + && TREE_CODE (whats_returned) == LABEL_DECL) w = warning_at (loc, OPT_Wreturn_local_addr, "address of label %qD returned", whats_returned); - else + else if (POINTER_TYPE_P (valtype)) w = warning_at (loc, OPT_Wreturn_local_addr, "address of local variable %qD returned", whats_returned); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ec03b2ca47cd..4371fc722680 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2019-08-02 Martin Sebor + + Backport from mainline + 2019-06-05 Martin Sebor + + PR c/90737 + * c-c++-common/Wreturn-local-addr.c: New test. + * g++.dg/warn/Wreturn-local-addr-6.C: New test. + 2019-08-02 Martin Sebor Backport from mainline diff --git a/gcc/testsuite/c-c++-common/Wreturn-local-addr.c b/gcc/testsuite/c-c++-common/Wreturn-local-addr.c new file mode 100644 index 000000000000..c8c3b9002912 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wreturn-local-addr.c @@ -0,0 +1,47 @@ +/* PR c/90737 - inconsistent address of a local converted to intptr_t + between callee and caller + { dg-do compile } + { dg-options "-O1 -Wall -Wreturn-local-addr -fdump-tree-optimized" } */ + +typedef __INTPTR_TYPE__ intptr_t; + +static inline intptr_t +return_addr_local_as_int (void) +{ + int i; + if ((intptr_t)&i == 0) + __builtin_abort (); + + return (intptr_t)&i; +} + +void get_addr_local_as_int (void) +{ + intptr_t i = return_addr_local_as_int (); + if (i == 0) + __builtin_abort (); +} + + +static inline intptr_t +return_addr_label_as_int (void) +{ + label: + if ((intptr_t)&&label == 0) + __builtin_abort (); + + return (intptr_t)&&label; +} + +void get_addr_label_as_int (void) +{ + intptr_t i = return_addr_label_as_int (); + if (i == 0) + __builtin_abort (); +} + +/* Verify that the functions that return the address of the label + or local variable have been optimized away and so have the calls + to abort. + { dg-final { scan-tree-dump-not "return_addr_" "optimized" } } + { dg-final { scan-tree-dump-not "abort" "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C new file mode 100644 index 000000000000..bfe144575478 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C @@ -0,0 +1,29 @@ +/* PR c/90737 - inconsistent address of a local converted to intptr_t + between callee and caller + { dg-do compile } + { dg-options "-O1 -Wall -Wreturn-local-addr -fdump-tree-optimized" } */ + +typedef __INTPTR_TYPE__ intptr_t; + +const intptr_t& +return_addr_label_as_intref (void) +{ + label: + if ((const intptr_t*)&&label == 0) + __builtin_exit (1); + + return *(const intptr_t*)&&label; // { dg-warning "\\\[-Wreturn-local-addr]" } */ +} + +const intptr_t& +return_addr_local_as_intref (void) +{ + int a[1]; + if ((const intptr_t*)a == 0) + __builtin_exit (1); + + return (const intptr_t&)a; // { dg-warning "\\\[-Wreturn-local-addr]" } */ +} + +/* Verify that the return value has been replaced with zero: + { dg-final { scan-tree-dump-times "return 0;" 2 "optimized" } } */ -- 2.47.2