public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/96988] New: Bad/missing warnings when returning a temporary from an inlined function
@ 2020-09-08 21:06 blubban at gmail dot com
  2020-09-09  6:46 ` [Bug c++/96988] " rguenth at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: blubban at gmail dot com @ 2020-09-08 21:06 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96988

            Bug ID: 96988
           Summary: Bad/missing warnings when returning a temporary from
                    an inlined function
           Product: gcc
           Version: 10.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: blubban at gmail dot com
  Target Milestone: ---

Minimal testcase:


// compile with: gcc -O2 -Wall bug.cpp

static int * foo()
{
    int a = 42;
    int * b = &a;
    return b;
}

int bar()
{
    return *foo();
}


Result: A misleading warning in wrong function.

<source>: In function 'bar':
<source>:10:12: warning: 'a' is used uninitialized in this function
[-Wuninitialized]
   10 |     return *foo();
      |            ^~~~~~


Expected result: I get a good warning (but the misleading one too) if the buggy
function is not inline, static, or a C++ template.

<source>: In function 'foo':
<source>:5:12: warning: function returns address of local variable
[-Wreturn-local-addr]
    5 |     return b;
      |            ^
<source>:3:9: note: declared here
    3 |     int a = 42;
      |         ^


More realistic example:


// compile with: g++ -O3 -Wall bug.cpp

template<typename T>
const T& max(const T& a) { return a; }
template<typename T, typename... Args>
const T& max(const T& a, Args... args)
{
    // whoops, this creates temporaries with insufficient lifetime if the
arguments aren't same type
    const T& b = max(args...);
    if (a < b) return b;
    else return a;
}

int victim()
{
    return max(1, 2u);
}


(I'm not sure what component this belongs to; please recategorize if wrong.)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/96988] Bad/missing warnings when returning a temporary from an inlined function
  2020-09-08 21:06 [Bug middle-end/96988] New: Bad/missing warnings when returning a temporary from an inlined function blubban at gmail dot com
@ 2020-09-09  6:46 ` rguenth at gcc dot gnu.org
  2020-09-09  9:44 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-09-09  6:46 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96988

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|middle-end                  |c++
             Blocks|                            |24639
           Keywords|                            |diagnostic

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
The important missing thing is indeed

<source>:5:12: warning: function returns address of local variable
[-Wreturn-local-addr]
    5 |     return b;
      |            ^


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639
[Bug 24639] [meta-bug] bug to track all Wuninitialized issues

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/96988] Bad/missing warnings when returning a temporary from an inlined function
  2020-09-08 21:06 [Bug middle-end/96988] New: Bad/missing warnings when returning a temporary from an inlined function blubban at gmail dot com
  2020-09-09  6:46 ` [Bug c++/96988] " rguenth at gcc dot gnu.org
@ 2020-09-09  9:44 ` redi at gcc dot gnu.org
  2020-09-09 11:42 ` blubban at gmail dot com
  2021-12-16 23:50 ` [Bug middle-end/96988] " msebor at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: redi at gcc dot gnu.org @ 2020-09-09  9:44 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96988

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2020-09-09

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug c++/96988] Bad/missing warnings when returning a temporary from an inlined function
  2020-09-08 21:06 [Bug middle-end/96988] New: Bad/missing warnings when returning a temporary from an inlined function blubban at gmail dot com
  2020-09-09  6:46 ` [Bug c++/96988] " rguenth at gcc dot gnu.org
  2020-09-09  9:44 ` redi at gcc dot gnu.org
@ 2020-09-09 11:42 ` blubban at gmail dot com
  2021-12-16 23:50 ` [Bug middle-end/96988] " msebor at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: blubban at gmail dot com @ 2020-09-09 11:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96988

--- Comment #2 from Alfred Agrell <blubban at gmail dot com> ---
Poked this thing a bit more, and discovered that there's no need for inlining,
you can reproduce it just as well with an extra {}.

And if you copy the function a few times, the warnings start pointing to wrong
source location. Is that just another facet of this issue, or is it a separate
bug?


$ gcc -O2 -Wall bug.c

int foo1() { int * b; { int a = 1; b = &a; } return *b; }
int foo2() { int * b; { int a = 2; b = &a; } return *b; }
int foo3() { int * b; { int a = 3; b = &a; } return *b; }
int foo4() { int * b; { int a = 4; b = &a; } return *b; }
int foo5() { int * b; { int a = 5; b = &a; } return *b; }


<source>: In function 'foo1':
<source>:1:54: warning: 'a' is used uninitialized in this function
[-Wuninitialized]
    1 | int foo1() { int * b; { int a = 1; b = &a; } return *b; }
      |                                                     ^~
<source>: In function 'foo2':
<source>:1:29: warning: 'a' is used uninitialized in this function
[-Wuninitialized]
    1 | int foo1() { int * b; { int a = 1; b = &a; } return *b; }
      |                             ^
<source>: In function 'foo3':
<source>:1:29: warning: 'a' is used uninitialized in this function
[-Wuninitialized]
<source>: In function 'foo4':
<source>:1:29: warning: 'a' is used uninitialized in this function
[-Wuninitialized]
<source>: In function 'foo5':
<source>:1:29: warning: 'a' is used uninitialized in this function
[-Wuninitialized]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug middle-end/96988] Bad/missing warnings when returning a temporary from an inlined function
  2020-09-08 21:06 [Bug middle-end/96988] New: Bad/missing warnings when returning a temporary from an inlined function blubban at gmail dot com
                   ` (2 preceding siblings ...)
  2020-09-09 11:42 ` blubban at gmail dot com
@ 2021-12-16 23:50 ` msebor at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: msebor at gcc dot gnu.org @ 2021-12-16 23:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96988

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c++                         |middle-end
                 CC|                            |msebor at gcc dot gnu.org
             Blocks|                            |90556

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
In the test cases in comment #0 the -Wreturn-local-addr warning is defeated by
inlining.  By the time the warning sees the program the body of the static
function has been inlined into its caller and replaced with a read from an
uninitialized variable:

;; Function bar (bar, funcdef_no=1, decl_uid=1981, cgraph_uid=2,
symbol_order=1)

int bar ()
{
  int a;

  <bb 2> [local count: 1073741824]:
  return a_2(D);

}

Running a subset of the -Wreturn-local-addr warning earlier, before inlining,
would make it possible to detect the problem in the C test case but not the one
in the more interesting C++ test case.  That one depends on inlining, but it
would have be diagnosed during inlining.  After the callee is inlined it's too
late.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90556
[Bug 90556] [meta-bug] bogus/missing -Wreturn-local-addr

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-12-16 23:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-08 21:06 [Bug middle-end/96988] New: Bad/missing warnings when returning a temporary from an inlined function blubban at gmail dot com
2020-09-09  6:46 ` [Bug c++/96988] " rguenth at gcc dot gnu.org
2020-09-09  9:44 ` redi at gcc dot gnu.org
2020-09-09 11:42 ` blubban at gmail dot com
2021-12-16 23:50 ` [Bug middle-end/96988] " 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).