[Bug target/71286] New: 6.1.0: compiling djgpp programs with LTO emits "visibility attribute not supported in this configuration" warnings
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71286 Bug ID: 71286 Summary: 6.1.0: compiling djgpp programs with LTO emits "visibility attribute not supported in this configuration" warnings Product: gcc Version: 6.1.0 Status: UNCONFIRMED Severity: minor Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Host: x86_64-pc-linux-gnu Target: i686-pc-msdosdjgpp Build: x86_64-pc-linux-gnu Compiling djgpp programs with LTO enabled makes gcc emit diagnostics like: error: visibility attribute not supported in this configuration; ignored [-Werror=attributes] The source code doesn't even contain __attribute__((visibility(...))) anywhere, however. I believe a similar problem is worked around in the MinGW target by defining a custom TARGET_ASM_ASSEMBLE_VISIBILITY. (Also, getting LTO to work in the first place required me to apply this:) --- configure +++ configure @@ -6177,7 +6177,7 @@ # Among non-ELF, only Windows platforms support the lto-plugin so far. # Build it unless LTO was explicitly disabled. case $target in -*-cygwin* | *-mingw*) build_lto_plugin=$enable_lto ;; +*-cygwin* | *-mingw* | *djgpp*) build_lto_plugin=$enable_lto ;; *) ;; esac (The comment needs updating too, by the way.)
[Bug target/71286] 6.1.0: compiling djgpp programs with LTO emits "visibility attribute not supported in this configuration" warnings
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71286 --- Comment #2 from felix --- mingw seems to do fine without it: on that target TARGET_ASM_ASSEMBLE_VISIBILITY (i.e. i386_pe_assemble_visibility) never emits any assembly code, and it only emits a warning if the visibility attribute was specified explicitly. The function was added in SVN revision 168763 (commit de0e5a52 in the git mirror). I believe support for LTO on mingw was first added in revision 158762 (4d992eb6 in git). LTO support was half-enabled for DJGPP in SVN revision 232290 (7aa50266 in git).
[Bug c/6906] warn about asserts with side effects
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=6906 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #7 from felix --- What's wrong with the __builtin_pure_p approach? Sure, the diagnostics generated by __attribute__((warning)) will be ugly, but it's still something. It's also very simple to implement: it's just !TREE_SIDE_EFFECTS(). In fact, I patched my copy of GCC to add __builtin_pure_p defined just like that and it seems to work fine. Might submit it soon (I didn't write any tests, though).
[Bug target/14557] va_list is automatically taken address-of when passed as argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14557 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #19 from felix --- The number of duplicates of this report isn't terribly high, but doesn't this at least deserve a mention in the 'Disappointments' section of the manual? In any case, the following macro could be used as a workaround, under some rather reasonable assumptions: #if __STDC_VERSION__ >= 201112L #define va_ptr(ap) _Generic(&(ap), va_list *: &(ap), default: (va_list *)(ap)) #elif __GNUC__ >= 4 #define va_ptr(ap) __builtin_choose_expr(__builtin_types_compatible_p(__typeof__(&(ap)), va_list *), &(ap), (va_list *)(ap)) #else #define va_ptr(ap) (sizeof(ap) == sizeof(va_list) ? (va_list *)&(ap) : (va_list *)(ap)) #endif The main assumption is that a pointer to an array is the same as a pointer to its zeroth element, i.e. when we have a variable T array[N]; then (&array == (T (*)[N])array); or at least that this holds for the array type that va_list is. I don't see anything in the C standard that would explicitly guarantee this, but this should be a safe assumption to make, because breaking it would presumably make the following memcpy calls non-equivalent: T array0[N], array1[N]; memcpy(array1, array0, sizeof(array0)); memcpy(&array1, array0, sizeof(array0)); memcpy(array1, &array0, sizeof(array0)); memcpy(&array1, &array0, sizeof(array0)); which would be strange. Furthermore, the last version will break in the presence of va_list defined like typedef void *va_list[1]; typedef char va_list[sizeof(char *)]; but I think it's reasonable to assume that no ABI standard is going to prescribe something like this. None of the targets currently supported by GCC do.
[Bug c/82167] New: Segmentation fault when dereferencing the address of an array argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82167 Bug ID: 82167 Summary: Segmentation fault when dereferencing the address of an array argument Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Host: i686-linux-gnu Target: i686-linux-gnu Created attachment 42145 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42145&action=edit Result of running gcc -v -S on the source code given Attempting to compile the code below triggers a segmentation fault in the front-end. int main(int argc, char *argv[]) { __builtin_printf("%zu\n", sizeof(*&argv)); return 0; } I discovered this when I was searching for a way to locally silence -Wsizeof-array-argument (without necessarily knowing if a variable was declared as an array in the first place), in relation to my comment under bug #14557. Is there any way to do that, by the way?
[Bug c/82167] Segmentation fault when dereferencing the address of an array argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82167 --- Comment #1 from felix --- Hmm, never mind my question, I found one way to do it... #define NO_SIZEOF_WARNING(expr) ({ \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wsizeof-array-argument\"") \ __typeof__((expr)) _value = (expr); \ _Pragma("GCC diagnostic pop") \ _value; \ }) Not the most concise code ever, but it works.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #7 from felix --- Created attachment 42188 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42188&action=edit Preliminary patch Based on the already-existing __has_attribute() support, I've developed a patch implementing this feature. Attached. After some superficial testing (./cc1 -E), it seems to be working correctly. I don't really have the resources to run regression tests, so I didn't (although I think regressions would be unlikely). I also didn't write any new tests or documentation. (I noticed __has_attribute also doesn't seem to have much of either.) I made the feature closely mimic The Other Compiler's behaviour: only function built-ins are recognised. This includes generic functions like __builtin_add_overflow and C library functions specially handled by the front-end like printf (unless -fno-builtin is used), but excludes types like __builtin_va_list and function-like constructs (implemented as keywords) like __builtin_offsetof and __builtin_types_compatible_p. This is not so much of a problem for them, since they also provide __has_feature(), __has_extension() and __is_identifier() macros. The former has been requested in PR 60512 and rejected; it may be reasonable to revisit the issue. However, if more such preprocessor, er, built-ins are desired, it may start becoming unwieldy to implement them the way I did in this patch; it involved some amount of copy-pasting.
[Bug c/79775] New: Confusing fix-it diagnostics with double pointers to structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79775 Bug ID: 79775 Summary: Confusing fix-it diagnostics with double pointers to structs Product: gcc Version: 6.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Created attachment 40859 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40859&action=edit test.c Attempting to compile the attached source file emits the following diagnostic: test.c: In function 'bar': test.c:10:14: error: '*foo' is a pointer; did you mean to use '->'? quux(*foo->a); ^~ -> The programmer's error is that they misremembered operator precedence rules: struct member access binds stronger than pointer dereference. This diagnostic above can only serve to confuse them further.
[Bug c/79816] New: -Wformat-security should warn about missing or excess precision/width in %s specifiers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79816 Bug ID: 79816 Summary: -Wformat-security should warn about missing or excess precision/width in %s specifiers Product: gcc Version: 6.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Created attachment 40869 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40869&action=edit Sample source code gcc with -Wformat-security should warn if a printf-/scanf-style function is passed a character array with a %s specifier that has missing or excess precision/field width. For scanf-style functions, gcc should also warn if a %s specifier is given without field width. If the character array happens not to be null-terminated, a missing precision specifier in printf() will trigger an out-of-bounds read, leading to an information leak or a crash. As for scanf(), I don't think I need to explain; it's another version of the gets() pitfall. This feature would be good at catching mistakes like the one corrected here: <https://github.com/dosfstools/dosfstools/commit/09769e678cb4c0235e3c395b6418ee329f41ec02>. The attached file provides a summary of proposed behaviour.
[Bug c/72783] Fortify scanf %s, %[ conversion specifiers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72783 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #4 from felix --- A few days ago I've filed PR 79816, which would cover this and also passing character arrays to printf-style functions. Good to know someone's working on this. By the way: in my report, I suggested making -Wformat-security enable this warning. Will -Wformat-length be implied by -Wformat-security?
[Bug c/79816] -Wformat-security should warn about missing or excess precision/width in %s specifiers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79816 felix changed: What|Removed |Added See Also|https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=79554 | --- Comment #2 from felix --- The documentation for -Wformat-security explicitly mentions that it may be extended in the future to cover cases other than non-literal format strings. I'm suggesting to take advantage of that provision and make that option also cover buffer overflows. It shouldn't be that hard to make -Wformat-security imply -Wformat-overflow and whatever you choose to name the warning about improper precision. Current problems with the non-literal format string case aren't terribly relevant here.
[Bug target/67770] New: i386: -fshrink-wrap can interact badly with trampolines
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67770 Bug ID: 67770 Summary: i386: -fshrink-wrap can interact badly with trampolines Product: gcc Version: 5.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Created attachment 36419 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36419&action=edit Miscompiled program Compiling the attached program with -m32 -DCRASH=1 produces a crash on run time. Without either switch, the program runs fine (the host is x86-64). The reason for crashing can be revealed by inspecting the generated assembly: the instruction which pushes the trampoline context on the stack is moved along with the frame setup code from the very start of the function where the trampoline expects it to be. The crucial optimisation seems to be -fshrink-wrap; however, for some reason I was unable to trigger the bug without enabling the full -O1 optimisation level, even by manually listing all the -f... options enabled by -O1.
[Bug target/59672] Add -m16 support for x86
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59672 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #10 from felix --- Out of curiosity: given that hjl's -m16 patch has been merged, is there a reason for keeping this open? Is anyone hoping to have a more complete support for x86-16 target, or at least to drop the .code16gcc kludge?
[Bug target/41557] gcc.exe: Internal error: (null) (program cc1plus)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41557 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #4 from felix --- Created attachment 36628 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36628&action=edit Fix djgpp-stdint.h (5.2.0) I had a similar issue when building a djgpp cross-compiler. Removing the "signed" qualifier, as proposed above, fixed it; I had no other problems building the cross-compiler. Attached is a patch against 5.2.0. Please note that I left "signed char" intact; this is because of -funsigned-char (and it still fixes the crash). I'd suggest to apply it and close this bug; there probably isn't anything else to do here.
[Bug driver/68181] New: djgpp: minor linker invocation issues
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68181 Bug ID: 68181 Summary: djgpp: minor linker invocation issues Product: gcc Version: 5.2.0 Status: UNCONFIRMED Severity: minor Priority: P3 Component: driver Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Created attachment 36635 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36635&action=edit gcc/config/i386/djgpp.h patch (5.2.0) 0. The gcc frontend unconditionally instructs the linker to use a script provided by the djgpp libraries package. It contains a few LONG(0) directives which seem to be needed by the CRT to have some variables/memory regions properly initialised. I'd like that it be possible to disable that linker script. (Why? To make GRUB modules buildable with the djgpp compiler the same way they're buildable on mingw: by building them as COFF files and then converting them to ELF.) 1. GNU ld has been able to directly output go32 .exe files for quite some time (before even the repository was converted to git, it seems). Therefore calling the stubify utility is unnecessary. (However, ld names the output file a.out by default, which confuses autoconf, so it should be passed -o a.exe unless -o was given to gcc). Removing this dependency will simplify things a bit. (On the other hand, the loader stub used by binutils is a bit outdated; it comes from the 2.02 release of djgpp.) Both issues can be resolved with the attached trivial patch. The -T option is not passed to the linker when -nostdlib is passed to gcc (maybe -nodefaultlibs should also do it; or maybe -dT should be passed to the linker instead). I think that ultimately it's the djgpp CRT that ought to be fixed, but I'm not sure how. In the meantime, this should do.
[Bug tree-optimization/96672] New: Missing -Wclobbered diagnostic, or: __attribute__((returns_twice)) does not inhibit constant folding across call site
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96672 Bug ID: 96672 Summary: Missing -Wclobbered diagnostic, or: __attribute__((returns_twice)) does not inhibit constant folding across call site Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Created attachment 49072 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49072&action=edit Sample program The attached sample, compiled with -O3 -DVOLATILE= outputs 5; without either flag it outputs 6. I expected at least one of the following: - that the compiler warn about the clobbered x variable at the return statement; - that the program output 6 whether or not x is declared volatile. Currently neither is the case; compiling with -Wall -Wextra -Wclobbered emits no warnings. While the standard mandates that the variable be declared volatile, GCC seems to make some effort to preserve the expected semantics even when this requirement is not met; this would seem like a missed case.
[Bug c/93031] Wish: When the underlying ISA does not force pointer alignment, option to make GCC not assume it
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93031 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #4 from felix --- Given the discussion above apparently ended with the conclusion that code which performs misaligned accesses is ill-formed even on architectures that are permissive of such accesses, would it not make sense to make -Wcast-align synonymous to -Wcast-align=strict?
[Bug tree-optimization/95799] New: Assumed conjunctions are not broken down into clauses if their pureness is checked first
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95799 Bug ID: 95799 Summary: Assumed conjunctions are not broken down into clauses if their pureness is checked first Product: gcc Version: 11.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- In the attached sample, foo is compiled into returning a constant 1, while bar will compare a to 0, even though bar’s assumption implies foo’s. If I replace __builtin_pure_p() testing with a constant 1, both functions compile to the same assembly code, returning a constant 1. If I change bar to return (a >= 0 && b >= 0), it also compiles to returning a constant 1. It seems as if the optimiser becomes unaware that conjunction elimination is a valid rule of inference if the conjunction’s pureness is checked first.
[Bug tree-optimization/95801] New: Optimiser does not exploit the fact that an integer divisor cannot be zero
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95801 Bug ID: 95801 Summary: Optimiser does not exploit the fact that an integer divisor cannot be zero Product: gcc Version: 11.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- int always1(int a, int b) { if (a / b) return b != 0; return 1; } The function above should be possible to optimise to a constant 1, as integer division by zero is undefined. I’m surprised this isn’t caught already; it seems like very low-hanging fruit. In case someone wants to claim there is no value to be gained from this, this is where it came up: #define SIGNUM(value) ({ \ __auto_type _value = (value); \ (__typeof__(_value)) ((_value > 0) - (_value < 0)); \ }) #define DIV_FLOOR(a, b) ({ \ __auto_type _a = (a); \ __auto_type _b = (b); \ (_a / _b) - ((SIGNUM(_a) != SIGNUM(_b) ? _a % _b : 0) != 0); \ }) For unsigned types, DIV_FLOOR(a, b) should compile to the same code as truncating division (a / b), but unless a statement to the effect of (b == 0 ? __builtin_unreachable() : (void) 0); is inserted before the division, DIV_FLOOR will generate considerably longer code, at least on x86.
[Bug tree-optimization/95810] New: Spurious UBSan warning when computing the opposite of the absolute value of INT_MIN
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95810 Bug ID: 95810 Summary: Spurious UBSan warning when computing the opposite of the absolute value of INT_MIN Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- When the expression (x <= 0 ? x : -x) with x having type int is compiled with -fsanitize=undefined -O3, setting (x = INT_MIN) triggers a spurious UBSan warning about INT_MIN being negated. Not sure if I should file this against tree-ssa or the frontend(s), because the expression apparently becomes (-ABS_EXPR ) very early, even at -O0. I checked this with C, C++ and D frontends.
[Bug tree-optimization/95799] Assumed conjunctions are not broken down into clauses if their pureness is checked first
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95799 --- Comment #1 from felix --- Created attachment 48767 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48767&action=edit Sample program I was pretty sure I attached this before. Never mind, here it is.
[Bug c/94081] New: -Waddress-of-packed-member doesn’t take variable attributes or __builtin_assume_aligned into account
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94081 Bug ID: 94081 Summary: -Waddress-of-packed-member doesn’t take variable attributes or __builtin_assume_aligned into account Product: gcc Version: 9.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- In this code: #include struct foo { uint16_t a, b; } __attribute__((packed)); extern struct foo *f(void); extern void g(uint16_t *p); void h(void) { struct foo *s0 = __builtin_assume_aligned(f(), 16); g(&s0->a); struct foo s1 __attribute__ ((aligned(16))); g(&s1.a); } GCC will warn about taking the address of s0->a and s1.a, even though it has enough information to recognise those as false positives. On many platforms, variables on the stack are naturally aligned at a 32-bit boundary, so I believe &s1.a is a false positive on those platforms as well, but I’m less sure if skipping the warning for this case is desirable.
[Bug other/79469] Feature request: provide `__builtin_assume` builtin function to allow more aggressive optimizations and to match clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79469 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #1 from felix --- > Unfortunately the macro trick is arcane and has one potential issue: the > compiler may actually generate code to check `cond` at run-time if it cannot > deduce that it's a pure function. Oh, don't worry; the Other Compiler’s solution isn’t perfect either :) __builtin_assume(({ for (;;) {}; 1; })); This emits code for the infinite loop. For a less silly example: __attribute__((__const__,__always_inline__)) inline static int is_pow2(unsigned j) { __auto_type i = j; for (int c = 0; c < CHAR_BIT * sizeof(i); ++c) { i = (i >> 1) | ((i & 1) << (CHAR_BIT * sizeof(i) - 1)); if (i == 1) break; } return i == 1; } int foo(void) { extern unsigned bar(void); __auto_type x = bar(); __builtin_assume(is_pow2(x)); return __builtin_popcount(x); } This will also emit code for the loop, even though the result is not used at runtime. The code is not very idiomatic, but I don’t believe it’s wrong either: the __attribute__((const)) on is_pow2 I consider correct, because the side effects do not escape the function. If anyone takes this up, it would be nice if GCC at least did not outright pessimise such code.
[Bug c/94081] -Waddress-of-packed-member doesn’t take variable attributes or __builtin_assume_aligned into account
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94081 My initial report text was apparently lost in the Bugzilla migration, so here I am submitting it again. In this code: #include struct foo { uint16_t a, b; } __attribute__((packed)); extern struct foo *f(void); extern void g(uint16_t *p); void h(void) { struct foo *s0 = __builtin_assume_aligned(f(), 16); g(&s0->a); struct foo s1 __attribute__ ((aligned(16))); g(&s1.a); } GCC will warn about taking the address of s0->a and s1.a, even though it has enough information to recognise those as false positives. On many platforms, variables on the stack are naturally aligned at a 32-bit (or coarser) boundary, so I believe &s1.a is a false positive on those platforms even without the attribute, but I’m less sure if skipping the warning for this case is desirable.
[Bug c/94389] New: __attribute__((warn_unused_result)) will warn if the result is discarded as an optimisation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94389 Bug ID: 94389 Summary: __attribute__((warn_unused_result)) will warn if the result is discarded as an optimisation Product: gcc Version: 9.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- With the code below, the compiler warns about an unused result, even though the result is used: #define O_TEXT 0 /* defined on Windows and DOS, but not needed on Unix */ __attribute__((warn_unused_result)) extern int text_mode(void); int get_flags(void) { return text_mode() ? O_TEXT : 0; } Similarly, there is a warning if the result of a function marked with __attribute__((warn_unused_result)) is multiplied by 0, and probably with other expressions that are easily constant-folded. If the function also has __attribute__((const)), there is no warning. I think this issue could be resolved as a by-product of fixing bug 66425.
[Bug c/94389] __attribute__((warn_unused_result)) will warn if the result is discarded as an optimisation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94389 --- Comment #6 from felix --- I don’t mind the transformation being applied. I think it is entirely sound and may be beneficial; I imagine it may be harder to allocate registers for the naïve translation of (foo() ? X : X) than it is for (foo(), X). It’s just the warning that is wrong. > So, use [[nodiscard]] instead This is filed against the C frontend, where [[nodiscard]] has not been implemented. Not even on trunk (as provided today by godbolt.org, at least). You are asking people to use a feature that does not exist. Even if [[nodiscard]] is going to be added eventually, most code in the wild uses __attribute__((warn_unused_result)) and will do so for a while. Which means it will still be subject to false positives like this one. Moreover, the attribute often appears in library headers, which the library user is not really at liberty to change. Are you suggesting that everyone compile their code with -Dwarn_unused_result=nodiscard -D__warn_unused_result__=nodiscard passed on the command line? Will that even work? Maybe you should reflect for a while on why the C++ and C committees considered it more useful to standardise [[nodiscard]] with the semantics they did, instead of the semantics of GCC’s __attribute__((warn_unused_result)) as of today. > O_TEXT != 0 ? text_mode () ? O_TEXT : 0 : 0 First of all, that is not equivalent: int text_mode(void) { if (mode == MODE_TEXT) { fprintf(log_file, "text mode selected\n"); return 1; } else { fprintf(log_file, "binary mode selected\n"); return 0; } } Maybe I care about that log message, even in the case where the return value itself happens to be ultimately irrelevant. Second of all, I should not be faulted for not adding redundant special cases to my already correct code. I am not going to add convoluted hacks just to avoid an asinine compiler warning. I do not want to hand-optimise platform-specific cases like this either; taking care of platform-specific serendipities that can be exploited for optimisation purposes is the compiler’s job. And finally, just because a faulty workaround exists doesn’t make the warning not wrong. If GCC cannot tell a legitimate use from ‘obfuscation’, it should err on the side of the former. (I believe a case could be made for multiplying by zero as well.) Though I think it would be simpler to just make the semantics of __attribute__((warn_unused_result)) be exactly like [[nodiscard]].
[Bug c/6906] warn about asserts with side effects
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=6906 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #9 from felix --- I have just realised that __builtin_pure_p is already expressible: #define __builtin_pure_p(expr) \ (__builtin_object_size(((void)(expr), ""), 2)) If (expr) is free of side effects, this is the same as __builtin_object_size("", 2), which is 1. Otherwise, the expression returns 0. This is documented behaviour, by the way. The documentation for __builtin_object_size at <https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html> states: > __builtin_object_size never evaluates its arguments for side effects. > If there are any side effects in them, it returns (size_t) -1 for > type 0 or 1 and (size_t) 0 for type 2 or 3. Experimentation reveals __attribute__((pure)) is enough for __builtin_object_size to consider a function free of side effects.
[Bug other/79469] Feature request: provide `__builtin_assume` builtin function to allow more aggressive optimizations and to match clang
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79469 --- Comment #2 from felix --- I realised recently that this is already expressible: #define __builtin_assume(expr) \ (__builtin_pure_p(expr) \ ? ((expr) \ ? (void) 0 \ : __builtin_unreachable()) \ : (void) 0 /* XXX: warn about side effects */) where __builtin_pure_p has the same definition that I gave under PR 6906: #define __builtin_pure_p(expr) \ (__builtin_object_size(((void) (expr), ""), 2)) As for the corner case I gave earlier, GCC manages to optimise the is_pow2 loop away at -O2 and -O3 (though not entirely at -O1), and it apparently considers statement-expressions that contain more than one statement, or any kind of loop, to have side effects. One can always check __OPTIMIZE__ to prevent spurious code from being generated at -O0. So this solution apparently performs no worse :)
[Bug tree-optimization/94757] New: GCC does not optimise unsigned multiplication known not to overflow
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94757 Bug ID: 94757 Summary: GCC does not optimise unsigned multiplication known not to overflow Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- This code: #include unsigned f(unsigned x) { if (x > UINT_MAX / 3) __builtin_unreachable(); return (x * 3) / 3; } should be possible to optimise into the identity function, but (on x86_64) gcc -O3 generates a multiplication (via LEA) then a division (via multiplication). GCC knows that the multiplication cannot overflow, because replacing the returned expression with __builtin_mul_overflow_p(x, 3, x) is makes it optimise to returning constant 0.
[Bug tree-optimization/94818] New: GCC emits dead bodies of functions whose all calls have been eliminated by optimisations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94818 Bug ID: 94818 Summary: GCC emits dead bodies of functions whose all calls have been eliminated by optimisations Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Target: x86_64-linux-gnu In this code: __attribute__((__warning__("argh"))) static void foo(void) { __asm__ ( "" "" ); } void bar0(int x) { if (__builtin_constant_p(x)) foo(); } void bar1(int x) { if (__builtin_constant_p(x)) foo(); } No calls to foo are emitted in the final output, and GCC knows this, since no warnings are emitted. However, GCC will still emit a function body for foo, unless either the __asm__ statement is removed or both conditions are changed to integer constant expressions, so that the function is eliminated by one of the inlining passes. (I decided to demonstrate it this way instead of using __attribute__((__noinline__)), just to make sure this is not related to __attribute__((__noinline__)) somehow implying __attribute__((__used__)).)
[Bug preprocessor/41492] Please ignore #! on the first line of a file
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=41492 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #2 from felix --- Please reconsider. For one thing, this extension does not in any way interfere with normal preprocessor syntax. For another, stripping the shebang line in an external preprocessor introduces overhead and complications: one has to create a temporary source file, probably insert a #line directive in the shebang line's place, and arrange for the temporary file to be deleted when compilation finishes. Being able to have the compiler read the file directly would make this so much simpler. Also, I sometimes develop small C programs by alternating between rapid write-compile-run cycle with Tiny C Compiler and running the program though a normal compiler to look for warnings and produce an optimised binary. Right now, if I do this, I have to comment out or remove the shebang line when compiling, and add it back when I want to invoke the source file directly from the command line through TCC. This hardly stops me dead in my tracks, but is sure irritating. Plus, the compiler can easily keep generating a warning for erroneous shebang lines (or for all shebang lines when -Wpedantic is in force), so the likelihood of this feature leading to accepting erroneous code is minimal.
[Bug c/79775] Confusing fix-it diagnostics with double pointers to structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79775 --- Comment #3 from felix --- A particularly amusing variant of this bug occurs with the following code: struct x { struct x **xx; }; int y = __builtin_offsetof(struct x, xx->xx); which gives the warning $ gcc xx.c xx.c:3:40: error: ‘*0->xx’ is a pointer; did you mean to use ‘->’? int y = __builtin_offsetof(struct x, xx->xx); ^~ -> mentioning `*0`, which doesn't appear in the source code at all. Similarly for C++: $ g++ xx.c xx.c:3:42: error: request for member ‘xx’ in ‘*((x*)0)->x::xx’, which is of pointer type ‘x*’ (maybe you meant to use ‘->’ ?) int y = __builtin_offsetof(struct x, xx->xx); ^~ Compare The Other Compiler, which refuses to parse `->` inside `__builtin_offsetof` altogether: $ clang xx.c xx.c:3:40: error: expected ')' int y = __builtin_offsetof(struct x, xx->xx); ^ xx.c:3:27: note: to match this '(' int y = __builtin_offsetof(struct x, xx->xx); ^ 1 error generated. I assume GCC parses it in order to have a more user-friendly ‘cannot apply ‘offsetof’ to a non constant address’ error, but I'm not sure if this is worth it.
[Bug c/66970] Add __has_builtin() macro
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66970 --- Comment #18 from felix --- Proper built-ins are ordinary identifiers subject to ordinary name resolution and shadowing, so the 'keyword built-in' case is impossible. If you don't know if (or don't want to depend on the fact that) a given built-in is a keyword or an intrinsic function, `__has_builtin(x) || !__is_identifier(x)` should suffice. In a way, that detail is already exposed to user code: `int __builtin_abort = 0;` compiles, but `int __builtin_choose_expr = 0;` doesn't. The documentation doesn't mention this, however; keyword built-ins are actually documented as being functions in the manual, either explicitly or implicitly (by being listed alongside true intrinsic functions with no discriminating features). So even if this feature is adopted as-is, it will necessitate some changes in the documentation. And while I can sympathise with claims that this behaviour is surprising, what are the alternatives? If keywords should count as built-ins, should __has_builtin(sizeof) expand to 1? Should __has_builtin(volatile)?
[Bug c/57612] add builtin to assert that expression does not have side effects
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57612 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #3 from felix --- Overlaps bug 6906. Under that ticket, I proposed adding a built-in that simply returns whether or not a given expression has side effects, simply by exposing TREE_SIDE_EFFECTS(). This more general built-in could also (partially) address bug 79469, by allowing to define __builtin_assume as #define __builtin_assume(cond) do { \ if (__builtin_pure_p(cond)) \ if (!(cond)) \ __builtin_unreachable(); \ } while (0) Partially, because e.g. if A has side effects, then with the definition above __builtin_assume(A && B) would consider the whole condition to have side effects as well, and therefore disregard it, even if B could potentially be mined for optimisation opportunities.
[Bug tree-optimization/93326] New: switch optimisation of multiple jumptables into a lookup
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93326 Bug ID: 93326 Summary: switch optimisation of multiple jumptables into a lookup Product: gcc Version: 9.2.1 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Target: i686-linux-gnu Attached two code samples are equivalent, yet they are optimised wildly differently (with -O3 -fno-pic). Apparently, GCC is capable of recognising that a switch/return realised by a single jumptable can be optimised into a lookup table, but is unable to do so when a switch is realised by multiple jumptables. When compiling in PIC mode, neither switch is optimised into a lookup table; I don't see a reason why it couldn't be.
[Bug tree-optimization/93326] switch optimisation of multiple jumptables into a lookup
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93326 --- Comment #1 from felix --- Created attachment 47680 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47680&action=edit Optimised into a lookup table of constants (-O3 -fno-pic)
[Bug tree-optimization/93326] switch optimisation of multiple jumptables into a lookup
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93326 --- Comment #2 from felix --- Created attachment 47681 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47681&action=edit Optimised into a jumptable, then load of an immediate (-O3 -fno-pic)
[Bug target/14557] va_list is automatically taken address-of when passed as argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14557 --- Comment #21 from felix --- > va_list ap2; > va_copy(ap2, ap); > and then use &ap2, this always works. > the proposed macros are both broken and unnecessary. That's not equivalent. Using va_arg(ap2, T) does not propagate state changes back to ap, which is the main motivation to form a pointer to ap in the first place. The macros do that just fine. You mean they are unportable? That part is true, I admitted as much. Pick your poison. As for being unnecessary, I vaguely remember gnulib trying to use internal helper functions with va_list * parameter in their vfprintf implementation. I cannot find the link now, unfortunately. But there are also duplicates to this very report, so clearly the need is there.
[Bug c++/88050] Add a warning for breaking the "Rule of Three"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88050 felix changed: What|Removed |Added CC||felix.von.s at posteo dot de --- Comment #4 from felix --- Created attachment 52401 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52401&action=edit Basic patch (no tests) Attached is a simple patch adding a warning checks for violations of the Rule of Three and the Rule of Five (Core Guideline C.21) and enabling it at the -Wextra level. Not included is a check for the rule-of-four-and-a-half variant: a swapping by-value assignment operator overload, paired with the appropriate constructor, is enough to implement copy- or move-assignment. Rule of Zero would be much harder to check for, but it may be possible to diagnose certain violations of it, by looking at the code inside the destructor: if the delete operator, or a single function is invoked more than once in the destructor, it probably means the class manages more than one resource.
[Bug c++/106940] New: Feature request: -Wsuggest-noexcept and -Wsuggest-explicit
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106940 Bug ID: 106940 Summary: Feature request: -Wsuggest-noexcept and -Wsuggest-explicit Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- When writing classes, I routinely tend to forget that constructors can be used for implicit conversions, unless marked explicit. I also tend to forget about noexcept specifiers, which can lead to performance pitfalls, especially with move constructors and move assignment operators. So I would like a compiler warning that could remind me to consider such concerns. In case of noexcept, I don’t particularly need full semantic analysis of the body; a pure syntax check whether the specifier is present should suffice. And in case of explicit, no other kind of check is possible, obviously. I imagine -Wsuggest-explicit could be suppressed for copy and move constructors from the same type. I am undecided whether it should apply to conversion operators, but leaning towards yes. The warnings would be silenced by adding explicit specifiers: explicit(false) and noexcept(false). Each warning should probably require the earliest language version where the respective silencing is possible (C++20 and C++11, respectively).
[Bug c++/100681] New: [[noreturn]] attribute can be applied to parameters of function type with strange results
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100681 Bug ID: 100681 Summary: [[noreturn]] attribute can be applied to parameters of function type with strange results Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Created attachment 50845 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50845&action=edit Sample program Attached is a code sample which G++ accepts and all other compilers I tested reject. When the `never::invoke` line is uncommented, compilation fails with a message naming the type of func as `R(Args ...) volatile`, which is an abominable function type. There doesn’t seem to be a real way to use the method. Expected behaviour: the code is rejected in both versions, just like in other compilers. Desired behaviour: the code is accepted in both versions, with the [[noreturn]] attribute applied to func as if it were a function invoked directly.
[Bug tree-optimization/101050] New: Range comparisons with more significant bits constant are not optimised into masked equality tests
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101050 Bug ID: 101050 Summary: Range comparisons with more significant bits constant are not optimised into masked equality tests Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: felix.von.s at posteo dot de Target Milestone: --- Target: x86_64-linux-gnu Created attachment 50995 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50995&action=edit Sample functions f and g Attached sample functions f and g have identical behaviour, but GCC optimises them differently at -O3. The former is optimised into an arithmetic offset and unsigned comparison, while the latter compiles into bit masking and an equality test, as written. I presume it would be advantageous to reduce the former to the latter whenever possible (that is, to simplify (C <= x && x < C + (1 << N)) where (C & ((1 << N) - 1)) == 0 into (x & ~(1 << N)) == C), since the operations involved are slightly weaker. The Other Compiler does this. And yes, the values in the example are not accidental. This comes up in Unicode processing, so I think it’s worth the trouble.