public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "msebor at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug tree-optimization/104069] -Werror=use-after-free false positive on elfutils-0.186
Date: Tue, 18 Jan 2022 22:03:54 +0000	[thread overview]
Message-ID: <bug-104069-4-rciasftFd4@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-104069-4@http.gcc.gnu.org/bugzilla/>

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amacleod at redhat dot com

--- Comment #6 from Martin Sebor <msebor at gcc dot gnu.org> ---
Thanks.  The new test case can be reduced to this:

void *xrealloc (void *ptr, int size)
{
  void *ret = __builtin_realloc (ptr, size);
  if (!ret && !size)
    ret = __builtin_realloc (ptr, 1);
  if (!ret) {
    ret = __builtin_realloc (ptr, size);   <<< -Wuse-after-free
    if (!ret && !size)
      ret = __builtin_realloc(ptr, 1);     <<< -Wuse-after-free
    if (!ret)
      __builtin_abort ();
  }
  return ret;
}

I don't see a bug in the warning code but let me CC Andrew for his comments on
the Ranger behavior.

The warnings are false positives but I'm afraid I don't see a bug in the
implementation.  Both trigger (at level 2) because the code is unable to rule
out that the successfully reallocated pointer isn't used in a subsequent call
to realloc().  In the unptimized IL the annotated flow for the first warning is
below.  It shows that the realloc(ptr) statement in bb 8 isn't reachable with a
nonnull ret_13 (i.e., after a successful call to realloc(ptr) in bb 2) but the
range query for the value of ret_13 in bb 8 returns an unknown (i.e., either
null or nonnull).

Andrew, this is determined by the following test art
gimple-ssa-warn-access.cc:4152:

              if (m_ptr_qry.rvals->range_of_expr (vr, realloc_lhs, use_stmt))

realloc_lhs is ret_13 and use_stmt is ret_19 = __builtin_realloc (ptr_11(D),
1).  debug_ranger() shows that bb 5 exports ret_3 == 0 but not ret_13 (which is
implied by the ret_3 equality to zero).  Is this a limitation I need to be
prepared for?

void * xrealloc (void * ptr, int size)
{
  void * ret;
  void * D.1996;
  long unsigned int _1;
  long unsigned int _2;
  void * _21;

  <bb 2> :
  _1 = (long unsigned int) size_9(D);
  ret_13 = __builtin_realloc (ptr_11(D), _1);
  if (ret_13 == 0B)
    goto <bb 3>; [INV]                          >>> ret_13 == 0
  else
    goto <bb 5>; [INV]                          >>> ret_13 != 0

  <bb 3> :
  if (size_9(D) == 0)
    goto <bb 4>; [INV]
  else
    goto <bb 5>; [INV]

  <bb 4> :
  ret_15 = __builtin_realloc (ptr_11(D), 1);    <<< ret_13 == 0

  <bb 5> :
  # ret_3 = PHI <ret_13(2), ret_13(3), ret_15(4)>
  if (ret_3 == 0B)
    goto <bb 6>; [INV]                          >>> ret_13 == 0 && ret_3 == 0
  else
    goto <bb 11>; [INV]

  <bb 6> :
  _2 = (long unsigned int) size_9(D);
  ret_17 = __builtin_realloc (ptr_11(D), _2);
  if (ret_17 == 0B)
    goto <bb 7>; [INV]                          >>> ret_13 == 0 && ret_3 == 0
&& ret_17 == 0
  else
    goto <bb 9>; [INV]

  <bb 7> :
  if (size_9(D) == 0)
    goto <bb 8>; [INV]                          >>> ret_13 == 0 && ret_3 == 0
&& ret_17 == 0 && size_9 == 0
  else
    goto <bb 9>; [INV]

  <bb 8> :                                      <<< ret_13 need not be 0 here
  ret_19 = __builtin_realloc (ptr_11(D), 1);    <<< -Wuse-after-free

  <bb 9> :
  # ret_4 = PHI <ret_17(6), ret_17(7), ret_19(8)>
  if (ret_4 == 0B)
    goto <bb 10>; [INV]
  else
    goto <bb 11>; [INV]

  <bb 10> :
  __builtin_abort ();

  <bb 11> :
  # ret_5 = PHI <ret_3(5), ret_4(9)>
  _21 = ret_5;

  <bb 12> :
<L12>:
  return _21;

}

