aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-06-06 02:53:01 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-06-05 20:53:01 -0600
commit65985d787504047cb0a82947f7287138b0c54bc5 (patch)
tree64d80c6241d50dde32f1122d2cf47c9f5236dad0
parent3146ec83db7e65982776a979b8c75883202a4e90 (diff)
downloadgcc-65985d787504047cb0a82947f7287138b0c54bc5.zip
gcc-65985d787504047cb0a82947f7287138b0c54bc5.tar.gz
gcc-65985d787504047cb0a82947f7287138b0c54bc5.tar.bz2
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
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-typeck.c3
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/typeck.c5
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/c-c++-common/Wreturn-local-addr.c47
-rw-r--r--gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C29
7 files changed, 100 insertions, 3 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 05f3866..5a0dabb 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,5 +1,11 @@
2019-06-05 Martin Sebor <msebor@redhat.com>
+ 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 <msebor@redhat.com>
+
* c-decl.c (start_decl): Adjust quoting and hyphenation
in diagnostics.
(finish_decl): Same.
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 5eff040..0dd86f0 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 952541a..1489238 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2019-06-05 Martin Sebor <msebor@redhat.com>
+
+ 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 <paolo.carlini@oracle.com>
* decl.c (smallest_type_location): New.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index eab8003..154da59 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 %<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 4f58a45..18a480f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-06-05 Martin Sebor <msebor@redhat.com>
+
+ 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 <hongtao.liu@intel.com>
* 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 0000000..c8c3b90
--- /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 0000000..bfe1445
--- /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" } } */