public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/100403] New: Bogus "function may return address of local variable" warning
@ 2021-05-03 18:52 lavr at ncbi dot nlm.nih.gov
2021-05-03 19:09 ` [Bug c/100403] " pinskia at gcc dot gnu.org
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: lavr at ncbi dot nlm.nih.gov @ 2021-05-03 18:52 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100403
Bug ID: 100403
Summary: Bogus "function may return address of local variable"
warning
Product: gcc
Version: 10.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: lavr at ncbi dot nlm.nih.gov
Target Milestone: ---
$ gcc --version
gcc (GCC) 10.2.0
$ cat test.c
#include <stdio.h>
#include <string.h>
#define RECLEN 128
struct R {
int head;
int code;
char text[1];
};
const char* fun(int n, const struct R* p)
{
union {
struct R r;
char rec[RECLEN];
} x;
const char* err = 0;
memset(&x, 0, sizeof(x));
if (p)
memcpy(&x.r, p, sizeof(*p));
else
err = "Invalid argument";
if (!err) {
static const char magic[] = "MAGIC";
const char* msg;
if (memcmp(x.rec, magic, sizeof(magic)-1) == 0)
msg = x.rec;
else if (x.r.text[0])
msg = x.r.text;
else
msg = "Error w/code";
if (msg)
printf("%s\n", msg);
if (x.rec <= msg && msg < x.rec + sizeof(x))
err = "Error detected";
else
err = msg;
} else
printf("%s\n", err);
return err;
}
$ gcc -Wall -O2 -c test.c
test.c: In function ‘fun’:
test.c:45:12: warning: function may return address of local variable
[-Wreturn-local-addr]
45 | return err;
| ^~~
test.c:19:7: note: declared here
19 | } x;
| ^
test.c:19:7: note: declared here
Noted that does not matter whether "sizeof(x)" or "sizeof(x.rec)" is used at
the end of the "if()" statement on line 39.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug c/100403] Bogus "function may return address of local variable" warning
2021-05-03 18:52 [Bug c/100403] New: Bogus "function may return address of local variable" warning lavr at ncbi dot nlm.nih.gov
@ 2021-05-03 19:09 ` pinskia at gcc dot gnu.org
2021-05-03 20:14 ` lavr at ncbi dot nlm.nih.gov
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-05-03 19:09 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100403
--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Note, the following condition in the if statement
if (x.rec <= msg && msg < x.rec + sizeof(x))
Is undefined if msg is not in the range of x.rec[0]...x.rec[RECLEN] .
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug c/100403] Bogus "function may return address of local variable" warning
2021-05-03 18:52 [Bug c/100403] New: Bogus "function may return address of local variable" warning lavr at ncbi dot nlm.nih.gov
2021-05-03 19:09 ` [Bug c/100403] " pinskia at gcc dot gnu.org
@ 2021-05-03 20:14 ` lavr at ncbi dot nlm.nih.gov
2021-05-03 20:46 ` [Bug middle-end/100403] " msebor at gcc dot gnu.org
2021-05-03 20:49 ` msebor at gcc dot gnu.org
3 siblings, 0 replies; 5+ messages in thread
From: lavr at ncbi dot nlm.nih.gov @ 2021-05-03 20:14 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100403
--- Comment #2 from lavr at ncbi dot nlm.nih.gov ---
> undefined if msg is not in the range of x.rec[0]...x.rec[RECLEN]
Indeed for the segmented data address space. But in most systems it's linear,
and the warning is then architecture dependent, and is only expected on those,
where the comparison cannot be safely made. Besides, the warning then should
be about that fact, not the return address being of a local variable -- that's
misleading, at best.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug middle-end/100403] Bogus "function may return address of local variable" warning
2021-05-03 18:52 [Bug c/100403] New: Bogus "function may return address of local variable" warning lavr at ncbi dot nlm.nih.gov
2021-05-03 19:09 ` [Bug c/100403] " pinskia at gcc dot gnu.org
2021-05-03 20:14 ` lavr at ncbi dot nlm.nih.gov
@ 2021-05-03 20:46 ` msebor at gcc dot gnu.org
2021-05-03 20:49 ` msebor at gcc dot gnu.org
3 siblings, 0 replies; 5+ messages in thread
From: msebor at gcc dot gnu.org @ 2021-05-03 20:46 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100403
Martin Sebor <msebor at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |diagnostic
Component|c |middle-end
CC| |msebor at gcc dot gnu.org
Resolution|--- |INVALID
Status|UNCONFIRMED |RESOLVED
--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
The warning behaves as designed. There's no way for it tell from the IL that
the function cannot return the address of x:
<bb 7> [local count: 375809640]:
# msg_21 = PHI <"Error w/code"(6), msg_19(10)>
if (&MEM <char[128]> [(void *)&x + 128B] > msg_21)
goto <bb 9>; [50.00%]
else
goto <bb 8>; [50.00%]
<bb 8> [local count: 187904820]:
<bb 9> [local count: 1073741824]:
# err_3 = PHI <msg_21(8), "Invalid argument"(4), "Error detected"(7), "Error
w/code"(6)>
x ={v} {CLOBBER};
return err_3; <<< -Wreturn-local-addr
<bb 10> [local count: 375809641]:
# msg_19 = PHI <&x.r.text(5), &x.rec(3)> <<< x is on stack
__builtin_puts (msg_19);
goto <bb 7>; [100.00%]
}
As Andrew explained, the pointer relational expression is undefined if msg
points to the string literal (changing it to equality avoids the warning). In
addition, and arguably more important, GCC's ability to extract useful
information from pointer relationships is quite limited so it doesn't "see
through" the expression. The underlying problem (and the limitation) can be
reduced to the failure to fold and the false positive for the much simpler test
case below. For a + n to be valid n must be zero or one, and so the function
must return null. If GCC used that to fold the function the warning wouldn't
trigger.
With that, I think the report can be resolved as invalid (I'm sure the pointer
range optimization has its own bug.)
$ cat z.c && gcc -O2 -S -Wall -fdump-tree-isolate-paths=/dev/stdout z.c
void* f (int n)
{
char a[1], *p = a + n;
if (p <= a + 1)
p = 0;
return p;
}
;; Function f (f, funcdef_no=0, decl_uid=1943, cgraph_uid=1, symbol_order=0)
z.c: In function ‘f’:
z.c:6:10: warning: function may return address of local variable
[-Wreturn-local-addr]
6 | return p;
| ^
z.c:3:8: note: declared here
3 | char a[1], *p = a + n;
| ^
SSA replacement table
N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j
p_7 -> { p_2 }
.MEM_8 -> { .MEM_6 }
Incremental SSA update started at block: 2
Number of blocks in CFG: 6
Number of blocks to update: 2 ( 33%)
Removing basic block 3
void * f (int n)
{
char * p;
char a[1];
sizetype _1;
<bb 2> [local count: 1073741824]:
_1 = (sizetype) n_3(D);
p_4 = &a + _1;
if (&MEM <char[1]> [(void *)&a + 1B] >= p_4)
goto <bb 3>; [100.00%]
else
goto <bb 4>; [0.00%]
<bb 3> [local count: 311385128]:
# p_2 = PHI <0B(2)>
a ={v} {CLOBBER};
return p_2;
<bb 4> [count: 0]:
# p_7 = PHI <p_4(2)>
a ={v} {CLOBBER};
return 0B;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug middle-end/100403] Bogus "function may return address of local variable" warning
2021-05-03 18:52 [Bug c/100403] New: Bogus "function may return address of local variable" warning lavr at ncbi dot nlm.nih.gov
` (2 preceding siblings ...)
2021-05-03 20:46 ` [Bug middle-end/100403] " msebor at gcc dot gnu.org
@ 2021-05-03 20:49 ` msebor at gcc dot gnu.org
3 siblings, 0 replies; 5+ messages in thread
From: msebor at gcc dot gnu.org @ 2021-05-03 20:49 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100403
Martin Sebor <msebor at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
See Also| |https://gcc.gnu.org/bugzill
| |a/show_bug.cgi?id=91227
--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> ---
The pointer limitation is discussed in more detail in pr91227.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-05-03 20:49 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-03 18:52 [Bug c/100403] New: Bogus "function may return address of local variable" warning lavr at ncbi dot nlm.nih.gov
2021-05-03 19:09 ` [Bug c/100403] " pinskia at gcc dot gnu.org
2021-05-03 20:14 ` lavr at ncbi dot nlm.nih.gov
2021-05-03 20:46 ` [Bug middle-end/100403] " msebor at gcc dot gnu.org
2021-05-03 20:49 ` msebor at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).