In the optimized IL (at -O2 below), it looks like the same issue.  Again, the
IL makes it clear that the call to realloc(ptr) in bb 5 where the warning
triggers isn't reachable after a successful prior realloc(), 

void * xrealloc (void * ptr, int size)
{
  void * ret;
  long unsigned int _1;
  _Bool _2;
  _Bool _3;
  _Bool _4;
  _Bool _5;
  _Bool _6;

  <bb 2> [local count: 1073741824]:
  _1 = (long unsigned int) size_13(D);
  ret_17 = __builtin_realloc (ptr_15(D), _1);
  _2 = ret_17 == 0B;
  _3 = size_13(D) == 0;
  _4 = _2 & _3;
  if (_4 != 0)
    goto <bb 3>; [33.00%]                       >>> ret_17 == 0
  else
    goto <bb 4>; [67.00%]                       >>> ret_17 need not be 0

  <bb 3> [local count: 354334800]:
  ret_19 = __builtin_realloc (ptr_15(D), 1);

  <bb 4> [local count: 1073741824]:
  # ret_7 = PHI <ret_17(2), ret_19(3)>
  if (ret_7 == 0B)
    goto <bb 5>; [0.04%]                        >>> ret_7 == 0 implies ret_17
== 0
  else
    goto <bb 9>; [99.96%]

  <bb 5> [local count: 429496]:                 <<< ret_17 == 0 but query
returns unknown
  ret_21 = __builtin_realloc (ptr_15(D), _1);   <<< -Wuse-after-free

  parent reply	other threads:[~2022-01-18 22:03 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-17 17:18 [Bug c/104069] New: " slyfox at gcc dot gnu.org
2022-01-17 17:27 ` [Bug tree-optimization/104069] " pinskia at gcc dot gnu.org
2022-01-17 17:29 ` slyfox at gcc dot gnu.org
2022-01-17 19:10 ` msebor at gcc dot gnu.org
2022-01-17 21:52 ` msebor at gcc dot gnu.org
2022-01-18  9:37 ` slyfox at gcc dot gnu.org
2022-01-18 22:03 ` msebor at gcc dot gnu.org [this message]
2022-01-18 22:06 ` [Bug middle-end/104069] " msebor at gcc dot gnu.org
2022-01-18 22:17 ` jakub at gcc dot gnu.org
2022-01-18 22:47 ` msebor at gcc dot gnu.org
2022-01-18 22:56 ` jakub at gcc dot gnu.org
2022-01-19  0:51 ` amacleod at redhat dot com
2022-01-19  1:04 ` cvs-commit at gcc dot gnu.org
2022-01-19 20:22 ` msebor at gcc dot gnu.org
2022-01-19 20:24 ` msebor at gcc dot gnu.org
2022-01-19 20:30 ` pinskia at gcc dot gnu.org
2022-01-19 20:31 ` pinskia at gcc dot gnu.org
2022-01-19 20:32 ` msebor at gcc dot gnu.org
2022-01-19 20:34 ` jakub at gcc dot gnu.org
2022-01-19 20:42 ` jakub at gcc dot gnu.org
2022-01-19 20:54 ` msebor at gcc dot gnu.org
2022-01-31 11:18 ` jakub at gcc dot gnu.org
2022-03-17 19:32 ` msebor at gcc dot gnu.org
2022-05-16 14:14 ` eike@sf-mail.de
2022-08-24  8:51 ` vincent at systemli dot org
2022-10-27 16:57 ` mark at gcc dot gnu.org
2022-10-28  7:36 ` slyfox at gcc dot gnu.org
2023-05-10  3:35 ` [Bug middle-end/104069] Wuse-after-free=2 -O0 false positive "may be used" mkaracsony81 at gmail dot com
2023-05-12  7:00 ` slyfox at gcc dot gnu.org
2023-05-12  8:30 ` mkaracsony81 at gmail dot com
2023-05-12  9:08 ` slyfox at gcc dot gnu.org
2023-05-12 13:20 ` mkaracsony81 at gmail dot com
2023-05-12 20:36 ` slyfox at gcc dot gnu.org
2023-05-13  5:07 ` mkaracsony81 at gmail dot com
2023-05-13  5:07 ` mkaracsony81 at gmail dot com
2023-12-17  4:40 ` lavr at ncbi dot nlm.nih.gov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-104069-4-rciasftFd4@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).