[Bug c/106920] -Warray-bound false positive regression with -O2 or -Os and constant address
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106920 --- Comment #5 from Dominique Martinet --- hmm this is a pretty complex topic. My problem like pointed out in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578 is more with all the legacy code that I have to deal with, that isn't maintained by anyone, and well the sorry state of embedded systems upstreams in general... So I'm really just sitting there trying to get old code to keep working with my newer gcc version. (I actually wonder why that didn't fail with gcc11, I've been using that for a while...) The solution in that other bug ^ to just not issue warnings for constant addresses is good in general and I was just unlucky that such an address happened below 4k for this code. I don't understand why the ast tree cannot make the difference between a constant address and a constant null pointer macroed to hell, but since that only happens with optimizations enabled I guess some info is lost at that point and there was nothing to do or it would have been done. Anyway, I consider that closed, there's been enough ink spilled in the other thread and thank you all for the quick replies!
[Bug c/106920] -Warray-bound false positive regression with -O2 or -Os and constant address
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106920 --- Comment #2 from Dominique Martinet --- Thanks for the very fast reply! since you mentioned null pointers I now see this warning doesn't happen if I try with a larger constant, I just had bad luck that imx-atf uses an address < 4k...? I checked the first dozen of issues from the meta-bug (from start of open bugs list to 86613 included), but there are just too many and didn't see a workaround in the ones I did open. I can see catching bad casts to be useful, but for low level hardware code accessing register addresses directly is the norm -- I'm not too worried now I've noticed the <4k "rule" but there really can't be any assumption made with hardware, as seen here... (And NXP isn't exactly great at working with external entities, I tried reaching out for another compile fix with little success... but that's offtopic.) Well, good to understand the reason behind that warning at least.
[Bug c/106920] New: -Warray-bound false positive regression with -O2 or -Os
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106920 Bug ID: 106920 Summary: -Warray-bound false positive regression with -O2 or -Os Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: npfhrotynz-ptnqh.myvf at noclue dot notk.org Target Milestone: --- Hello, I think I've run into a false positive on this file: https://source.codeaurora.org/external/imx/imx-atf/tree/plat/imx/imx8m/hab.c?h=lf_v2.6 I could trim it down to this #include typedef void hab_rvt_entry_t(void); int main() { hab_rvt_entry_t *a; a = ((hab_rvt_entry_t *)(*(unsigned long *)(0x908))); a(); return 0; } $ gcc -O2 -Warray-bounds -c t.c t.c: In function ‘main’: t.c:7:34: warning: array subscript 0 is outside array bounds of ‘long unsigned int[0]’ [-Warray-bounds] 7 | a = ((hab_rvt_entry_t *)(*(unsigned long *)(0x908))); | ~^~ According to godbolt this passed on 11.3 and starts emitting the warning on 12.1 (it doesn't have 12.0) and still emits it on trunk. Note the warning requires -O2, -O3 or -Os to be emitted. The problem seems to be that it considers an arbitrary address casted to u64* to be a u64[0] ? If so that might be a problem for quite a few embedded products as that is quite common when dealing with hardware registers. (and who doesn't love products that compile with -Werror for release builds...) Thanks!
[Bug analyzer/103217] analyzer false positive on leak warning when using indirect strdup
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103217 --- Comment #10 from Dominique Martinet --- Thank you for this work! I can confirm this indeed fixed the warning in my application as well, time to add a fanalyzer build to my CI :)
[Bug analyzer/103217] analyzer false positive on leak warning when using indirect strdup
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103217 --- Comment #5 from Dominique Martinet --- Ah, this apparently needed the unused fields in the struct, and the extra config_init() call. Here's something trimmed down from the actual program instead of building back up: - #define _POSIX_C_SOURCE 200809L #include #include #include struct state { const char *confpath; const char *host; const char *port; const char *state_dir_prefix; }; static inline char *xstrdup(const char *s) { char *val = strdup(s); if (!val) abort(); return val; } int config_init(struct state *config); int main(int argc, char *argv[]) { int rc; struct state state = { 0 }; config_init(); while ((rc = getopt(argc, argv, "H:p:")) != -1) { switch (rc) { case 'H': free((void*)state.host); state.host = xstrdup(optarg); break; case 'p': free((void*)state.port); state.port = xstrdup(optarg); break; } } free((void*)state.host); free((void*)state.port); return rc; } - - /opt/gcc/bin/gcc -fanalyzer -c ../copytool/coordinatool.c In function ‘main’: cc1: warning: leak of ‘’ [CWE-401] [-Wanalyzer-malloc-leak] ‘main’: events 1-4 | |../copytool/coordinatool.c:25:5: | 25 | int main(int argc, char *argv[]) { | | ^~~~ | | | | | (1) entry to ‘main’ |.. | 31 | while ((rc = getopt(argc, argv, "H:p:")) != -1) { | |~~~ | | | | | (2) following ‘true’ branch (when ‘rc != -1’)... | 32 | switch (rc) { | | ~~ | | | | | (3) ...to here |.. | 39 | state.port = xstrdup(optarg); | | ~~~ | | | | | (4) calling ‘xstrdup’ from ‘main’ | +--> ‘xstrdup’: events 5-9 | | 16 | static inline char *xstrdup(const char *s) { | | ^~~ | | | | | (5) entry to ‘xstrdup’ | 17 | char *val = strdup(s); | | ~ | | | | | (6) allocated here | 18 | if (!val) | |~ | || | |(7) assuming ‘val’ is non-NULL | |(8) following ‘false’ branch (when ‘val’ is non-NULL)... | 19 | abort(); | 20 | return val; | |~~~ | || | |(9) ...to here | <--+ | ‘main’: event 10 | | 39 | state.port = xstrdup(optarg); | | ^~~ | | | | | (10) returning to ‘main’ from ‘xstrdup’ | ‘main’: event 11 | |cc1: | (11): ‘’ leaks here; was allocated at (6) | - Thanks!
[Bug analyzer/103217] analyzer false positive on leak warning when using indirect strdup
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103217 Dominique Martinet changed: What|Removed |Added Resolution|FIXED |--- Status|RESOLVED|REOPENED --- Comment #4 from Dominique Martinet --- Thanks for the fix! I've compiled gcc from master and can confirm this fixes the warning for the example I provided... But unfortunately it doesn't fix it for my real application, so my reproducer was simplified too much :/ (It fails on this file: https://github.com/cea-hpc/coordinatool/blob/06c5e319e3c934256d51c2af3ba5f7551bac4bff/copytool/coordinatool.c , but this project requires lustre development headers to compile so it's not a good reproducer) Here's a new attempt, this also gives a similar warning without a precise location on gcc master: --- #include #include #include char *xstrdup(const char *src) { char *val = strdup(src); if (!val) abort(); return val; } struct test { char *one, *two; }; int main(int argc, char *argv[]) { struct test *options = calloc(1, sizeof(*options)); int rc; if (!options) abort(); while ((rc = getopt(argc, argv, "a:b:")) != -1) { switch (rc) { case 'a': free(options->one); options->one = xstrdup(optarg); break; case 'b': free(options->two); options->two = xstrdup(optarg); break; } } free(options->one); free(options->two); free(options); return 0; } --- In function ‘main’: cc1: warning: leak of ‘’ [CWE-401] [-Wanalyzer-malloc-leak] ‘main’: events 1-2 | |/tmp/t4.c:16:5: | 16 | int main(int argc, char *argv[]) { | | ^~~~ | | | | | (1) entry to ‘main’ |.. | 19 | if (!options) | |~ | || | |(2) following ‘false’ branch (when ‘options’ is non-NULL)... | ‘main’: event 3 | |cc1: | (3): ...to here | ‘main’: events 4-6 | | 22 | while ((rc = getopt(argc, argv, "a:b:")) != -1) { | |~~^ | | | | | (4) following ‘true’ branch (when ‘rc != -1’)... | 23 | switch (rc) { | | ~~ | | | | | (5) ...to here |.. | 30 | options->two = xstrdup(optarg); | |~~~ | || | |(6) calling ‘xstrdup’ from ‘main’ | +--> ‘xstrdup’: events 7-11 | |5 | char *xstrdup(const char *src) { | | ^~~ | | | | | (7) entry to ‘xstrdup’ |6 | char *val = strdup(src); | | ~~~ | | | | | (8) allocated here |7 | if (!val) | |~ | || | |(9) assuming ‘val’ is non-NULL | |(10) following ‘false’ branch (when ‘val’ is non-NULL)... |8 | abort(); |9 | return val; | |~~~ | || | |(11) ...to here | <--+ | ‘main’: event 12 | | 30 | options->two = xstrdup(optarg); | |^~~ | || | |(12) returning to ‘main’ from ‘xstrdup’ | ‘main’: event 13 | |cc1: | (13): ‘’ leaks here; was allocated at (8) | I'm not sure it's accurate enough for my usecase though: in my project the "option" struct is declared on the stack and not dynamically allocated... and I cannot reproduce with "struct test option = { 0 };" so I'm not sure where this is different; I'll try a bit more and update this ticket if I find a better reproducer. (What do you prefer to move forward -- I've tried reopening the bug but you really fixed something so should I open a new bz instead and keep this resolved?)
[Bug analyzer/99269] False positive -Wanalyzer-malloc-leak/-Wanalyzer-double-free with -fanalyzer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99269 Dominique Martinet changed: What|Removed |Added CC||npfhrotynz-ptnqh.myvf@noclu ||e.notk.org --- Comment #1 from Dominique Martinet --- gcc 11.2.1 20210728 (fc34) does not produce any warning with this, so would be tempted to say it's been fixed.
[Bug analyzer/103217] New: analyzer false positive on leak warning when using indirect strdup
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103217 Bug ID: 103217 Summary: analyzer false positive on leak warning when using indirect strdup Product: gcc Version: 11.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: analyzer Assignee: dmalcolm at gcc dot gnu.org Reporter: npfhrotynz-ptnqh.myvf at noclue dot notk.org Target Milestone: --- Inlining both the reproducer and fanalyzer warning as they are small enough: -- #include #include #include char *xstrdup(const char *src) { char *val = strdup(src); if (!val) abort(); return val; } int main(int argc, char *argv[]) { char *one = NULL, *two = NULL; int rc; while ((rc = getopt(argc, argv, "a:b:")) != -1) { switch (rc) { case 'a': free(one); one = xstrdup(optarg); break; case 'b': free(two); two = xstrdup(optarg); break; } } free(one); free(two); return 0; } -- -- $ gcc -fanalyzer -o t t.c t.c: In function ‘main’: cc1: warning: leak of ‘val’ [CWE-401] [-Wanalyzer-malloc-leak] ‘main’: events 1-4 | |t.c:13:5: | 13 | int main(int argc, char *argv[]) { | | ^~~~ | | | | | (1) entry to ‘main’ |.. | 17 | while ((rc = getopt(argc, argv, "a:b:")) != -1) { | |~~~ | | | | | (2) following ‘true’ branch (when ‘rc != -1’)... | 18 | switch (rc) { | | ~~ | | | | | (3) ...to here |.. | 25 | two = xstrdup(optarg); | | ~~~ | | | | | (4) calling ‘xstrdup’ from ‘main’ | +--> ‘xstrdup’: events 5-9 | |6 | char *xstrdup(const char *src) { | | ^~~ | | | | | (5) entry to ‘xstrdup’ |7 | char *val = strdup(src); | | ~~~ | | | | | (6) allocated here |8 | if (!val) | |~ | || | |(7) assuming ‘val’ is non-NULL | |(8) following ‘false’ branch (when ‘val’ is non-NULL)... |9 | abort(); | 10 | return val; | |~~~ | || | |(9) ...to here | <--+ | ‘main’: event 10 | | 25 | two = xstrdup(optarg); | | ^~~ | | | | | (10) returning to ‘main’ from ‘xstrdup’ | ‘main’: event 11 | |cc1: | (11): ‘val’ leaks here; was allocated at (6) | -- As far as I see the conditions seem to be: - there have to be at least two cases and two variables, adding more than two cases leave the error only on second one; interverting the two makes the error stay on 2nd. Similarly, using the same variable in both cases makes the error go away. - it has to be strdup, replacing strdup with malloc makes the error go away. - it has to be indirected, calling strdup() directly in main (with the same check/abort) makes the error go away. explicit "inline" attribute does not change behaviour. - it doesn't have to be getopt, but there has to be a function call e.g. replacing getopt() with a locally defined iteration function keeps the error, but checking argc/argv directly in the loop makes the error disappear What's also interesting is the event 11 and "(11): ‘val’ leaks here" that points to... nothing at all? There's no line number or any code quoted to refer to. I'm a bit at a loss as to what this could mean, exiting from main? where?
[Bug regression/94436] incompatible-pointer-types warning with container_of
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94436 Dominique Martinet changed: What|Removed |Added Resolution|--- |FIXED Status|UNCONFIRMED |RESOLVED --- Comment #2 from Dominique Martinet --- Sorry I didn't check the latest git, I'm using whatever is shipped in fedora 32's gcc-10.0.1-0.9.fc32 . . . which I now see isn't even the latest ; and upgrading does fix this. Sorry for the noise! And thanks for fast reply.
[Bug regression/94436] New: incompatible-pointer-types warning with container_of
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94436 Bug ID: 94436 Summary: incompatible-pointer-types warning with container_of Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: regression Assignee: unassigned at gcc dot gnu.org Reporter: npfhrotynz-ptnqh.myvf at noclue dot notk.org Target Milestone: --- Created attachment 48157 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48157=edit test program.c This looks like a regression in warnings: passing an argument straight from a container_of construct fails with incompatible type warning. In the attached code, the if 0'd implementation taken from the linux kernel works, but the other one also seen in the linux kernel (why do they have multiple implementations?!) produces the following warning: t.c: In function ‘main’: t.c:14:41: warning: passing argument 1 of ‘func’ from incompatible pointer type [-Wincompatible-pointer-types] 14 | #define container_of(ptr, type, member) (type *)((char *)(ptr) - (char *) &((type *)0)->member) | ^~~ | | | char * t.c:24:14: note: in expansion of macro ‘container_of’ 24 | return func(container_of(, struct foo, bar)); | ^~~~ t.c:17:22: note: expected ‘struct foo *’ but argument is of type ‘char *’ 17 | int func(struct foo* foo) { | ^~~ - Here is -E preprocessed interesting line: return func((struct foo *)((char *)() - (char *) &((struct foo *)0)->bar)); For me the whole thing is cast with (struct foo*) so it should silence that warning as it used to do (tested with gcc 7.4.0 and gcc 9.2.0) In the case I'm looking at I could work around by using the other implementation, but I see that macro defined all the time so would be interested in seeing the old behaviour back. Thanks!
[Bug analyzer/94365] New: false positive leak when using container_of-like constructs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94365 Bug ID: 94365 Summary: false positive leak when using container_of-like constructs Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: analyzer Assignee: dmalcolm at gcc dot gnu.org Reporter: npfhrotynz-ptnqh.myvf at noclue dot notk.org Target Milestone: --- Created attachment 48136 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48136=edit test program.c First, thanks for this awesome feature! I'm not sure how "ready" it is, but there are other open bugs and I did not see this one, so here goes... I'm often using patterns where I return a pointer to an inner field of a struct and then use it with container_of later on. The attached example program gives two warnings; only the first one is interesting to me but figured I could cite both since I stumbled on the second when writing the reproducer... - In function ‘foo’: t.c:22:9: warning: leak of ‘a’ [CWE-401] [-Wanalyzer-malloc-leak] 22 | return >b; | ^ ‘foo’: events 1-5 | | 14 | struct container *a = malloc(sizeof(*a)); | |^~ | || | |(1) allocated here |.. | 19 | if (!a) | | ~ | | | | | (2) assuming ‘a’ is non-NULL | | (3) following ‘false’ branch (when ‘a’ is non-NULL)... |.. | 22 | return >b; | | ~ | | | | | (4) ...to here | | (5) ‘a’ leaks here; was allocated at (1) | - In function ‘main’: t.c:41:2: warning: ‘free’ of ‘’ which points to memory not on the heap [CWE-590] [-Wanalyzer-free-of-non-heap] 41 | free(container_of(b, struct container, b)); | ^~ ‘main’: events 1-2 | | 29 | int main() { | | ^~~~ | | | | | (1) entry to ‘main’ | 30 | struct a_struct *b = foo(); | | ~ | | | | | (2) calling ‘foo’ from ‘main’ | +--> ‘foo’: events 3-5 | | 13 | struct a_struct *foo() { | | ^~~ | | | | | (3) entry to ‘foo’ |.. | 19 | if (!a) | | ~ | | | | | (4) following ‘false’ branch (when ‘a’ is non-NULL)... |.. | 22 | return >b; | | ~ | | | | | (5) ...to here | <--+ | ‘main’: events 6-10 | | 30 | struct a_struct *b = foo(); | | ^ | | | | | (6) returning to ‘main’ from ‘foo’ |.. | 33 | if (!b) | | ~ | | | | | (7) following ‘false’ branch (when ‘b’ is non-NULL)... |.. | 41 | free(container_of(b, struct container, b)); | | ~~ | | | | | (8) ...to here | | (9) pointer is from here | | (10) call to ‘free’ here | - I would think that as long as it is programmatically possible to go back to the allocated pointer (e.g. the return value is a constant offset from malloc value) then there should be no leak. Thanks, -- Dominique Martinet