From 65985d787504047cb0a82947f7287138b0c54bc5 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 6 Jun 2019 02:53:01 +0000 Subject: [PATCH] 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: r271985 --- gcc/c/ChangeLog | 6 +++ gcc/c/c-typeck.c | 3 +- gcc/cp/ChangeLog | 7 +++ gcc/cp/typeck.c | 5 +- gcc/testsuite/ChangeLog | 6 +++ .../c-c++-common/Wreturn-local-addr.c | 47 +++++++++++++++++++ .../g++.dg/warn/Wreturn-local-addr-6.C | 29 ++++++++++++ 7 files changed, 100 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 05f3866185b..5a0dabbd034 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +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-06-05 Martin Sebor * c-decl.c (start_decl): Adjust quoting and hyphenation diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 5eff040e85d..0dd86f074b9 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -10628,7 +10628,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 952541a781f..1489238b716 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +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-06-05 Paolo Carlini * decl.c (smallest_type_location): New. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index eab800305ec..154da59627b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -9307,11 +9307,12 @@ maybe_warn_about_returning_address_of_local (tree retval) "returning local % 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 4f58a453387..18a480fcdab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +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-06-05 Hongtao Liu * gcc.target/i386/avx512dq-vfpclasspd-1.c: Adjust scan assember 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 00000000000..c8c3b900291 --- /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 00000000000..bfe14457547 --- /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.30.2