[Bug tree-optimization/94357] New: Inline assembly with memory operand is considered nothrow with `-fnon-call-exceptions`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94357 Bug ID: 94357 Summary: Inline assembly with memory operand is considered nothrow with `-fnon-call-exceptions` Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- Created attachment 48130 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48130&action=edit Issue demonstration The documentation of `-fnon-call-exceptions` (https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fnon-call-exceptions) states that any instruction with a "memory references" is allowed to throw a c++ exception (or in other words: do what essentially boils down to performing a CFI unwind, and calling `__gxx_personality_v0()` without that function calling `std::terminate()` because the faulting PC isn't allowed to trap) However, from what I can tell by looking at the GCC sources (gcc/tree-eh.c:tree_could_trap_p(); case ASM_EXPR), GCC only considers an `asm()` statement as being able to cause a non-call-exception (i.e. trap) when written as `asm volatile()`. Given the fact that "memory references" is listed as one of the possible reasons for an instruction to be trapable, it stands reason that any inline assembly statement that uses memory operands (i.e. `asm("..." : "=m" (...))` or `asm("..." : : "m" (...))`), as well as any assembly statement that specifies "memory" as part of its clobber list (i.e. `asm("..." : : : "memory")`) should also be considered as potentially containing instructions that may trap. Note also that during my investigation I've noticed that the catch(...) block is fully optimized away in the following case ... (`gcc -S` does contain `/* Hello */`, but doesn't contain `/* World! */`): ```c void foo() { try { __asm__ __volatile__("/* Hello */"); } catch (...) { __asm__("/* World! */"); } } ``` ... but isn't optimized away when the first `__asm__ __volatile__` is placed in an inline function (`gcc -S` does contains both `/* Hello */` and `/* World! */`): ```c inline void bar() { __asm__ __volatile__("/* Hello */"); } void foo() { try { bar(); } catch (...) { __asm__("/* World! */"); } } ``` The attached file shows the different cases where `__asm__` appears in `try ... catch`, and should be compiled as follows (note that -O* flags don't have any affect on which catch-statements get deleted; -O0 has the same output as -O3): $ g++ -S -x c++ -fnon-call-exceptions attaced-file.cc -o - | grep "reference" The current output is:``` callmust_reference_1 ``` A consistent output (with the current rules concerning __volatile__) would look like:``` callmust_reference_1 callmust_reference_2 callmust_reference_3 ``` And an output consistent with published documentation would look like:``` callmust_reference_1 callmust_reference_2 callmust_reference_3 callmust_reference_4 callmust_reference_5 callmust_reference_6 ```
[Bug debug/96417] New: c++ `using` causes massive debug-info bloat (debug-info is kept for types/symbols)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96417 Bug ID: 96417 Summary: c++ `using` causes massive debug-info bloat (debug-info is kept for types/symbols) Product: gcc Version: 9.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- Created attachment 48982 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48982&action=edit Compile me with and without -DNO_USING It appears as though the c++ `using` keyword prevents - `-feliminate-unused-debug-symbols` and - `-feliminate-unused-debug-types` from working for the associated symbol/type. As such, any use of c++'s `using` causes debug information to be generated, even if (in the case of symbols) the associated object doesn't appears as an addressible entity in generated object files, or are ever even used. As a demonstration, you may compile the attached file as: $ g++ -g -S -o - demo.cc | grep imported_ .string "_ZN1a17imported_functionEi" .string "imported_function" .string "imported_type" $ g++ -g -S -o - demo.cc -DNO_USING | grep imported_ Note that only `using ns::symbol;` is affected by this, but `using namespace ns;` works just fine. In addition to g++9.3.0, I was also able to reproduce the same problem on g++9.1.0 and g++5.4.0, meaning that this must have been going on for ages. - So long as a matter of fact that I'm wondering if there's some ABI mandate that requires this kind of behavior??? In case there is some kind of weird, non-sensical ABI requirement that requires debug information to always be generated for c++ using declarations, I'd like to request a commandline option to work around this, as I'm working on a program that's currently 4MiB actual text+data, and 6MiB debug info (and that is with already using -gz=zlib)
[Bug c++/96516] New: template + __attribute__((copy)) produce compiler errors
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96516 Bug ID: 96516 Summary: template + __attribute__((copy)) produce compiler errors Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- Created attachment 49016 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49016&action=edit Same code as already seen in the bug description Using `__attribute__((copy(...)))' to inherit an `returns_nonnull' attribute will cause a compiler error if the applied-to function's return type uses a decltype type-expression, or has it's is-pointer-y-ness depend on a template parameter. However, when `returns_nonnull' is not inherited via `copy()', but explicitly used, then everything still works fine, so there appears to be a discrepency between using `copy()' to inherit `returns_nonnull', and specifying `returns_nonnull' directly. ``` __attribute__((returns_nonnull)) void *base(void *); __attribute__((copy(base))) __typeof__((void *)0) wrap1(void *); __attribute__((copy(base))) decltype((void *)0) wrap2(void *); template __attribute__((copy(base))) T *wrap3(T *); template __attribute__((copy(base))) decltype(T()) *wrap4(T *); template __attribute__((returns_nonnull)) decltype((T *)0) wrap5(T *); template __attribute__((copy(base))) decltype((T *)0) wrap6(T *); template __attribute__((copy(base)))__typeof__((T *)0) wrap7(T *); template __attribute__((copy(base))) Twrap8(T); template __attribute__((returns_nonnull)) Twrap9(T); ``` All of these `wrapN()' functions should work the same, and none of them should produce an error, but `wrap6()', `wrap7()' and `wrap8()' produce errors: `returns_nonnull attribute on a function not returning a pointer' I know that `__attribute__((copy(...)))' is a gcc extension, and this bug only happens with g++, and I also know that it being an extension, it's correct behavior isn't written in stone. But in this example, it's behavior is plainly inconsistent (if `returns_nonnull' wasn't allowed with a template-dependent return expression, then `wrap5()' and `wrap9()' should also cause errors, even though they don't), and as already stated, _all_ of the above should work without issues in my opinion. I've placed this Report under c++ since this bug seems to be specific to the combination of `template' + `__attribute__((copy))', where the template-part is specific to c++. But if I had to guess, this is probably caused by a minor difference in how `copy()' sets the `returns_nonnull' attribute vs. how directly making use of `returns_nonnull' does the same. Note: The same thing also happens with `__attribute((malloc))' and `__attribute((nonnull(...)))' (in the case of `nonnull(...)', it even appears to produce errors for _all_ template-functions that use `copy()' (`wrap5' and `wrap9' continue to work correctly, so this is most definitely a problem with `copy()')) (s.a. the attached `bug.cc`, which is replicated in the following): ``` __attribute__((returns_nonnull, malloc, nonnull(1))) void *base(void *); __attribute__((copy(base))) __typeof__((void *)0) wrap1(decltype((void *)0)); __attribute__((copy(base))) decltype((void *)0) wrap2(decltype((void *)0)); template __attribute__((copy(base))) T *wrap3(decltype((T *)0)); template __attribute__((copy(base))) decltype(T()) *wrap4(decltype((T *)0)); template __attribute__((returns_nonnull, nonnull(1))) decltype((T *)0) wrap5(decltype((T *)0)); template __attribute__((copy(base))) decltype((T *)0) wrap6(decltype((T *)0)); template __attribute__((copy(base)))__typeof__((T *)0) wrap7(decltype((T *)0)); template __attribute__((copy(base))) T wrap8(T); template __attribute__((returns_nonnull, nonnull(1))) T wrap9(T); ``` The following are the errors produced by the above code. Note that inheriting `__attribute__((malloc))' causes the `returns_nonnull` error to become duplicated for `wrap6()', `wrap7()' and `wrap8()' for some reason (possibly an unrelated bug), and that `wrap5()' and `wrap9()' (i.e. the declarations that don't use `copy()') produces no errors or warnings: ``` [wrap3]: warning: 'nonnull' attribute argument value '1' refers to parameter type 'decltype ((T*)(0))' [-Wattributes] [wrap4]: warning: 'nonnull' attribute argum
[Bug c++/96516] template + __attribute__((copy)) produce compiler errors
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96516 --- Comment #3 from sagebar at web dot de --- No problem. Also: What you just said made me realize that once __attribute__((copy)) works correctly with templates, _any_ attribute that can be inherited via copy() can be made template-conditional in c++: ``` template struct conditional_returns_nonnull { static __attribute__((returns_nonnull)) void *func(void); }; template<> struct conditional_returns_nonnull { static void *func(void); }; template __attribute__((copy(conditional_returns_nonnull::func))) void *function_with_conditional_returns_nonnull_attribute(); #define SASS(x) static_assert(x, #x) SASS(!__builtin_has_attribute( conditional_returns_nonnull::func, returns_nonnull)); SASS(__builtin_has_attribute( conditional_returns_nonnull::func, returns_nonnull)); SASS(!__builtin_has_attribute( function_with_conditional_returns_nonnull_attribute, returns_nonnull)); SASS(__builtin_has_attribute( function_with_conditional_returns_nonnull_attribute, returns_nonnull)); ``` Currently, this doesn't compile due to the last `static_assert()' failing (Which I'm guessing is due to the same bug) -> So I guess: Here's another test
[Bug c++/96516] template + __attribute__((copy)) produce compiler errors
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96516 --- Comment #4 from sagebar at web dot de --- (In reply to sagebar from comment #3) > ..., _any_ attribute that > can be inherited via copy() can be made template-conditional in c++: Also note that I've tested if gcc (`-x c') allows multiple copy attributes on the same declaration, and it appears to do allow this, meaning that deferring attribute copy until template instantiation should be made functional for 0-N copy attributes, rather than 0-1: gcc currently allows multiple __attribute__((copy)) within the same declaration: ``` __attribute__((returns_nonnull)) void *func_with_returns_nonnull(); __attribute__((malloc)) void *func_with_malloc(); __attribute__(( copy(func_with_returns_nonnull), copy(func_with_malloc))) void *func_with_both(); #define SASS(x) static_assert(x, #x) SASS(__builtin_has_attribute(func_with_returns_nonnull, returns_nonnull)); SASS(!__builtin_has_attribute(func_with_returns_nonnull, malloc)); SASS(!__builtin_has_attribute(func_with_malloc, returns_nonnull)); SASS(__builtin_has_attribute(func_with_malloc, malloc)); SASS(__builtin_has_attribute(func_with_both, returns_nonnull)); SASS(__builtin_has_attribute(func_with_both, malloc)); ```
[Bug c++/96985] New: c++ `noexcept` is ignored for *known* functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96985 Bug ID: 96985 Summary: c++ `noexcept` is ignored for *known* functions Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- g++ has a list of *special* function names that it recognizes as builtins. This includes things like `memcpy` or `strlen`. The problem is that this list includes information about a function being nothrow/noexcept, too, and there doesn't seem to be any way of preventing g++ from compiling/generating code based on these assumptions, even if they violate a previous, explicit declaration, and even when "-ffreestanding -fno-builtin" is passed on the commandline. See the following (compile as `g++ -ffreestanding -fno-builtin`): ``` extern "C" { extern void *cpymem(void *, void const *, unsigned long) noexcept(false); extern void *memcpy(void *, void const *, unsigned long) noexcept(false); } /* extern "C" */ static_assert(!noexcept(cpymem(0, 0, 0))); static_assert(!noexcept(memcpy(0, 0, 0))); ``` The second static_assertion (the one for `memcpy`) fails because despite asking g++ to compile without any assumptions in regards to *known* functions (-ffreestanding), it still makes use of its builtin assumptions regarding a function named `memcpy()`. (Note: I know the `noexcept(false)` are redundant, but they're there to emphasize my point) Work-around: ``` #define STRINGIFY2(x) #x #define STRINGIFY(x) STRINGIFY2(x) extern "C++" { extern void *memcpy(void *, void const *, unsigned long) __asm__(STRINGIFY(__USER_LABEL_PREFIX__) "memcpy"); } /* extern "C++" */ static_assert(!noexcept(memcpy(0, 0, 0))); ``` I assume this works because only functions with extern-c linkage are considered candidates for builtin functions, so declaring as extern-c++ and assigning the proper asm-name for extern-c manually, bypasses the is-a-builtin detector entirely. Proposed solution / expected behavior: - gcc/g++ should disregard whatever it believes to be the case in regards to nothrow/noexcept for any *known* function when `-ffreestanding` or `-fno-builtin` are given. - Similarly, when `-fnon-call-exceptions` is given, gcc/g++ should assume that the library variant of any of its builtin functions may throw an exception (example: `memcpy()` can trigger SIGSEGV) - iow: Handle `-fnon-call-exceptions` the same as `-ffreestanding` / `-fno-builtin` in regards to nothrow/noexcept
[Bug c++/92438] New: Function declaration parsed incorrectly with `-std=c++1z`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92438 Bug ID: 92438 Summary: Function declaration parsed incorrectly with `-std=c++1z` Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- Created attachment 47204 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47204&action=edit Demonstration of incorrect parsing + several work-arounds Functions declarations returning a typedef'ed struct-type, and having their names wrapped by parenthesis, as well as a calling-convention attribute within those parenthesis, causes g++ to think that it's a variable declaration, rather than a function declaration. Essentially, given something like this: ``` typedef struct myint_struct { int x; } MYINT; ``` All of the following declarations get parsed correctly: ``` MYINT (myabs1)(MYINT x); MYINT __attribute__((stdcall)) myabs2(MYINT x); struct myint_struct (__attribute__((stdcall)) myabs3)(MYINT x); ``` However, this declaration (incorrectly) causes a parser error: ``` MYINT (__attribute__((stdcall)) myabs4)(MYINT x); ``` Note that the problem only appears when `-std=c++1z` or `-std=gnu++1z` is passed on the commandline, such that you can re-produce the problem with the attached file and: ``` g++ -c -std=c++1z attached-file.cc g++ -c -std=gnu++1z attached-file.cc ``` However, compiling it without any special std=... flag doesn't produce any errors: ``` g++ -c attached-file.cc ```
[Bug c++/92438] [7/8/9/10 Regression] Function declaration parsed incorrectly with `-std=c++1z`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92438 --- Comment #2 from sagebar at web dot de --- The c++ standard may not cover it, however in the interest of compatibility with other compilers, g++ for cygwin actually defines the following predefined macros (among others): g++ -dM -E -x c++ - < /dev/null | grep cdecl ``` #define _cdecl __attribute__((__cdecl__)) #define __cdecl __attribute__((__cdecl__)) ``` Obviously, these are there for compatibility with msvc, and as it turns out: msvc _only_ allows calling convention attributes if they are written between a function's return type, and its name (or in the case of there being parenthesis: only inside of them). ``` // - The only way that msvc accepts it // - One of the ways that g++ for cygwin accepts it int __cdecl foo(); int (__cdecl bar)(); ``` So it does make perfect sense, and in a way is very much intended behavior in my mind that __attribute__((...)) is accepted in that same place, and even more so: If you look at the windows headers used by cygwin, you'll see that this is behavior that is very much depended upon. And even disregarding the (thus far fully maintained) compatibility with msvc as far as the annotation of calling conventions go, this is most definitely still a bug since using the typedef'd name `MYINT` as return type breaks g++, however using the struct's name (including the `struct` prefix) as `struct myint_struct` gets parsed correctly (so whatever would be the ~correct~ way of doing, g++ is inconsistent about it).
[Bug middle-end/92641] New: Function called from dead branch
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92641 Bug ID: 92641 Summary: Function called from dead branch Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- Created attachment 47339 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47339&action=edit Listing of problematic code, and similar code that works correctly Given something like this:``` extern unsigned int get_vla_size(void); ``` This is ok:``` if (0) { (void)(int(*)[get_vla_size()])0; } else { (void)get_vla_size(); } ``` asm:``` call_Z12get_vla_sizev ``` However, re-writing this code to use the ?-operator causes `get_vla_size()` to be called twice:``` 0 ? ( (void)(int(*)[get_vla_size()])0 ) : ( (void)get_vla_size() ); ``` asm:``` call_Z12get_vla_sizev call_Z12get_vla_sizev ``` Note that the first call to `get_vla_size()` happens from within a dead branch, meaning that the call should have been fully removed, or at the very least have been skipped by an unconditional jump. When the first branch is wrapped in statement-expressions, code once again function as expected:``` 0 ? ({ (void)(int(*)[get_vla_size()])0; }) : ( (void)get_vla_size() ); ``` asm:``` call_Z12get_vla_sizev ``` This problem consistently appears when compiling for c++, regardless of optimization level, and if I had to guess, it's probably related to the scope in which some given type is declared, where `type-expr` in `{ int x; 0 ? (type-expr)expr : expr; }` is declared in the same scope as `x`, and thereby unconditionally initialized. The problem can be reproduced using:``` g++ -S attached-file.cc && cat attached-file.s ``` and inspecting the produced output Note: I hope that `middle-end` was the correct place to report this, and I'm sorry if it isn't.
[Bug c++/92641] VLA type finalized at the beginging of the statement rather at the point of use
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92641 --- Comment #2 from sagebar at web dot de --- (In reply to Andrew Pinski from comment #1) > The big question comes, where should the VLA type be finalized, at the use > or at the beginning of the statement. > > Statement expressions create a new statement so you are seeing that. > > I don't know the correct answer. Since VLA types are not part of the C++ > standard, what GCC does currently might be considered the correct answer > (and most likely could not be implemented different either). That may be so, however I find it extremely disconcerting that it is possible to have the contents of a compile-time dead branch be able to affect the generated assembly in ways that can cause some very real side-effects (function calls) at runtime. When I write a macro like `#define ifelse(c, tt, ff) ((c) ? (tt) : (ff))`, then I really _have_ to be able to rely on the fact that whatever happens, and whatever it is passed, _only_ 1 of `tt` or `ff` get evaluated at runtime, no matter what happens between me invoking g++, and eventually running the produced binary. To answer the question as to when finalization of the type should happen: the naive (and probably most comprehensible) answer would be at the end of the dead ?-branch, though I can see how that might be difficult since that branch doesn't have its own scope. I sadly don't know enough of how gcc in particular generates assembly, however I do know how a generic compiler works, so one solution might be to compile `0 ? vla-expr : other-expr' as `jmp 1f; vla-expr; jmp 2f; 1: other-expr; 2:` and use peephole optimization to transform this into `other-expr;`
[Bug c/93087] New: Bogus `-Wsuggest-attribute=cold` on function already marked as `__attribute__((cold))`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93087 Bug ID: 93087 Summary: Bogus `-Wsuggest-attribute=cold` on function already marked as `__attribute__((cold))` Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- Created attachment 47555 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47555&action=edit Issue demonstration Like the title implies, `-Wsuggest-attribute=cold` is emit for functions that were already given the `__attribute__((cold))` annotation The attached file demonstrates the issue, and should be compiled as: ``` gcc -c -O* attached-file.c ``` Where `*` can be any one of `` (empty), `1-3` (though not `0`), `g`, `s`, `fast` Note that the issue doesn't arise when no `-O*` flag is given at all (or when `-O0` is given)
[Bug target/93985] New: Sub-optimal assembly for %st(0) constant loading with SSE enabled (x86_64)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93985 Bug ID: 93985 Summary: Sub-optimal assembly for %st(0) constant loading with SSE enabled (x86_64) Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- Created attachment 47939 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47939&action=edit Inefficient code generation, similar working cases & work-around With gcc for x86_64, where SSE is enabled by default, some situations exist where legacy (fpu) math instructions (and their constraints) still have to be used. x86 offets a hand full of instructions to load specific floating point constants more efficiently (including `1.0`). As such, it would stand to reason to implement a function `atan()` as: ```c double atan(double x) { double result; __asm__("fpatan" : "=t" (result) : "0" (1.0) , "u" (x) : "st(1)"); return result; } ``` This code works perfectly on i386, where it compiles to: ```asm fldl4(%esp) # push(x) fld1 # push(1.0) fpatan ret ``` However, on x86_64 it is compiled as: ```asm movsd .LC0(%rip), %xmm1 movsd %xmm1, -8(%rsp) fldl-8(%rsp) # push(1.0) movsd %xmm0, -8(%rsp) fldl-8(%rsp) # push(x) fxch%st(1)# { x, 1.0 } -> { 1.0, x } fpatan fstpl -8(%rsp) movsd -8(%rsp), %xmm0 ret ... .LC0: .long 0 # SSE constant: 1.0 .long 1072693248# ... ``` When the optimal code would look like: ```asm movsd %xmm0, -8(%rsp) fldl-8(%rsp) # push(x) fld1 # push(1.0) fpatan fstpl -8(%rsp) movsd -8(%rsp), %xmm0 ret ``` Still though, it appears that GCC _is_ aware of the fld1 instruction for encoding inline assembly operands, even when SSE is enabled (s.a. `atan_reverse()` within the attached file). So it would stand to reason that this is either a problem with how GCC weights different encoding schemes, or a problem with how GCC decides if certain encoding schemes are even possible at all (which seems quite likely, especially considering that the x86_64 version contains an fxch-instruction which also wouldn't be necessary if GCC had encoded the `1.0` _after_ pushing `x` (ignoring the fact that `1.0` can be pushed using `fld1`)) NOTE: The attached file should be compiled as `gcc -O3 -S attached-file.c`
[Bug libstdc++/91655] New: Use of `__in` and `__out` as argument names in c++ headers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91655 Bug ID: 91655 Summary: Use of `__in` and `__out` as argument names in c++ headers Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- After building libstdc++ for a custom toolchain that tries to form a hybrid of both linux/gnu system headers, as well as headers normally only found on MSVC (in this case namely: ), I've noticed a problem when it comes to some of the names used for paramters taken/used by functions exposed in headers created by libstdc++ Example: In [`bits/basic_string.tcc`](https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00771_source.html), a function is defined `[...] operator>>(basic_istream<_CharT, _Traits>& __in, [...])` As plainly visible, this function takes (and uses) an argument named `__in`. This causes a collision with a macro defined by MSVC's [``](https://github.com/dotnet/corert/blob/master/src/Native/inc/unix/sal.h) header, which is also used by headers such as ``. I bring up this minor compatibility problem not because it posed too much problems for me (for my purposes, I simply created a [patch](https://github.com/GrieferAtWork/KOSmk4/blob/master/kos/misc/patches/libstdc%2B%2B-9.1.0.patch) file to fix all of those argument names), but because the fix would be so simple that resolving it could possibly take less time than reading this bug report. Of course you are still free to mark this as wont-fix and I would fully understand the decision to not provide for such compatibility with a proprietary Windows header.
[Bug libstdc++/91655] Use of `__in` and `__out` as argument names in c++ headers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91655 --- Comment #2 from sagebar at web dot de --- Of course. I understand, am sorry to have bothered you, and totally agree that those macros are extremely bad (but sadly are being used by programs that I'm trying to provide compatibility for). Have a great day, and thanks for the quick reply
[Bug tree-optimization/90710] New: Bogus Wmaybe-uninitialized caused by __builtin_expect when compiled with -Og
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90710 Bug ID: 90710 Summary: Bogus Wmaybe-uninitialized caused by __builtin_expect when compiled with -Og Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- Created attachment 46442 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46442&action=edit Copy of the code already contained in the description Use of `__builtin_expect()` within `testFunction()` below causes a warning to be falsely emit when compiled as `gcc -Og -Wall test.c': ``` test.c: In function 'testfunction': test.c:22:3: warning: 'value' may be used uninitialized in this function [-Wmaybe-uninitialized] 22 | printf("My if() causes -Wmaybe-uninitialized for my use of `value': %d\n",value); | ^~~~ / ``` Code (`test.c`): ``` #include /* A simple store-value-in-pointer-or-return-error function */ static __inline__ __attribute__((__always_inline__)) unsigned int getValueIfNotZero(unsigned int value, unsigned int *result) { if (value == 0) goto err; *result = value; return 1; err: return 0; } __attribute__((__noinline__)) void testFunction(void) { volatile unsigned int x = 1; unsigned int value; int was_ok = getValueIfNotZero(x, &value); if (was_ok) printf("My if() compiles fine: %d\n",value); if (__builtin_expect(was_ok, 1)) printf("My if() causes -Wmaybe-uninitialized for my use of `value': %d\n",value); } ``` This problem seems to be related to the `-Og` flag, as I was unable to reproduce it with `-O[0-4]` I can personally confirm this warning being emit the same way with: - i686-pc-cygwin-gcc.exe (gcc version 6.4.0) - i686-elf-gcc.exe(gcc version 9.1.0) I can only assume that this also affects all versions between these two My host is a windows 10 machine and I'm using cygwin to run GCC
[Bug tree-optimization/90710] Bogus Wmaybe-uninitialized caused by __builtin_expect when compiled with -Og
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90710 --- Comment #2 from sagebar at web dot de --- (In reply to Jeffrey A. Law from comment #1) > We focus most of our effort on avoiding false positives with -O2 > optimization levels. As you lower the optimization level (-Og) you will > almost certainly run into these kinds of issues. > > Elimination of false positive uninitialized warnings is highly dependent > upon what we call "jump threading". The purpose of jump threading is to > realize that certain paths through the CFG are not possible and to use block > copying to isolate and remove those paths. At lower optimization levels the > compiler does not aggressively thread jumps and thus can leave unexecutable > paths in the CFG which leads to the false positive warning. > > The use of builtin_expect can have these effects too as it impacts the cost > analysis done during jump threading to determine the cost/benefit of block > copying to isolate the path. > > > So confirmed, but not likely something we'll fix in the near future. Thanks for taking the time to explain the what-s and why-s. Dealing with a long-time -O3-compiled codebase (always having optimizations at max prevents nasty surprises later), I was originally trying to use -Og to improve the quality of .debug_info for gdb (I read somewhere that that -Og's supposed to be used for), but for anyone else that has the same Problem and finds this, I managed to get it to work well enough by simply not passing any -O* flags for the time being.
[Bug tree-optimization/90994] New: Bogus Wmaybe-uninitialized with fnon-call-exceptions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90994 Bug ID: 90994 Summary: Bogus Wmaybe-uninitialized with fnon-call-exceptions Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- Created attachment 46517 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46517&action=edit Minimal code that triggers the problem Using a branch-dependent return value in an assembly block with at least 5 line-line or `;` characters, where one of the branches gets triggered by some non-call-exception will result in values conditionally returned by only one of the paths to be considered uninitialized. This behavior seems to be _extremely_ specific, relying on any different factors having to come together to actually trigger the problem. (The attached file is a minimal code example that triggers this) To proove to yourself just how inconsistent this problem appears to be, try moving around the `asm`, or copying it after the second call to `readbyte` (or even just deleting one of its empty lines), and you will see that the warning will vanish. The provided configuration seems to be the only one for which the problem can be reproduced. The problem surfaces with `-O[1-4]` and `-O`, however doesn't with `-Og` or no `-O*` flag at all Removing `-fnon-call-exceptions` and adding an external function call or a conditional `throw`-statement within the `try`-block also seems to prevent the problem. Also note that the problem still happens when the assignment of `*presult` is moved after the `try`-block within `readbyte`, so-long as the read from `*(unsigned char volatile *)1234` stays inside the `try`-block. Compile the attached file with: `g++ -O2 -Wall -fnon-call-exceptions -c bogus.cc` I can personally confirm this problem for: - i686-elf-g++(Version 9.1.0) - i686-pc-cygwin-g++ (Version 6.4.0) - i686-w64-mingw32-g++(Version 7.4.0) - x86_64-pc-cygwin-g++(Version 7.4.0) - x86_64-w64-mingw32-g++ (Version 7.4.0)
[Bug ipa/105682] [12/13 Regression] Both `-Wsuggest-attribute=pure` and `-Wsuggest-attribute=const` on same function since r12-5177-g494bdadf28d0fb35
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105682 --- Comment #8 from sagebar at web dot de --- (In reply to Jan Hubicka from comment #6) > I think the conlcusion here is correct. callee has pure attribute and that > means that it has no side effects except for reading global memory. So > whatever volatile assembly does has to satisfy this. > > Now since assembly is not declared as reading memory, GCC concludes that the > function has no side effects and does not read global memory and this can be > uprgraded to const. This assumes that reading memory is the only thing inline assembly can do to access (part of) the global state. But consider the following example where the ARM FPU control word is read: ``` #include // HINT: this is arm assembly //#define _FPU_GETCW(cw) __asm__ __volatile__("vmrs %0, fpscr" : "=r" (cw)) //#define _FPU_SETCW(cw) __asm__ __volatile__("vmsr fpscr, %0" : : "r" (cw)) __attribute__((pure)) fpu_control_t getcw() { fpu_control_t result; _FPU_GETCW(result); return result; } int main() { fpu_control_t before, after; before = getcw(); _FPU_SETCW(0x1234); after = getcw() printf("oldcw: %d\n", before); printf("newcw: %d\n", after); } ``` If you're saying that a `__asm__ __volatile__` that doesn't access memory should be considered as `const`, then gcc should be allowed to remove the first `getcw()` and simply assign the same value to `before` and `after` (since a `const` function's return value only depends on its arguments, meaning it calls can be removed and re-ordered however gcc pleases). I think you can see how that would be a problem in the above. However: I would understand gcc doing this if `_FPU_GETCW` was implemented using `__asm__` instead of `__asm__ __volatile__`. (If I'm misunderstanding how `pure` is meant to work, please correct me. But as far as I understand it, the above is a correct usage examle)
[Bug c/105676] New: Bogus `-Wsuggest-attribute=pure` on function marked `__attribute__((const))`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105676 Bug ID: 105676 Summary: Bogus `-Wsuggest-attribute=pure` on function marked `__attribute__((const))` Product: gcc Version: 12.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- When compiling with `-Wsuggest-attribute=pure`, gcc warns about missing `__attribute__((pure))` on functions declared as `__attribute__((const))`. It is common knowledge that any function marked as `__attribute__((const))` also implicitly has the behavior of a function marked as `__attribute__((pure))` (const implies pure). Therefor, it stands to reason that such a warning is bogus (also: earlier version of gcc didn't emit a warning in this case; know: gcc-9 already supported these warnings, but didn't emit `-Wsuggest-attribute=pure` on a `__attribute__((const))` function). Example (`gcc -Wsuggest-attribute=pure -c -O2 input.c`): ``` __attribute__((const)) extern int do_expensive_calculation(void); __attribute__((const)) int getval(void) { static int cache = -1; if (cache == -1) cache = do_expensive_calculation(); return cache; } ``` >test.c: In function 'getval': >test.c:5:5: warning: function might be candidate for attribute 'pure' >>[-Wsuggest-attribute=pure] >5 | int getval(void) { > | ^~ When trying to declare as both pure+const: >test.c:5:1: warning: ignoring attribute 'const' because it conflicts with >attribute 'pure' [-Wattributes] >5 | int getval(void) { > | ^~~ Explaination of why using `__attribute__((const))` is valid here I see why gcc might think that `getval()` is *only* `pure`, but there is nothing wrong with the `__attribute__((const))` annotation since we don't "read global memory" (emphasis on the "global"), and thus don't depend on the global state (also: what counts as "global" vs. "non-global" isn't something that can be quantified. - It depends on the application and how memory is used). As such, the use of `__attribute__((const))` is very much valid (and gcc might even consider suggesting `__attribute__((const))` instead of `__attribute__((pure))`, since because `cache` is scoped-static, it not being used outside of `getval()` can actually be proven, though that isn't what this bug report is about...). However, so-long as it believes that the function is pure, there is no reason to ever emit a about that fact so-long as `getval()` remains annotated as `__attribute__((const))`. End of Explaination
[Bug c/105682] New: Both `-Wsuggest-attribute=pure` and `-Wsuggest-attribute=const` on same function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105682 Bug ID: 105682 Summary: Both `-Wsuggest-attribute=pure` and `-Wsuggest-attribute=const` on same function Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- The following example causes both a `-Wsuggest-attribute=pure` and `-Wsuggest-attribute=const` warning for the same function. Additionally, in this example, only `-Wsuggest-attribute=pure` would be correct (the `-Wsuggest-attribute=const` is completely bogus): Compile with `gcc -c -O2 -Wsuggest-attribute=const -Wsuggest-attribute=pure input.c`: ``` __attribute__((pure)) int callee(int x) { unsigned int a; __asm__ __volatile__(""); __asm__ __volatile__("" : "=X" (a)); x &= 1; if (a & 2) __asm__ __volatile__("" : "=m" (x)); return x & 4; } int caller(int x) { return callee(x); } ``` Output (gcc-12.1.0): >input.c: In function 'caller': >input.c:12:5: warning: function might be candidate for attribute 'pure' >[-Wsuggest-attribute=pure] > 12 | int caller(int x) { > | ^~ >input.c:12:5: warning: function might be candidate for attribute 'const' >[-Wsuggest-attribute=const] Output (gcc-11.2.0; expected behavior): >input.c: In function 'caller': >input.c:12:5: warning: function might be candidate for attribute 'pure' >[-Wsuggest-attribute=pure] > 12 | int caller(int x) { > | ^~ === After adding `__attribute__((pure))` to `caller` === ``` __attribute__((pure)) int caller(int x) { return callee(x); } ``` gcc-12.1.0 (bogus warning: `caller()` has no right to be const; it calls a pure function, and that function even contains inline assembly): >infile.c: In function 'caller': >infile.c:13:5: warning: function might be candidate for attribute 'const' >[-Wsuggest-attribute=const] > 13 | int caller(int x) { > | ^~ gcc-11.2.0 (expected behavior): > (No warnings) === NOTES: - Not only does gcc suggest to add both pure & const to the same function, the later wouldn't even make any sense in this scenario (though suggesting `pure` is correct). - The strange-looking body of `callee()` is required to reproduce the bug. - Trying to further simplify it tends to make the warning go away, suggesting a problem with some kind of heuristic. - I know I also just reported https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105676, but that one is about a bogus `-Wsuggest-attribute=pure` warning, while this one is about a bogus `-Wsuggest-attribute=const` warning. The two bugs may be related, but simply suppressing `-Wsuggest-attribute=pure` on const-functions wouldn't be enough to fix the bug addressed in this report.
[Bug c/105684] New: Bogus `-Warray-bounds` in partially allocated struct
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105684 Bug ID: 105684 Summary: Bogus `-Warray-bounds` in partially allocated struct Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- Accessing the fields of a partially allocated struct results in `-Warray-bounds`, even when all accessed fields lie within the allocated portion of the struct (a fact that can be proven to be known to gcc by asking it for `__builtin_object_size()`) Example (compile with `gcc -c infile.c -O2 -Warray-bounds -S -o -`): ``` struct obj { unsigned long long kind; union { struct { unsigned long long a; } data0; struct { unsigned long long a; unsigned long long b; } data1; }; }; extern __attribute__((alloc_size(1))) void *my_malloc(unsigned long); #define offsetafter(s, m) (__builtin_offsetof(s, m) + sizeof(((s *)0)->m)) struct obj *create_object_kind_0(void) { struct obj *result; result = (struct obj *)my_malloc(offsetafter(struct obj, data0)); __asm__ __volatile__("# Object size is: %p0" : : "X" (__builtin_object_size(result, 0))); result->kind= 0; result->data0.a = 1; return result; } ``` Real-world use-case & rationale: the idea is that access to `data1` vs. `data0` is governed by the value of `kind` (`obj` is a "typed variant"), and by allocating only the relevant portion of the object, we can save memory, and create an environment where buggy code that wrongfully accesses (e.g.) certain fields of `data1` of a `kind=0` object might cause the program to crash (rather than remain unnoticed as would be the case when simply using `sizeof(struct obj)` as allocation size). Expected behavior: no warnings should be generated == Actual behavior (Truncated) === >[stderr]infile.c: In function 'create_object_kind_0': >[stderr]infile.c:22:15: warning: array subscript 'struct obj[0]' is partly >outside array bounds of 'unsigned char[16]' [-Warray-bounds] >[stderr] 21 | result->kind= 0; >[stderr] | ^~ >[stderr]infile.c:20:32: note: object of size 16 allocated by 'my_malloc' >[stderr] 19 | result = (struct obj *)my_malloc(offsetafter(struct >obj, data0)); >[stderr] | >^ >[stderr]infile.c:23:15: warning: array subscript 'struct obj[0]' is partly >outside array bounds of 'unsigned char[16]' [-Warray-bounds] >[stderr] 22 | result->data0.a = 1; >[stderr] | ^~ >[stderr]infile.c:20:32: note: object of size 16 allocated by 'my_malloc' >[stderr] 19 | result = (struct obj *)my_malloc(offsetafter(struct >obj, data0)); >[stderr] | >^ >[stdout][...] >[stdout]/ 22 "infile.c" 1 >[stdout]# Object size is: 16 >[stdout]/ 0 "" 2 >[stdout]/NO_APP >[stdout]movl$0, (%eax) >[stdout]movl$0, 4(%eax) >[stdout]movl$1, 8(%eax) >[stdout]movl$0, 12(%eax) >[stdout]leave >[stdout]ret >[stdout][...] As can be seen by `# Object size is: 16` (and repeated in warning messages), gcc knows that the allocated size of the object is 16 bytes, and as can be seen by the offsets used by the `movl` instructions, this limit is never exceeded. Judging by what the warnings state (and confirmed by replacing `offsetafter(struct obj, data0)` with `sizeof(struct obj)`), the `-Warray-bounds` warning will always be generated for any accessed field (irregardless of that field's offset) so-long as `__builtin_object_size(result, 0) < sizeof(struct obj)`. I am uncertain about the intended semantics of `-Warray-bounds`, and technically speaking, the warning is stating the truth: "'struct obj[0]' is partly outside array bounds" (emphasis on the "partly"). However, as it stands right now, warning about this situation is less than useful (a warning might arguably be useful when passing `result` -- or a pointer to one of its members -- to some other function, but even in that situation a warning would probably be a false positive). So in my opinion, at `-Warray-bounds[=1]`, a warning should only be generated exactly in those cases where an out-of-bounds access *actually* happens (*possible* out-of-bounds warnings may appear at `-Warray-bounds=2`, but defini
[Bug ipa/105685] New: Still Bogus `-Wsuggest-attribute=cold` on function already marked as `__attribute__((cold))`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105685 Bug ID: 105685 Summary: Still Bogus `-Wsuggest-attribute=cold` on function already marked as `__attribute__((cold))` Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de CC: marxin at gcc dot gnu.org Target Milestone: --- I would re-open https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93087, but I don't think I can so a new bug report it is... - Anyways: while my test-case from back then remains fixed, the same problem still happens for the following code: Run (`gcc -c -O2 -Wsuggest-attribute=cold infile.c`) ``` extern void external_fun(char *, char const *, int); __attribute__((cold)) char *my_cold_fun(int x) { static char b[42]; external_fun(b, "Without me, the warning disappears?", x); return b; } __attribute__((cold)) char *my_other_cold_fun(int x) { return my_cold_fun(x); } ``` Output >infile.c: In function 'my_other_cold_fun': >infile.c:9:29: warning: function might be candidate for attribute 'cold' >[-Wsuggest-attribute=cold] >9 | __attribute__((cold)) char *my_other_cold_fun(int x) { > | ^ Output (Expected) >
[Bug c/105689] New: Bogus `-Wstringop-overflow=` after accessing field, then containing struct (wrong "region size")
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105689 Bug ID: 105689 Summary: Bogus `-Wstringop-overflow=` after accessing field, then containing struct (wrong "region size") Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- The following code wrongly produces a warning `[-Wstringop-overflow=`: Compile (using `gcc -c -O2 infile.c`) ``` struct subobject { int field1; int field2; }; struct myobject { struct subobject sub; }; extern void access_1(int *a); extern __attribute__((access(read_write, 1))) void access_2(struct subobject *); void myfunc(struct myobject *me) { // { void *p __attribute__((unused)) = &me->sub; } access_1(&me->sub.field1); access_2(&me->sub); } ``` === Output (gcc-12) === >infile.c: In function 'myfunc': >infile.c:16:9: warning: 'access_2' accessing 8 bytes in a region of size 4 >[-Wstringop-overflow=] > 16 | access_2(&me->sub); > | ^~ >infile.c:11:52: note: in a call to function 'access_2' declared with attribute >'access (read_write, 1)' > 11 | extern __attribute__((access(read_write, 1))) void access_2(struct > subobject *); > |^~~~ === Output (expected) === > === Notes === - By uncommenting the line `{ void *p __attribute__((unused)) = &me->sub; }`, the warning goes away, even though that line literally does nothing. (see Theory below) - I was able to observe this bug in gcc-12.1.0 and gcc-11.2.0 === Theory === It seems that this has got something to do with some internal, hidden attribute (relating to the "region size") attached to some field-expression the first time that field is accessed, only that when accessing `me->sub.field1` (where `offsetof(field1) == 0`) before `me->sub`, that "region size" attribute wrongfully also gets attached to `me->sub`. Then, when an access to `me->sub` actually happens, gcc seems to think that the "region size" of `me->sub` as a whole matches the size of the previously accessed field (`me->sub.field1`). This seems further compounded by the fact that this only happens when `field1` is the first field of `subobject` (i.e. has offset 0). If we insert another field `int field0;` before it, the warning also disappears (so something in gcc's logic appears to make it think that `region_size_of() == region_size_of()`)
[Bug tree-optimization/105684] Bogus `-Warray-bounds` in partially allocated struct
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105684 --- Comment #3 from sagebar at web dot de --- >The issue is that 'result->data0.a' is (*result).data0.a, and so to GCC you are >accessing an object of type 'obj' for which there isn't enough allocated space. Technically true, and yes: not dereferencing `result` while it's still a `struct obj` makes the warning go away: ``` - result->kind= 0; - result->data0.a = 1; + *(unsigned long long *)((char *)result + __builtin_offsetof(struct obj, kind)) = 0; + *(unsigned long long *)((char *)result + __builtin_offsetof(struct obj, data0.a)) = 1; ``` But that's like saying `int x = obj->field;` is the same as `int x = ({ typeof(*obj) c = *obj; c.field; })` (i.e. accessing 1 field is like accessing _all_ fields) -- They're just not the same: accessing a single field simply doesn't cause the rest of the containing struct to also be loaded (if there's some weird arch where it does ???, fine; but then this should be an arch-specific warning). >A workaround might be to declare 'obj' as > >struct obj { > unsigned long long kind; > unsigned long long data[]; >}; > >if in your case all data is really uniform 'unsigned long long'. There's >no way to union several different typed flexarrays though. It would for the demo-code, but that's not the context where I encountered this problem in the real world. For reference, the following is the "typed variant"-style struct which lead me to create this bug report: https://github.com/GrieferAtWork/KOSmk4/blob/master/kos/src/kernel/moddbx/include/ctype.h#L193 I simply crafted the minimal viable code that still causes the warning for the sake of making this bug report.
[Bug debug/111080] New: restrict qualifier leaks debug info
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111080 Bug ID: 111080 Summary: restrict qualifier leaks debug info Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- The the following code example, debug information is retained for `struct foo` even though that structure doesn't end up used: Compile as `gcc -g -S -o - in.c | grep field_number` ``` struct foo { int field_number_1; int field_number_2; int field_number_3; int field_number_4; int field_number_5; }; typedef int fun_t(struct foo *restrict); int main() { return 0; } ``` Output: gcc -g -S -o - test.c | grep field_number .ascii "field_number_1\0" .ascii "field_number_2\0" .ascii "field_number_3\0" .ascii "field_number_4\0" .ascii "field_number_5\0" When removing the `restrict` qualifier in the parameter of `funptr_t`, debug information is not included in the produced assembly (as one would expect). Here is a list of different declarations and where `struct foo` is leaked in gcc 12.1.0: > typedef int fun_t(struct foo *restrict);// Leak > typedef int fun_t(struct foo *);// No leak > typedef int (*fun_t)(struct foo *restrict); // Leak > typedef int (*fun_t)(struct foo *); // No leak > extern int fun_t(struct foo *restrict); // No leak > extern int fun_t(struct foo *); // No leak > extern int (*fun_t)(struct foo *restrict); // Leak > extern int (*fun_t)(struct foo *); // No leak > static int fun_t(struct foo *restrict); // No leak > static int fun_t(struct foo *); // No leak > static int (*fun_t)(struct foo *restrict); // Leak > static int (*fun_t)(struct foo *); // Leak (even w/o restrict!) > int fun_t(struct foo *restrict);// No leak > int fun_t(struct foo *);// No leak > int (*fun_t)(struct foo *restrict); // Leak > int (*fun_t)(struct foo *); // Leak (even w/o restrict!) There is no difference when using `__restrict` or `__restrict__` instead.
[Bug debug/111080] [11/12/13/14 Regression] restrict qualifier causes extra debug info to happen
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111080 --- Comment #2 from sagebar at web dot de --- @Andrew Pinski Of course: yes. I did make a mistake there, but only for this case: > int (*fun_t)(struct foo *); // Leak (even w/o restrict!) asm: ... .globl fun_t .section.bss .align 4 .type fun_t, @object .size fun_t, 4 fun_t: .zero 4 ... In the other case: > static int (*fun_t)(struct foo *); // Leak (even w/o restrict!) asm: ... # No data-symbol is generated for `fun_t` ... Gcc actually doesn't generate a .bss-symbol for the static variable (since it's unused), but it still generates debug inforation for `struct foo`. So I guess strike `int (*fun_t)(struct foo *);` from the list, but keep `static int (*fun_t)(struct foo *);` which still leaks
[Bug driver/110607] New: Makefile.in build broken build-tools when CXXFLAGS is defined
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110607 Bug ID: 110607 Summary: Makefile.in build broken build-tools when CXXFLAGS is defined Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: driver Assignee: unassigned at gcc dot gnu.org Reporter: sagebar at web dot de Target Milestone: --- This part in the main makefile: > 177 # These variables must be set on the make command line for directories > 178 # built for the build system to override those in BASE_FLAGS_TO_PASS. > 179 EXTRA_BUILD_FLAGS = \ > 180 CFLAGS="$(CFLAGS_FOR_BUILD)" \ > 181 LDFLAGS="$(LDFLAGS_FOR_BUILD)" Should instead be: > 177 # These variables must be set on the make command line for directories > 178 # built for the build system to override those in BASE_FLAGS_TO_PASS. > 179 EXTRA_BUILD_FLAGS = \ > 180 CFLAGS="$(CFLAGS_FOR_BUILD)" \ > 181 CXXFLAGS="$(CXXFLAGS_FOR_BUILD)" \ > 182 LDFLAGS="$(LDFLAGS_FOR_BUILD)" Since some components of the build system are compiled as c++, if one wants to define custom CXX-flags in cross-compilation situations, these flags then also get used when building build-tools (which causes breakage)
[Bug bootstrap/110607] Makefile.in builds broken build-tools when CXXFLAGS is defined
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110607 --- Comment #2 from sagebar at web dot de --- @Andrew Pinski Sorry if this is a known bug. I simply checked the current gcc master (https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=Makefile.tpl;h=d0fe7e2fb778b3c3fa2cc8742e06cf1f78fdc5f2;hb=HEAD#l183), which is still affected. I was not aware that a fix was already pending but not yet merged.