public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "jason at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug c++/103534] [12 regression] Spurious -Wstringop-overflow warning with std::string concatencation
Date: Fri, 10 Dec 2021 16:29:57 +0000	[thread overview]
Message-ID: <bug-103534-4-Mc2e3OP81w@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-103534-4@http.gcc.gnu.org/bugzilla/>

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

Jason Merrill <jason at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P1
                 CC|                            |aldyh at gcc dot gnu.org,
                   |                            |jason at gcc dot gnu.org

--- Comment #5 from Jason Merrill <jason at gcc dot gnu.org> ---
The dataflow analysis seems to be:

We set the length of one string to 0, and the other string to 16.  Then we
store a char to the string buffer, which the compiler thinks could possibly
have clobbered the  length we previously set to 0, so we reload it.  And we add
the two together.  So now we have a combined length about which we think we
know nothing

We should really somehow tell the compiler that stores to the string char
buffer can't alias other non-char objects.  And maybe in general we could do
branch prediction based on assuming that char stores don't clobber values we
knew before?  But let's put that missed-optimization issue in a separate PR.

So, let's focus away from that problem by making the second string unknown:

#include <string>
std::string foo(std::string x)
{
  return std::string("1234567890123456") + x;
}

I get the same surprising warning with this testcase.

Now, we have an unknown total length.  We compare this length to the size of
the local buffer, which partitions the range at 16.  On the path where the sum
of the lengths is <=16, we conclude that the length of string A must either be
0 or a number so large that adding 16 to it causes it to wrap around to [0,16]
(because integer overflow in unsigned arithmetic is defined).  Which branch
prediction thinks is just as likely as 0.

So then along that branch we try to append this impossibly large hypothetical
string to this string we do know the length of, and we get this warning.

So, the warning seems to be that if we were to call _M_append with a
ridiculously large __n argument, we would get undefined behavior.  In other
words, if x happened to be the longest possible string.  It seems that we check
for unreasonable length arguments in the char* append functions, but not in the
string append function.  Changing them to do that check silences the warning. 
I'll attach a patch in a moment.

  parent reply	other threads:[~2021-12-10 16:29 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-02 19:47 [Bug c++/103534] New: " sss@li-snyder.org
2021-12-02 21:03 ` [Bug c++/103534] " msebor at gcc dot gnu.org
2021-12-02 21:53 ` pinskia at gcc dot gnu.org
2021-12-02 23:02 ` redi at gcc dot gnu.org
2021-12-02 23:19 ` msebor at gcc dot gnu.org
2021-12-06  8:16 ` rguenth at gcc dot gnu.org
2021-12-10 16:29 ` jason at gcc dot gnu.org [this message]
2021-12-10 16:30 ` jason at gcc dot gnu.org
2021-12-10 16:37 ` jason at gcc dot gnu.org
2021-12-10 16:53 ` msebor at gcc dot gnu.org
2021-12-10 17:04 ` jakub at gcc dot gnu.org
2021-12-11  4:58 ` cvs-commit at gcc dot gnu.org
2021-12-13 16:11 ` jason at gcc dot gnu.org
2021-12-13 16:11 ` jason at gcc dot gnu.org

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-103534-4-Mc2e3OP81w@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).