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 middle-end/103483] [12 regression] context-sensitive ranges change triggers stringop-overread Date: Tue, 18 Jan 2022 00:47:13 +0000 [thread overview] Message-ID: <bug-103483-4-f28QDS2BLV@http.gcc.gnu.org/bugzilla/> (raw) In-Reply-To: <bug-103483-4@http.gcc.gnu.org/bugzilla/> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103483 --- Comment #17 from Martin Sebor <msebor at gcc dot gnu.org> --- Jaosn: this is how all middle-end warnings have always behaved. They trigger on invalid statements present in the IL. A statement is considered invalid when any of its operands is out of bounds or in some other way not valid for it (e.g., null in -Wnonnull, or not pointing to the first byte allocated on the heap in -Wfree-nonheap-pointer, or not matching an allocation call in -Wmismatched-dealloc). Warnings don't differentiate between constant operands or those in some range. We have been making more extensive use of ranges since get_range_info() was introduced, but prior to that, -Warray-bounds made use of ranges as well (thanks to VRP). Even in warnings that don't use ranges, constant operands need not be literals: they can be reduced to constants from ranges by various transformations (jump threading is just one of them). For more background please see my two-part article from 2019: Understanding GCC Warnings: https://developers.redhat.com/blog/2019/03/13/understanding-gcc-warnings https://developers.redhat.com/blog/2019/03/13/understanding-gcc-warnings-part-2 It's easy to derive examples from the one in comment #12 or comment #15 showing other similar warnings: replacing the memcpy() call with an array subscript triggers a -Warray-bounds; snprintf() triggers -Wformat-truncation; malloc() triggers -Walloc-size-larger-than; etc. See below. (I also showed an example with -Wnonnull in comment #13. It's issued on the same basis.) It might seem like the common denominator in all these instances is ranges, but they're a red herring. The same effect can be demonstrated without them. The root cause behind them all is that (again) warnings are designed to trigger for apparently reachable invalid IL. See pr54202 for an example from 2012 with -Wfree-nonheap-object. The warning is simply based on what the pointer points to, irrespective of the conditions under which the invalid statement is evaluated. If you consider any of the warnings above false positives you must consider as such all of them. It makes no sense to do something about just a subset of them and not the rest. And to avoid them altogether you have to disable (or at least seriously cripple) all those we've ever added into the middle end. You could, for example, only warn in statements that are reached unconditionally from function entry. Removing them them all from -Wall and making them opt-in would reduce the number of complaints but only as a result of the number of users explicitly enabling the warnings, without actually improving anything (besides, by being included in -Wall most already are opt-in). In any event, any of these alternatives would compromise the security improvements we have invested so much in over the years. The best solution, in my view, is to show users the conditionals under which the invalid statements can be reached. I hoped to be able to do that by extending Ranger (https://gcc.gnu.org/pipermail/gcc/2021-December/237922.html) but it could also be done by rolling a range propagation engine just for warnings (like for the static analyzer). char *sink; __attribute__ ((noipa)) int mystrlen (const char *p) { return __builtin_strlen (p); } inline void copy(const char *p) { int L = mystrlen (p); if (L < 5) /* Small string magic. */; else *sink = p[L]; } void f() { copy ("12"); } In function ‘copy’, inlined from ‘f’ at a.c:18:3: a.c:14:13: warning: array subscript [5, 2147483647] is outside array bounds of ‘char[3]’ [-Warray-bounds] 14 | *sink = p[L]; | ~^~~ char *sink; __attribute__ ((noipa)) int mystrlen (const char *p) { return __builtin_strlen (p); } inline void copy(const char *p) { int L = mystrlen (p); if (L < 5) /* Small string magic. */; else __builtin_snprintf (sink, 5, "%*s", L, p); } void f() { copy ("12"); } a.c: In function ‘f’: a.c:14:38: warning: ‘__builtin_snprintf’ output truncated before the last format character [-Wformat-truncation=] 14 | __builtin_snprintf (sink, 5, "%*s", L, p); | ^ In function ‘copy’, inlined from ‘f’ at a.c:18:3: a.c:14:5: note: ‘__builtin_snprintf’ output between 6 and 2147483648 bytes into a destination of size 5 14 | __builtin_snprintf (sink, 5, "%*s", L, p); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ gcc -O2 -S -Walloc-size-larger-than=4 a.c har *sink; __attribute__ ((noipa)) int mystrlen (const char *p) { return __builtin_strlen (p); } inline void copy(const char *p) { int L = mystrlen (p); if (L < 5) /* Small string magic. */; else sink = __builtin_malloc (L); } void f() { copy ("12"); } In function ‘copy’, inlined from ‘f’ at a.c:18:3: a.c:14:12: warning: argument 1 range [5, 2147483647] exceeds maximum object size 4 [-Walloc-size-larger-than=] 14 | sink = __builtin_malloc (L); | ^~~~~~~~~~~~~~~~~~~~ a.c:14:12: note: in a call to built-in allocation function ‘__builtin_malloc’
next prev parent reply other threads:[~2022-01-18 0:47 UTC|newest] Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-11-30 4:27 [Bug c++/103483] New: constexpr basic_string " john at mcfarlane dot name 2021-11-30 4:39 ` [Bug c++/103483] context-sensitive ranges change " pinskia at gcc dot gnu.org 2021-11-30 12:11 ` redi at gcc dot gnu.org 2021-11-30 17:56 ` [Bug middle-end/103483] " msebor at gcc dot gnu.org 2021-11-30 18:13 ` msebor at gcc dot gnu.org 2021-11-30 22:33 ` john at mcfarlane dot name 2021-12-01 16:38 ` aldyh at gcc dot gnu.org 2021-12-01 16:53 ` redi at gcc dot gnu.org 2021-12-01 23:38 ` pinskia at gcc dot gnu.org 2021-12-01 23:44 ` pinskia at gcc dot gnu.org 2021-12-02 22:14 ` msebor at gcc dot gnu.org 2021-12-09 23:24 ` cvs-commit at gcc dot gnu.org 2021-12-10 22:10 ` jason at gcc dot gnu.org 2021-12-11 0:56 ` msebor at gcc dot gnu.org 2021-12-11 22:43 ` jason at gcc dot gnu.org 2022-01-17 22:44 ` [Bug middle-end/103483] [12 regression] " jason at gcc dot gnu.org 2022-01-17 23:10 ` amacleod at redhat dot com 2022-01-18 0:47 ` msebor at gcc dot gnu.org [this message] 2022-01-28 2:02 ` pinskia at gcc dot gnu.org 2022-01-28 5:03 ` jason at gcc dot gnu.org 2022-01-28 6:38 ` law at gcc dot gnu.org 2022-01-28 7:48 ` redi at gcc dot gnu.org 2022-01-28 15:23 ` law at gcc dot gnu.org 2022-03-09 14:11 ` rguenth at gcc dot gnu.org 2022-03-14 23:58 ` msebor at gcc dot gnu.org 2022-05-06 8:32 ` [Bug middle-end/103483] [12/13 " jakub at gcc dot gnu.org 2022-10-19 9:43 ` rguenth at gcc dot gnu.org 2023-05-08 12:23 ` [Bug middle-end/103483] [12/13/14 " rguenth 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-103483-4-f28QDS2BLV@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: linkBe 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).