Summary: | wrong location in -Wreturn-local-addr for a return with a conditional expression | ||
---|---|---|---|
Product: | gcc | Reporter: | Martin Sebor <msebor> |
Component: | middle-end | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | NEW --- | ||
Severity: | minor | CC: | webrown.cpp |
Priority: | P3 | Keywords: | diagnostic |
Version: | 9.0 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2020-01-27 00:00:00 | |
Bug Depends on: | |||
Bug Blocks: | 90556 |
Description
Martin Sebor
2019-07-01 22:51:31 UTC
This warning is generated in gimple-ssa-isolate-paths.c. I'm not sure this a middle-end issue. The path isolation pass uses the location of the return statement to issue the warning. In C, the location is that of the whole operand to the statement. That also doesn't seem quite right but it's less confusing than in C++ where the location corresponds to just one of the operand (the second one?). When the operand is not the address of a local variable it's plain wrong. The difference in the location between C and C++ can be seen as early as the Gimple dump. It only shows the beginning location so it's not complete but it's the starting location that's the problem. Here's C: $ cat a.C && gcc -O2 -S -Wall -fdump-tree-gimple-lineno=/dev/stdout -xc a.C void* g (int i) { extern int j; return i ? &i : &j; } g (int i) [a.C:2:1] { void * D.1913; int * iftmp.0; extern int j; [a.C:4:12] i.1_1 = i; [a.C:5:13] if (i.1_1 != 0) goto <D.1915>; else goto <D.1916>; <D.1915>: [a.C:5:13] iftmp.0 = [a.C:5:10] &i; goto <D.1917>; <D.1916>: [a.C:5:13] iftmp.0 = [a.C:6:10] &j; <D.1917>: [a.C:5:13] D.1913 = iftmp.0; [a.C:5:13] return D.1913; } a.C: In function ‘g’: a.C:5:13: warning: function may return address of local variable [-Wreturn-local-addr] 4 | return i ? | ~~~ 5 | &i : | ~~~^ 6 | &j; | ~~ a.C:1:14: note: declared here 1 | void* g (int i) | ~~~~^ and here's the dump for the same test case compiled as C++: g (int i) [a.C:6:12] { void * D.2304; int * iftmp.0; extern int j; [a.C:6:11] i.1_1 = i; [a.C:6:11] if (i.1_1 != 0) goto <D.2306>; else goto <D.2307>; <D.2306>: [a.C:6:11] iftmp.0 = [a.C:5:10] &i; goto <D.2308>; <D.2307>: [a.C:6:11] iftmp.0 = [a.C:6:10] &j; <D.2308>: [a.C:6:11] D.2304 = iftmp.0; [a.C:6:11] return D.2304; } |