PR c/90737 - [8/9/10 Regression] inconsistent address of a local converted to intptr_...
authorMartin Sebor <msebor@redhat.com>
Thu, 6 Jun 2019 02:53:01 +0000 (02:53 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Thu, 6 Jun 2019 02:53:01 +0000 (20:53 -0600)
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
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wreturn-local-addr.c [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C [new file with mode: 0644]

index 05f3866185b36bc78c05bffcd3c29cdad5abf3eb..5a0dabbd034c6a259cd9a3666c67c26e0552565a 100644 (file)
@@ -1,3 +1,9 @@
+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
index 5eff040e85dcd69960091f47186f7c8346ecb4c1..0dd86f074b91108b5563ce4e55f7396a7d2a9cd3 100644 (file)
@@ -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,
index 952541a781f70c3df26b6d86ae16f97b8edebf38..1489238b716da23f7b77fc7bf531f9133e41da77 100644 (file)
@@ -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.
index eab800305ec16746fb71586eebe2f826e6160e3c..154da59627b66288c6d1098066b29c4974994a62 100644 (file)
@@ -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);
index 4f58a453387f90be797c08f40f8d9b50c82ba3d2..18a480fcdab85bfc9d5e61f1a80498171719b106 100644 (file)
@@ -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 (file)
index 0000000..c8c3b90
--- /dev/null
@@ -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 (file)
index 0000000..bfe1445
--- /dev/null
@@ -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" } } */