Summary: | [8 Regression] inconsistent address of a local converted to intptr_t between callee and caller | ||
---|---|---|---|
Product: | gcc | Reporter: | Martin Sebor <msebor> |
Component: | c | Assignee: | Martin Sebor <msebor> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | jakub |
Priority: | P2 | Keywords: | diagnostic, patch, wrong-code |
Version: | 9.0 | ||
Target Milestone: | 9.2 | ||
Host: | Target: | ||
Build: | Known to work: | 4.9.4 | |
Known to fail: | 5.1.0, 6.4.0, 7.3.0, 8.2.0 | Last reconfirmed: | 2019-06-03 00:00:00 |
Bug Depends on: | |||
Bug Blocks: | 90556 |
Description
Martin Sebor
2019-06-03 19:07:52 UTC
The warning for this code goes at least as far back as GCC 4.1. The inconsistency between the callee and the caller started in GCC 4.9. Author: msebor Date: Thu Jun 6 02:53:01 2019 New Revision: 271985 URL: https://gcc.gnu.org/viewcvs?rev=271985&root=gcc&view=rev Log: 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. Added: trunk/gcc/testsuite/c-c++-common/Wreturn-local-addr.c trunk/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C Modified: trunk/gcc/c/ChangeLog trunk/gcc/c/c-typeck.c trunk/gcc/cp/ChangeLog trunk/gcc/cp/typeck.c trunk/gcc/testsuite/ChangeLog I don't understand very well why the cast to an integer before returning is relevant. What if I return the pointer, and convert it to an integer afterwards in the caller? Or what if there is no cast, but I test if the pointer is NULL both in the caller and the callee? What if I return an integer, and then cast it to a pointer in the caller? This optimization was always a bit borderline, I am trying to understand the difference better. (In reply to Marc Glisse from comment #5) Returning a pointer to a local and converting it to an integer in the caller is undefined because the pointer is indeterminate. If there is no cast to an integer in the return statement in the callee but the pointer is tested for equality to NULL both in the caller and the callee, the behavior of the test in the caller is also undefined. If a pointer is converted to an integer, returned, and then cast back to a pointer in the caller, the behavior (of the cast) is implementation defined (opinions might vary here whether that could include undefined since the result is indeterminate). What is well-defined is storing the pointer in some integer X, and b) returning the pointer as an integer R, and the comparing X == R: the result must be true. I see the transformation to null as helpful in avoiding accidentally accessing some other function's stack (not so much as an optimization). Please consider backporting for GCC 9.2. Author: msebor Date: Fri Aug 2 17:05:34 2019 New Revision: 274022 URL: https://gcc.gnu.org/viewcvs?rev=274022&root=gcc&view=rev Log: 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. Added: branches/gcc-9-branch/gcc/testsuite/c-c++-common/Wreturn-local-addr.c branches/gcc-9-branch/gcc/testsuite/g++.dg/warn/Wreturn-local-addr-6.C Modified: branches/gcc-9-branch/gcc/c/ChangeLog branches/gcc-9-branch/gcc/c/c-typeck.c branches/gcc-9-branch/gcc/cp/ChangeLog branches/gcc-9-branch/gcc/cp/typeck.c branches/gcc-9-branch/gcc/testsuite/ChangeLog GCC 8.4.0 has been released, adjusting target milestone. The GCC 8 branch is being closed, fixed in GCC 9.2. |