[Bug tree-optimization/109290] warning: array subscript -50 is outside array bounds of ‘struct kobject[36028797018963967]’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109290 lavr at ncbi dot nlm.nih.gov changed: What|Removed |Added CC||lavr at ncbi dot nlm.nih.gov --- Comment #4 from lavr at ncbi dot nlm.nih.gov --- GCC 11.4 produces the same warning on code as simple as this: char buf[128]; char* c, q; // buf is filled with some contents from a read() if (!*(c = buf + strcspn(buf, kDigits))) return 0; q = c > buf ? c[-1] : '\0'; // THIS LINE GETS A WARNING array subscript -1 is outside array bounds of 'char[128]' [-Warray-bounds] Note that there's an explicit check that c > buf before accessing the index backwards.
[Bug middle-end/104069] Wuse-after-free=2 -O0 false positive "may be used"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104069 lavr at ncbi dot nlm.nih.gov changed: What|Removed |Added CC||lavr at ncbi dot nlm.nih.gov --- Comment #35 from lavr at ncbi dot nlm.nih.gov --- I'm still seeing this bogus warning for code as simple as this: if (!(buf = (char*) realloc(var, newsize)) { free(var); // THIS LINE GETS A WARNING HERE return 0; } with GCC 13.2: warning: pointer 'var' may be used after 'realloc' [-Wuse-after-free]
[Bug libstdc++/108561] std::endl causes a flush on a bad stream
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108561 --- Comment #3 from lavr at ncbi dot nlm.nih.gov --- Also, the standard seems to mention that flush() is an "unformatted output function", meaning it is supposed to build and check a sentry object (which in case of a bad stream, would fail, so it's not going to proceed with pubsync()). In GCC implementation, the sentry is not constructed, and the comment in the source code seems to contradict with the standard: // basic_ostream::flush() is *not* an unformatted output function. ios_base::iostate __err = ios_base::goodbit; __try { if (this->rdbuf() && this->rdbuf()->pubsync() == -1) __err |= ios_base::badbit; } If the flush() implementation followed the standard, then the implementation of endl could be left alone (unconditional chained flush).
[Bug libstdc++/108561] std::endl causes a flush on a bad stream
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108561 --- Comment #2 from lavr at ncbi dot nlm.nih.gov --- Indeed, it does not. But the reason the endl manipulator is there, is to flush _after_ '\n'. If the stream has gone bad in between, it is the gray area, but for the output device (the stream buffer), it's an intentional corruption.
[Bug libstdc++/108561] New: std::endl causes a flush on a bad stream
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108561 Bug ID: 108561 Summary: std::endl causes a flush on a bad stream Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- As implemented: template inline basic_ostream<_CharT, _Traits>& endl(basic_ostream<_CharT, _Traits>& __os) { return flush(__os.put(__os.widen('\n'))); } this code can cause flush() to be called for a stream that has gone bad during the execution of put(). Note that put() constructs a sentry, which if it threw an exception, would case the stream to get a badbit (the most severe case; but other unsuccessful sentry construction errors fit the same pattern). On the other hand, flush() does not check for any such things -- there's no sentry construction -- instead, it just blindly calls the underlying stream buffer's pubsync(). The bottom line result is that the failed output is missing yet the flush is still attempted, but the expected behavior is that the output should be _followed_ by the flush. Otherwise, the order of the expected I/O is wrong (the flush appears out of order when put() failed). A fix would be to do something like this: __os = __os.put(__os.widen('\n'); return __os ? flush(__os) : __os;
[Bug c/107465] New: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107465 Bug ID: 107465 Summary: Bogus warning: promoted bitwise complement of an unsigned value is always nonzero Product: gcc Version: 11.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- Tried on both Ubuntu and Cygwin, the same gcc-11.3.0 -- and the same problem: $ gcc --version gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ gcc --version gcc (GCC) 11.3.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. The code: $ cat test.c extern void fun2(void); #ifdef BOGUS_WARNING typedef unsigned short uint2; #else #define uint2 unsigned short #endif static void fun(uint2 x) { if (!(x ^ 0x)) fun2(); } int main(void) { fun(0); } The compilation: $ gcc -Wall -Wextra -O6 -c test.c (clean) BUT: $ gcc -Wall -Wextra -O6 -c -DBOGUS_WARNING test.c test.c: In function ‘fun’: test.c:11:9: warning: promoted bitwise complement of an unsigned value is always nonzero [-Wsign-compare] 11 | if (!(x ^ 0x)) | ^ The variable "x" is an unsigned short, so it gets promoted to int without the sign extension; the second argument to XOR is a 32-bit int with only 16 bits set to 1. The result of XOR is not necessarily non-0 because it does not flip all the bits in an int, but only the lower 16 (so there's no promotion of any sort, IMO). Also, it's weird that the warning is only issued with a typedef for the type of "x".
[Bug c/96293] Extraneously noisy "taking address of packed member may result in an unaligned pointer value"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96293 --- Comment #10 from lavr at ncbi dot nlm.nih.gov --- > In your code, `>record.data[0]` is not a well-aligned access It is well-aligned, its offset gets printed out by the very test code, and it's 2. > because `struct attribute` is defined as packed, so compiler has no any > information about where `a` itself is aligned to. Are you kidding me? "a" is an automatic object on stack, which compiler itself allocates. So it is well-aligned, for sure. Even if "a" was coming as an argument of a function call (via a pointer), the compiler should assume it's aligned, because it always does for any other regular structures.
[Bug c/96293] Extraneously noisy "taking address of packed member may result in an unaligned pointer value"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96293 --- Comment #8 from lavr at ncbi dot nlm.nih.gov --- Consider the following code: struct record { unsigned char len; unsigned short data[5]; } __attribute__((packed)); struct attribute { unsigned char code; struct record record; } __attribute__((packed)); If I had "struct attribute* a" in my code then ">record.data[0]" would be a well-aligned access, even though "struct record" is not "properly aligned". If I had "struct record" defined with the align(2) attribute (to cater to "short"s), it might have been placed in "struct attribute" at offset 2, leaving a one byte gap after the "code" member. Newer gcc gives even more warnings where there should be none (but fortunately, it does not leave a gap: I can't check the behavior with GCC 9 anymore because I do no longer have it). $ cat align.c #include #ifdef ALIGN2 # define ALIGN __attribute__((packed, aligned(2))) #else # define ALIGN __attribute__((packed)) #endif void fun(unsigned short* n) { *n = 0xCAFE; } struct record { unsigned char len; unsigned short data[5]; } ALIGN; struct attribute { unsigned char code; struct record record; } __attribute__((packed)); int main() { struct attribute a; printf("offsetof data = %zu\n", offsetof(struct attribute, record.data[0])); fun([0]); return 0; } $ gcc -Wall -o align align.c align.c: In function ‘main’: align.c:34:9: warning: taking address of packed member of ‘struct record’ may result in an unaligned pointer value [-Waddress-of-packed-member] 34 | fun([0]); | ^ $ ./align offsetof data = 2 $ gcc -Wall -DALIGN2 -o align align.c align.c:26:1: warning: alignment 1 of ‘struct attribute’ is less than 2 [-Wpacked-not-aligned] 26 | } __attribute__((packed)); | ^ align.c:25:19: warning: ‘record’ offset 1 in ‘struct attribute’ isn’t aligned to 2 [-Wpacked-not-aligned] 25 | struct record record; | ^~ align.c: In function ‘main’: align.c:34:9: warning: taking address of packed member of ‘struct record’ may result in an unaligned pointer value [-Waddress-of-packed-member] 34 | fun([0]); | ^ $ ./align offsetof data = 2
[Bug c/96293] Extraneously noisy "taking address of packed member may result in an unaligned pointer value"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96293 --- Comment #7 from lavr at ncbi dot nlm.nih.gov --- The problem with the aligned(4) attribute is that if this structure appears as a member of an outer packed structure, it may not be "enclosed" properly without a gap. The warnings are pointless is they are emitted for members that are located already aligned to their native boundaries. GCC is perfectly aware of all the offsets and it so can only warn of those, which are indeed off. Otherwise, it's the same if GCC begins warning about taking address of any member, whose structure pointer was passed to a function, because that pointer may not be assumed as properly aligned (any structure pointer passed to a function is align(1) because the pointer's origin may not be generally even known!). But that'd be ridiculous!
[Bug middle-end/106092] Bogus -Wfree-nonheap-object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106092 --- Comment #2 from lavr at ncbi dot nlm.nih.gov --- Created attachment 53201 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53201=edit preprocessed source Attached! It's rather big
[Bug c++/106092] New: Bogus -Wfree-nonheap-object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106092 Bug ID: 106092 Summary: Bogus -Wfree-nonheap-object Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- I got the following report from the compilation: In file included from /home/ANTON/cxx/src/util/qparse/parser.cpp:352: query_parser_bison.tab.c: In function ‘int ncbi_q_parse(void*)’: query_parser_bison.tab.c:2354:18: warning: ‘void free(void*)’ called on unallocated object ‘yyssa’ [-Wfree-nonheap-object] In file included from /home/ANTON/cxx/src/util/qparse/parser.cpp:352: query_parser_bison.tab.c:1351:18: note: declared here The thing is, the code which is "blamed", looks like this (line numbers on): 2353 if (yyss != yyssa) 2354 YYSTACK_FREE (yyss); which obviously tells NOT to free if the "yyss" is the same as "yyssa"... So it's unclear from which context GCC "figured" that yyssa is going to be freed. The declarations look like this: 1350 /* The state stack. */ 1351 yytype_int16 yyssa[YYINITDEPTH]; 1352 yytype_int16 *yyss; 1353 yytype_int16 *yyssp; 1384 yyss = yyssa; so at some point, yyss gets assigned with yyssa. But then again, the code instructs exactly NOT to free, in this case. There's nothing to warn about.
[Bug tree-optimization/103835] bogus sprintf warnings due to missing strlen propagation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103835 --- Comment #4 from lavr at ncbi dot nlm.nih.gov --- Thank you for investigating this! Like I said, it's better NOT to emit any warnings if some machinery in the compiler is not perfect enough to recognize the danger correctly (as it used to be the case in previous versions and so they were silent in this respect). There is the second warning there, too, which seems not being addressed by the discussion. Not only the count (499) is not given correctly (but maybe it's because of the constant propagation that was mentioned), there's the second part (the note), which follows, and which looks extremely bad and unintelligent w.r.t. the output size calculation: test.c:8:21: warning: ‘a = ’ directive writing 4 bytes into a region of size between 0 and 499 [-Wformat-overflow=] 8 | sprintf(buf, "%sa = %d\n" | ^~~~ test.c:8:5: note: ‘sprintf’ output between 13 and 1031 bytes into a destination of size 499 Is this the same cause, too?
[Bug tree-optimization/103835] Bogus sprintf warnings
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103835 --- Comment #2 from lavr at ncbi dot nlm.nih.gov --- Irrespective of whether atoi() is known, printing an "int" (or two) will never produce this many characters... This, however, also seems to have triggered some weird logic that took the entire size of buf[] as a possible size of "pfx" on output; hence, the warning noted 1000+ characters to be printed.
[Bug c/103835] New: Bogus sprintf warnings
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103835 Bug ID: 103835 Summary: Bogus sprintf warnings Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- Please address these warnings because they create more noise than they help! $ cat test.c #include #include #include const char* fun(char* buf, const char* pfx, int a, int b) { sprintf(buf, "%sa = %d\n" "%sb = %d\n", pfx, a, pfx, b); return buf; } int main(int argc, char* argv[]) { char buf[500]; const char* str; strcpy(buf, "\t"); str = fun(buf + strlen(buf) + 1, buf, atoi(argv[1]), atoi(argv[2])); printf("%s\n", str); return 0; } $ gcc --version gcc (GCC) 11.2.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ gcc -Wall -O6 test.c test.c: In function ‘main’: test.c:8:21: warning: ‘a = ’ directive writing 4 bytes into a region of size between 0 and 499 [-Wformat-overflow=] 8 | sprintf(buf, "%sa = %d\n" | ^~~~ test.c:8:5: note: ‘sprintf’ output between 13 and 1031 bytes into a destination of size 499 8 | sprintf(buf, "%sa = %d\n" | ^ 9 | "%sb = %d\n", | ~ 10 | pfx, a, pfx, b); | ~~~ test.c:8:5: warning: ‘sprintf’ arguments 3, 5 may overlap destination object ‘buf’ [-Wrestrict] test.c:17:10: note: destination object referenced by ‘restrict’-qualified argument 1 was declared here 17 | char buf[500]; | ^~~ It's clear that the destination buffer will NOT overlap with anything related to "pfx" in the fun() function. Is also clear that output will NOT contain that many characters that the warning claims (up to 1031). If GCC can't estimate the length for sure, it's better NOT to emit any warnings, rather than printing this annoying noise. Please be mindful of your users -- and their time to re-analyze the code that suddenly is now flagged with these senseless warnings, only to realize that it's all red herring. Thank you
[Bug c/100403] Bogus "function may return address of local variable" warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100403 --- Comment #2 from lavr at ncbi dot nlm.nih.gov --- > undefined if msg is not in the range of x.rec[0]...x.rec[RECLEN] Indeed for the segmented data address space. But in most systems it's linear, and the warning is then architecture dependent, and is only expected on those, where the comparison cannot be safely made. Besides, the warning then should be about that fact, not the return address being of a local variable -- that's misleading, at best.
[Bug middle-end/100401] Bogus -Wformat-overflow for a trailing zero-length array of a union
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100401 --- Comment #2 from lavr at ncbi dot nlm.nih.gov --- > GCC warnings are designed to "report constructions that are not inherently > erroneous but that are risky or suggest there may have been an error." Certainly, but the [0] size trailing member arrays were specifically devised to be such constructions, TBH. So the warning in this case is like shooting yourself in the foot... Especially when the boundaries are well observed.
[Bug c/100403] New: Bogus "function may return address of local variable" warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100403 Bug ID: 100403 Summary: Bogus "function may return address of local variable" warning Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- $ gcc --version gcc (GCC) 10.2.0 $ cat test.c #include #include #define RECLEN 128 struct R { int head; int code; char text[1]; }; const char* fun(int n, const struct R* p) { union { struct R r; char rec[RECLEN]; } x; const char* err = 0; memset(, 0, sizeof(x)); if (p) memcpy(, p, sizeof(*p)); else err = "Invalid argument"; if (!err) { static const char magic[] = "MAGIC"; const char* msg; if (memcmp(x.rec, magic, sizeof(magic)-1) == 0) msg = x.rec; else if (x.r.text[0]) msg = x.r.text; else msg = "Error w/code"; if (msg) printf("%s\n", msg); if (x.rec <= msg && msg < x.rec + sizeof(x)) err = "Error detected"; else err = msg; } else printf("%s\n", err); return err; } $ gcc -Wall -O2 -c test.c test.c: In function ‘fun’: test.c:45:12: warning: function may return address of local variable [-Wreturn-local-addr] 45 | return err; |^~~ test.c:19:7: note: declared here 19 | } x; | ^ test.c:19:7: note: declared here Noted that does not matter whether "sizeof(x)" or "sizeof(x.rec)" is used at the end of the "if()" statement on line 39.
[Bug c/100401] New: Bogus -Wformat-overflow warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100401 Bug ID: 100401 Summary: Bogus -Wformat-overflow warning Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- $ gcc --version gcc (GCC) 10.2.0 $ cat bogus.c #include #define RECLEN 128 struct S { int code; char text[0]; }; const void fun(int n) { union { struct S s; char rec[RECLEN]; } x; const char* err; if (!n) { err = "No error"; } else { sprintf(x.s.text, "Error %d", n); err = x.s.text; } printf("%s\n", err); } int main(int argc, const char* argv[]) { fun(argc); return 0; } $ gcc -Wall -O2 bogus.c bogus.c: In function ‘fun’: bogus.c:22:28: warning: ‘Error ’ directive writing 6 bytes into a region of size 0 [-Wformat-overflow=] 22 | sprintf(x.s.text, "Error %d", n); |^~ bogus.c:22:9: note: ‘sprintf’ output between 8 and 18 bytes into a destination of size 0 22 | sprintf(x.s.text, "Error %d", n); | ^~~~
[Bug c/100395] New: Bogus -Wstringop-overflow warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100395 Bug ID: 100395 Summary: Bogus -Wstringop-overflow warning Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- $ gcc --version gcc (GCC) 10.2.0 $ cat test.c #include #include int main(int argc, const char* argv[]) { size_t len0 = strlen(argv[0]), len1 = strlen(argv[1]); char buf[444]; char* s; s = buf + sizeof(buf) - len0; memcpy(s, argv[0], len0); s -= len1; memcpy(--s, argv[1], len1); s[len1++] = ' '; printf("%.*s\n", (int)(len0 + len1), s); return 0; } $ gcc -O2 -Wall test.c test.c: In function ‘main’: test.c:14:15: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 14 | s[len1++] = ' '; | ~~^ test.c:7:10: note: at offset -1 to object ‘buf’ with size 444 declared here 7 | char buf[444]; | ^~~ The offset shown in the message is wrong, which most likely was the reason to emit the warning altogether. The test code above mocks up a situation where the lengths of both strings, which are being copied in the reverse order into "buf", are known and small, i.e. both fit (a few times, actually) together into the buffer, including the separator and terminator.
[Bug c/96293] Extraneously noisy "taking address of packed member may result in an unaligned pointer value"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96293 --- Comment #5 from lavr at ncbi dot nlm.nih.gov --- My test case is not invalid. You're talking about base address of a structure, which would make offsets within it all unaligned, which is why I said "the same rule should apply for aggregates". So should "struct S" appear anywhere in an outer structure at an offset, which would not be its "native offset otherwise assigned by GCC, as if it wasn't packed", then there's a potential problem. Otherwise, the member addresses will still remain well-aligned, and no warnings would be ever necessary. As for your example, any structure's address can be type-cast to any value (it's C, for the sake of it), yet GCC doesn't assume that happens for non-packed structures, right? Extra warnings in large projects are disruptive, and if GCC warns about something, it should be well-warranted and verified. Applying a bit of an extra-logic (which does not take a lot of CPU cycles, or additional compilation time) for those new warnings, and not issuing them just mechanically, would help a lot.
[Bug c/96293] Extraneously noisy "taking address of packed member may result in an unaligned pointer value"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96293 lavr at ncbi dot nlm.nih.gov changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #3 from lavr at ncbi dot nlm.nih.gov --- I don't want my structure to be aligned at the int boundary. I want my structure to reflect the actual data layout "byte","byte","short","int" as they are laid out without any gaps, and "packed" guarantees such a disposition. I also don't want GCC issue warnings "just in case" where there's nothing happening: like I said the "short int" field is located at the native "short int" offset (multiple of 20, so there's no need for the warning; and so on with the int field. GCC should worry only if, for example, an int is placed at an odd offset, or, for 4 byte ints, at an offset not multiple of 4.
[Bug c/96293] Extraneously noisy "taking address of packed member may result in an unaligned pointer value"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96293 --- Comment #2 from lavr at ncbi dot nlm.nih.gov --- I don't want my structure to be aligned at the int boundary. I want my structure to reflect the actual data layout "byte","byte","short","int" as they are laid out without any gaps, and "packed" guarantees such a disposition. I also don't want GCC issue warnings "just in case" where there's nothing happening: like I said the "short int" field is located at the native "short int" offset (multiple of 20, so there's no need for the warning; and so on with the int field. GCC should worry only if, for example, an int is placed at an odd offset, or, for 4 byte ints, at an offset not multiple of 4.
[Bug c/96293] New: Extraneously noisy "taking address of packed member may result in an unaligned pointer value"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96293 Bug ID: 96293 Summary: Extraneously noisy "taking address of packed member may result in an unaligned pointer value" Product: gcc Version: 9.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- Hi, Beginning version 9 GCC started to generate tons of warnings of "unaligned pointer value". While this may be useful in some cases, many of these warnings should not be emitted (because the packed attribute is generally used by those, who follow the layout and usually know, what they are doing), IMO. Consider the following: ``` #include struct S { char a; unsigned char b; short c; unsigned int d; } __attribute__((packed)); void f1(char* p) { *p = '0'; } void f2(unsigned char* p) { *p = '1'; } void f3(short* p) { *p = 2; } void f4(unsigned int* p) { *p = 3; } int main() { struct S s; f1(); f2(); f3(); f4(); printf("%c %c %hd %u\n", s.a, s.b, s.c, s.d); return 0; } ``` On most platforms all members of the packed 'struct S' above are well-aligned to their respective type boundary, and the warnings like: ``` test.c: In function ‘main’: test.c:36:8: warning: taking address of packed member of ‘struct S’ may result in an unaligned pointer value [-Waddress-of-packed-member] 36 | f3(); |^~~~ test.c:37:8: warning: taking address of packed member of ‘struct S’ may result in an unaligned pointer value [-Waddress-of-packed-member] 37 | f4(); |^~~~ ``` are distracting and unhelpful! I'd say that GCC should only issue a warning about the alignment if the packed member does not indeed align with its natural boundary (what would have been assigned by GCC if the structure wasn't packed). That is, if the "b" member above would have been missing, then the warnings are indeed legitimate. Otherwise, "c", being a two-byte short integer, is perfectly fine to be located at offset 2, and "d" (a 4 byte integer) is perfectly fine to be located at offset 4, there's no need for any warnings. The same rule should apply for aggregates, too. Thanks for considering this suggestion.
[Bug c/89694] New: Redundant code with optimization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89694 Bug ID: 89694 Summary: Redundant code with optimization Product: gcc Version: 7.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- When I use the -O6 optimization, I noticed that GCC 7.4.0 interjects some redundant code, like marked below: mulP: .seh_endprologue movq%rcx, %r10 movq%rdx, %r11 movl%ecx, %eax shrq$32, %r10 shrq$32, %r11 movl%edx, %edx // REDUNDANT movq%r10, %r8 xorl%ecx, %ecx imulq %r11, %r8 imulq %rdx, %r10 imulq %rax, %r11 addq%r11, %r10 setc%cl leaq59(%r10), %r11 jc .L6 testq %rcx, %rcx jne .L6 cmpq$-60, %r10 cmovbe %r10, %r11 .L6: movq%r8, %r10 salq$32, %r8 xorl%ecx, %ecx shrq$32, %r10 imulq $59, %r10, %r9 addq%r8, %r9 setc%cl leaq59(%r9), %r8 jc .L11 testq %rcx, %rcx jne .L11 cmpq$-60, %r9 cmovbe %r9, %r8 .L11: xorl%r9d, %r9d addq%r11, %r8 setc%r9b movq%r8, %rcx imulq %rax, %rdx testq %r9, %r9 jne .L29 jne .L29 // REDUNDANT cmpq$-60, %r8 ja .L33 .L16: movq%rcx, %r9 salq$32, %rcx shrq$32, %r9 imulq $59, %r9, %r8 addq%rcx, %r8 setc%cl movq%r8, %rax movzbl %cl, %ecx testq %rcx, %rcx jne .L30 jne .L30 // REDUNDANT cmpq$-60, %r8 jbe .L17 $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/7.4.0/lto-wrapper.exe Target: x86_64-pc-cygwin Configured with: /cygdrive/i/szsz/tmpp/gcc/gcc-7.4.0-1.x86_64/src/gcc-7.4.0/configure --srcdir=/cygdrive/i/szsz/tmpp/gcc/gcc-7.4.0-1.x86_64/src/gcc-7.4.0 --prefix=/usr --exec-prefix=/usr --localstatedir=/var --sysconfdir=/etc --docdir=/usr/share/doc/gcc --htmldir=/usr/share/doc/gcc/html -C --build=x86_64-pc-cygwin --host=x86_64-pc-cygwin --target=x86_64-pc-cygwin --without-libiconv-prefix --without-libintl-prefix --libexecdir=/usr/lib --enable-shared --enable-shared-libgcc --enable-static --enable-version-specific-runtime-libs --enable-bootstrap --enable-__cxa_atexit --with-dwarf2 --with-tune=generic --enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-graphite --enable-threads=posix --enable-libatomic --enable-libcilkrts --enable-libgomp --enable-libitm --enable-libquadmath --enable-libquadmath-support --disable-libssp --enable-libada --disable-symvers --with-gnu-ld --with-gnu-as --with-cloog-include=/usr/include/cloog-isl --without-libiconv-prefix --without-libintl-prefix --with-system-zlib --enable-linker-build-id --with-default-libstdcxx-abi=gcc4-compatible --enable-libstdcxx-filesystem-ts Thread model: posix gcc version 7.4.0 (GCC)
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 --- Comment #6 from lavr at ncbi dot nlm.nih.gov --- That said, any function call within the outer "if()" but before the inner "if()" would cause the warning, even if that call does not accept any pointers (and thus cannot alias with local "s"). Modifying the code above to include "fun()" in stead of "printf()", same issue results: ... void fun(int i) { srand(i); } int main(void) { char blk[512], tmp[512]; struct S *s = (struct S*) blk; struct H *h; getblk(blk); if (s->a || !(h = gethdr(tmp)) || s->a != h->d) { #ifdef BUG fun(s->b); #endif ... $ gcc -DBUG -O6 -Wall -c bogus2.c bogus2.c: In function ‘main’: bogus2.c:47:17: warning: ‘h’ may be used uninitialized in this function [-Wmaybe-uninitialized] else if (!h) ^
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 --- Comment #5 from lavr at ncbi dot nlm.nih.gov --- Thank you Martin, for giving me the idea of where the problem might be stemming from! It does look like *printf() is not recognized by GCC as not modifying the local memory. But in your example GCC _might_ think that "p" and "q" can be aliased (being the result of the same function). Below is a mockup of the code that I was dealing with, clearly showing that "s" and "h" cannot be aliased! "s" is being on the local frame all alone. I get the same "uninitialized" warning if BUG is defined: $ cat bogus2.c #include #include #include struct S { int a; int b; }; struct H { int c; int d; }; void getblk(void* blk) { struct S* s = (struct S*) blk; memset(blk, 0, 512); s->a = rand() & 1; } struct H* gethdr(void* blk) { memset(blk, 0, 512); return rand() & 1 ? (struct H*) blk : 0; } int main(void) { char blk[512], tmp[512]; struct S *s = (struct S*) blk; struct H *h; getblk(blk); if (s->a || !(h = gethdr(tmp)) || s->a != h->d) { #ifdef BUG printf("%d\n", s->b); #endif if (s->a) printf("s->a = %d\n", s->a); else if (!h) printf("!h\n"); else printf("h->d = %d\n", h->d); } } $ gcc -O6 -Wall -c bogus2.c $ gcc -DBUG -O6 -Wall -c bogus2.c bogus2.c: In function ‘main’: bogus2.c:42:17: warning: ‘h’ may be used uninitialized in this function [-Wmaybe-uninitialized] else if (!h) ^
[Bug middle-end/89230] Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 --- Comment #2 from lavr at ncbi dot nlm.nih.gov --- Okay, but "d" points to a clearly separate storage on stack within a local frame. None of the pointers passed to (s)printf() relate to that area (either they are also clearly separate within the current stack frame, automatic ("name", "type", "temp"); or the argument values, that function was called with ("pfx")), so how "d->D_fid[2]" can be changed, in GCC's point of view? I mean, within the semantics of the language, that's impossible; and the warning should only be issued for that kind of a (mis)use.
[Bug c/89230] New: Bogus uninited usage warning
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89230 Bug ID: 89230 Summary: Bogus uninited usage warning Product: gcc Version: 7.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- I have a piece of code that reads like this (line numbers added): 2401 if (d->D_fid[2] || !(hdr = getfh(vol, d->D_fid[0], tmp)) || d->D_fid[1] != hdr->H_fseq) { 2402 char temp[80]; 2403 sprintf(temp, "%s.%s;%hu", name, type, d->D_fver); 2404 printf("%s%-20s ", pfx, temp); 2405 sprintf(temp, "(%ho,%ho,%ho)", d->D_fid[0], d->D_fid[1], d->D_fid[2]); 2406 printf("%-22s ", temp); 2407 if (d->D_fid[2]) 2408 printf("file header is on volume %hu.\n", d->D_fid[2]); 2409 else if (!hdr) 2410 printf("unable to get file header\n"); 2411 else 2412 printf("stale sequence no. (%ho)\n", hdr->H_fseq); 2413 } In the above "d" is a local variable (a pointer to a structure), unrelated to any of the other variables shown in the fragment above (that is, not pointing into any areas occupied by "vol" and "tmp" that are passed to "getfh()", hence, cannot be indirectly modified by that call). When GCC compiles the code optimized (-O6), it gives out the following warning: rsx11io.c: In function ‘list_dir.constprop’: rsx11io.c:2409:29: warning: ‘hdr’ may be used uninitialized in this function [-Wmaybe-uninitialized] else if (!hdr) ^ Note that the warning is completely uncalled for, because of the "if" on line 2401, checking first whether "d->D_fid[2]" is non-zero, and if not, then proceeding with the assignment of "hdr". Now, line 2409 could only be reached if "d->D_fid[2]" was zero, meaning "hdr" was in fact initialized. Unfortunately, I failed to reduce the above to a test case, as simplifying the code makes the warning disappear somehow. Moreover, the warning also disappears if I remove just the lines 2402-2407 from the original source code, so that the outer "if" is followed by the inner "if" immediately. $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/7.4.0/lto-wrapper.exe Target: x86_64-pc-cygwin Configured with: /cygdrive/i/szsz/tmpp/gcc/gcc-7.4.0-1.x86_64/src/gcc-7.4.0/configure --srcdir=/cygdrive/i/szsz/tmpp/gcc/gcc-7.4.0-1.x86_64/src/gcc-7.4.0 --prefix=/usr --exec-prefix=/usr --localstatedir=/var --sysconfdir=/etc --docdir=/usr/share/doc/gcc --htmldir=/usr/share/doc/gcc/html -C --build=x86_64-pc-cygwin --host=x86_64-pc-cygwin --target=x86_64-pc-cygwin --without-libiconv-prefix --without-libintl-prefix --libexecdir=/usr/lib --enable-shared --enable-shared-libgcc --enable-static --enable-version-specific-runtime-libs --enable-bootstrap --enable-__cxa_atexit --with-dwarf2 --with-tune=generic --enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-graphite --enable-threads=posix --enable-libatomic --enable-libcilkrts --enable-libgomp --enable-libitm --enable-libquadmath --enable-libquadmath-support --disable-libssp --enable-libada --disable-symvers --with-gnu-ld --with-gnu-as --with-cloog-include=/usr/include/cloog-isl --without-libiconv-prefix --without-libintl-prefix --with-system-zlib --enable-linker-build-id --with-default-libstdcxx-abi=gcc4-compatible --enable-libstdcxx-filesystem-ts Thread model: posix gcc version 7.4.0 (GCC)
[Bug c/89161] New: Bogus -Wformat-overflow warning with value range known
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89161 Bug ID: 89161 Summary: Bogus -Wformat-overflow warning with value range known Product: gcc Version: 7.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Target Milestone: --- The following code $ cat bogus1.c #include static char* print(const unsigned short a[2]) { static char buf[3]; if (a[0] && a[0] < a[1]) sprintf(buf, ".%1u", (10 * a[0]) / a[1]); else *buf = '\0'; return buf; } unsigned short array[2]; int main() { printf("%s\n", print(array)); return 0; } produces a lot of noise when compiled optimized (no warning without): $ gcc -Wall -O6 -c bogus1.c bogus1.c: In function ‘main’: bogus1.c:7:24: warning: ‘%1u’ directive writing between 1 and 10 bytes into a region of size 2 [-Wformat-overflow=] sprintf(buf, ".%1u", (10 * a[0]) / a[1]); ^~~ bogus1.c:7:22: note: directive argument in the range [0, 2147483647] sprintf(buf, ".%1u", (10 * a[0]) / a[1]); ^~ bogus1.c:7:9: note: ‘sprintf’ output between 3 and 12 bytes into a destination of size 3 sprintf(buf, ".%1u", (10 * a[0]) / a[1]); ^~~~ even though the compiler could have figured out that because of the "if", the value range of the integer division expression is actually [0..9], which perfectly fits into the buffer provided for the sprintf() statement. $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/7.4.0/lto-wrapper.exe Target: x86_64-pc-cygwin Configured with: /cygdrive/i/szsz/tmpp/gcc/gcc-7.4.0-1.x86_64/src/gcc-7.4.0/configure --srcdir=/cygdrive/i/szsz/tmpp/gcc/gcc-7.4.0-1.x86_64/src/gcc-7.4.0 --prefix=/usr --exec-prefix=/usr --localstatedir=/var --sysconfdir=/etc --docdir=/usr/share/doc/gcc --htmldir=/usr/share/doc/gcc/html -C --build=x86_64-pc-cygwin --host=x86_64-pc-cygwin --target=x86_64-pc-cygwin --without-libiconv-prefix --without-libintl-prefix --libexecdir=/usr/lib --enable-shared --enable-shared-libgcc --enable-static --enable-version-specific-runtime-libs --enable-bootstrap --enable-__cxa_atexit --with-dwarf2 --with-tune=generic --enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-graphite --enable-threads=posix --enable-libatomic --enable-libcilkrts --enable-libgomp --enable-libitm --enable-libquadmath --enable-libquadmath-support --disable-libssp --enable-libada --disable-symvers --with-gnu-ld --with-gnu-as --with-cloog-include=/usr/include/cloog-isl --without-libiconv-prefix --without-libintl-prefix --with-system-zlib --enable-linker-build-id --with-default-libstdcxx-abi=gcc4-compatible --enable-libstdcxx-filesystem-ts Thread model: posix gcc version 7.4.0 (GCC)
[Bug c/60100] warning disappears when preprocessed source is compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60100 --- Comment #10 from lavr at ncbi dot nlm.nih.gov --- I guess also a dup of PR57201. While I can agree these cases (and the one mentioned within PR57201) look similar, the gravity of the disappearing warning in case of a mismatched type is more severe than an unused variable or no-effect code...
[Bug c/60100] warning disappears when preprocessed source is compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60100 --- Comment #6 from lavr at ncbi dot nlm.nih.gov --- The .c file has a lot of headers included. Do you want all of them, as well? OTOH, the code in the preprocessed file clearly shows the use of a function pointer of mismatched type gone un-warned. I can't exactly understand how the .c file can help in better understanding why there is no warning where it had to be. The warning itself (from the .c compilation) is shown in one of my previous comments, so you can easily locate the relevant place in the .i file, I guess.
[Bug c/60100] warning disappears when preprocessed source is compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60100 --- Comment #8 from lavr at ncbi dot nlm.nih.gov --- This is the code from the original .c file that fails to post a warning. sock-w_len -= BUF_PeekAtCB(sock-w_buf, BUF_Size(sock-w_buf) - sock-w_len, x_WriteBuf, ctx, sock-w_len); It is not changed in any way during pre-processing. An assert() comes right after it. x_WriteBuf is a function (defined just prior to the function where it is used) that had a wrong prototype versus what a header defining BUF_PeekAtCB() declared. What constitutes a system header? Because a file that defines BUF_PeekAtCB() is referenced via angle brackets (versus quotes) in the #include directive. A path for gcc is provided with the -I option. Finally, if gcc compiling the original code .c manages to post a warning, it certainly somehow knows that no system headers are involved in this particular case.
[Bug c/60100] New: warning disappears when preprocessed source is compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60100 Bug ID: 60100 Summary: warning disappears when preprocessed source is compiled Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: lavr at ncbi dot nlm.nih.gov Created attachment 32070 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=32070action=edit GCC specs are attached Hello, When compiling the attached C code with GCC 4.8.1, I see a warning (which is correct) that the callback signature mismatches what's expected in the argument of BUF_PeekAtCB() call. If however, the source is first preprocessed then compiled, there is no warning! Since distcc uses precompiled source, the disappearing warning is a bad thing because it hides potential (and real, such as this case) bugs. $ cat qq.h #include stddef.h typedef struct SBUF* BUF; extern size_t BUF_PeekAtCB (BUF buf, size_t pos, size_t(*callback)(void* cbdata, const void* buf, size_t size), void* cbdata, size_t size ); $ cat qq.c #include stdio.h #include qq.h size_t cb(void* a, void* b, size_t c, int d) { return c; } int main() { BUF b = 0; size_t n = BUF_PeekAtCB(b, 0, cb, 0, 512); printf(%u\n, (unsigned int) n); return 0; } $ gcc -Wall -c qq.c -o qq.o qq.c: In function 'main': qq.c:14:5: warning: passing argument 3 of 'BUF_PeekAtCB' from incompatible pointer type [enabled by default] size_t n = BUF_PeekAtCB(b, 0, cb, 0, 512); ^ In file included from qq.c:2:0: qq.h:7:15: note: expected 'size_t (*)(void *, const void *, size_t)' but argument is of type 'size_t (*)(void *, void *, size_t, int)' extern size_t BUF_PeekAtCB ^ $ gcc -Wall -E qq.c -o qq.e $ gcc -Wall -c qq.e -o qq.o gcc: warning: qq.e: linker input file unused because linking not done Also, I'm not sure why there is a bogus warning about linking here (and not when compiling right from the source file, above). Any insight that you may have provide will be highly appreciated. Thanks, Anton Lavrentiev
[Bug c/60100] warning disappears when preprocessed source is compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60100 --- Comment #2 from lavr at ncbi dot nlm.nih.gov --- Because your command line did not actual compile anything. Indeed. with .i I see the warning again. But I can't see any warning if the precompiled file is processed through distcc...
[Bug c/60100] warning disappears when preprocessed source is compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60100 --- Comment #3 from lavr at ncbi dot nlm.nih.gov --- Ok, sorry and let me start again. My original mockup case wasn't good enough. So attached is the real (preprocessed) code that fails to produce a warning (yet when compiled from the .c form, the warning is there). This completes w/o warnings: gcc -E -std=gnu11 -fgnu89-inline -c -Wall -Wno-format-y2k -fPIC -gdwarf-3 -D_DEBUG -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -DNCBI_WITHOUT_MT -I/home/lavr/cxx/GCC-Debug64/inc -I/home/lavr/cxx/include /home/lavr/cxx/src/connect/ncbi_socket.c -o ncbi_socket.i gcc -std=gnu11 -fgnu89-inline -c -Wall -Wno-format-y2k -fPIC -gdwarf-3 -D_DEBUG -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 ncbi_socket.i -o ncbi_socket.o This produces a warning (as it should): gcc -c -std=gnu11 -fgnu89-inline -c -Wall -Wno-format-y2k -fPIC -gdwarf-3 -D_DEBUG -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -DNCBI_WITHOUT_MT -I/home/lavr/cxx/GCC-Debug64/inc -I/home/lavr/cxx/include /home/lavr/cxx/src/connect/ncbi_socket.c -o ncbi_socket.o /home/lavr/cxx/src/connect/ncbi_socket.c: In function 's_WritePending': /home/lavr/cxx/src/connect/ncbi_socket.c:3447:33: warning: passing argument 3 of 'BUF_PeekAtCB' from incompatible pointer type [enabled by default] x_WriteBuf, ctx, sock-w_len); ^ In file included from /home/lavr/cxx/src/connect/ncbi_socketp.h:44:0, from /home/lavr/cxx/src/connect/ncbi_connssl.h:37, from /home/lavr/cxx/src/connect/ncbi_socket.c:76: /home/lavr/cxx/include/connect/ncbi_buffer.h:180:36: note: expected 'size_t (*)(void *, const void *, size_t)' but argument is of type 'size_t (*)(void *, const void *, size_t, int)' extern NCBI_XCONNECT_EXPORT size_t BUF_PeekAtCB
[Bug c/60100] warning disappears when preprocessed source is compiled
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60100 --- Comment #4 from lavr at ncbi dot nlm.nih.gov --- Created attachment 32072 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=32072action=edit Preprocessed C source that fails to produce a warning when compiled