[Bug other/29442] insn-attrtab has grown too large
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29442 Gašper Ažman changed: What|Removed |Added CC||gasper.azman at gmail dot ||com --- Comment #11 from Gašper Ažman 2012-05-02 16:28:52 UTC --- I can confirm this is still a problem on 2.5.3. Compiling on a system with 256MB memory (hired, remote, virtualized) is not possible without an extra 1GB of memory and almost nothing else running (the memory usage peaked at full RAM and 522MB swap used, with gcc using everything but 60MB).
[Bug c++/98660] New: -Wold-style-cast should not warn on casts that look like (decltype(x))(x)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98660 Bug ID: 98660 Summary: -Wold-style-cast should not warn on casts that look like (decltype(x))(x) Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gasper.azman at gmail dot com Target Milestone: --- Dear GCC wizards, Recently, the use of std::forward has been idiomatically replaced by the following: ``` template void george(T&& x) { john((T&&)x); // means std::forward(x) } ``` Casting an `x` to `decltype(x)` is far shorter and faster to compile (which matters since it's done in unevaluated contexts A LOT). For an example, observe the usage in libunifex, the in-progress research implementation of the executors proposal: https://github.com/facebookexperimental/libunifex/blob/master/include/unifex/tag_invoke.hpp Unfortunately, the only real way to combine this fairly important exception to the general rules of "no c-style casts" is to disable -Wold-style-cast. It would be a great benefit if I could leave that warning enabled, and sleep soundly in the knowledge I didn't mistype the forwarding expression if gcc checked for me that the type I'm casting to is, in fact, `decltype(x)`, and complain otherwise. Please consider this refinement for a future release of GCC. Thank you.
[Bug c++/98660] -Wold-style-cast should not warn on casts that look like (decltype(x))(x)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98660 --- Comment #2 from Gašper Ažman --- Ivan: indeed, you could use a static cast, or a macro - you're literally just changing the value category of the expression to its original one. The cast is safe. The reason Niebler and friends (including me) are using the c-style cast is purely because it's short, concise, unambiguous, and fast to compile. `static_cast(x)` is a lot longer than `(T&&)x`. When you have 6 or 10 of these expressions (often with `...`s) in a function declaration (please see the `tag_invoke` definition linked), the noise starts to matter.
[Bug c++/98660] -Wold-style-cast should not warn on casts that look like (decltype(x))(x)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98660 --- Comment #4 from Gašper Ažman --- @Eric Gallager: yes, the #pragma solution is what I currently use. It is entirely unsatisfactory, for the reasons described in my original request. The long-term usefulness of warnings is directly proportional to the number of false positives they generate. If I wanted to enforce the warning in most of the code, and only disable it where appropriate, this is what that looks like, on a non-terrible example (borrowed from libunifex): #pragma GCC diagnostic push #pragma GCC diagnostic ignore "-Wold-style-cast" template constexpr auto operator()(CPO cpo, Args&&... args) const noexcept(noexcept(tag_invoke((CPO &&) cpo, (Args &&) args...))) -> decltype(tag_invoke((CPO &&) cpo, (Args &&) args...)) { return tag_invoke((CPO &&) cpo, (Args &&) args...); } #endif Now please, kindly tell me how I can know I didn't screw up a C-style cast in that mess? It turns out that in the example above, ALL the casts mean std::forward, but imagine it was a function where only some of the arguments are forwarded, and a co-worker mistakenly puts in a c-style cast that doesn't just change the value-category. I'm asking for this warning to get more useful by still diagnosing c-style casts that change more than the value category, and not diagnosing c-style casts that are the "safest" kind - value category only, since that's what the idiom seems to be.
[Bug c++/98660] -Wold-style-cast should not warn on casts that look like (decltype(x))(x)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98660 --- Comment #5 from Gašper Ažman --- s/endif/pragma GCC diagnostic pop
[Bug c++/102609] [C++23] P0847R7 - Deducing this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 --- Comment #4 from Gašper Ažman --- As one of the authors, I can assure you you never need to implement this for c++23.
[Bug c++/102609] [C++23] P0847R7 - Deducing this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 --- Comment #5 from Gašper Ažman --- And of course by "this" I meant support for a default argument on the explicit object parameter. We might add it back in the future if we find a usecase.
[Bug c++/102609] [C++23] P0847R7 - Deducing this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 --- Comment #10 from Gašper Ažman --- Yes, the explicit object parameter always receives the cv-l/r qualified reference to the object of the call. Implicit conversions are then of course allowed, same as any other parameter. S* is not that useful as a type of an explicit object parameter, implicit conversions to pointer to yourself are probably about as weird as overloading operator&(). Also, don't forget explicit object function bodies and their type behave a lot more like static functions than member functions. On Sat, Aug 19, 2023, 10:43 redi at gcc dot gnu.org < gcc-bugzi...@gcc.gnu.org> wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 > > --- Comment #9 from Jonathan Wakely --- > If we're right about that, then I agree that a warning would be useful for > classes that have no such implicit conversion from S to S*. > > I think the warning would give a false positive in the case below, so a > way to > disable it locally would be needed (e.g. via a diagnostic pragma). > > struct S { > int f(this S*); // warning: explicit object parameter of pointer type can > only match if an implicit conversion to S* exists > }; > > struct T : S { > operator T*(); > }; > > T t; > int i = t.f(); // derived class has the required conversion > > -- > You are receiving this mail because: > You are on the CC list for the bug.
[Bug c++/102609] [C++23] P0847R7 - Deducing this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 --- Comment #12 from Gašper Ažman --- Replies to relevant snippets inline. That was quite a write-up! > The only compelling case I can think of for such a thing would be passing a > pointer type that isn't related by inheritance anyway. That is to say, I'm not > disagreeing with you, I just stopped to think about it and came up with this, > consider the following example. > > struct my_function { > using func_ptr = void(*)(int); > func_ptr _f; > > void operator()(this func_ptr f, int a) { > return f(a); > } > > operator func_ptr() const { > return _f; > } > }; This case is already covered by surrogate functions: struct S { using fptr = int(*)(int); operator fptr() const { return +[](int){return 42;}; } }; int main() { S x; x(3); // OK, returns 42 } https://godbolt.org/z/48Efzdr1q The conversion operator is a better match in this case, so the operator() which requires an implicit conversion is not the one called. > > I'm mostly just excited to share what I finally thought of as a good example > for an explicit object parameter that is not of a deduced or base type, but > it's never the less a pointer type. Converting to a pointer-type is not weird; it's converting to pointer to your own type that is. Any proxy object with a conversion operator to its underlying will have that if the underlying happens to be a pointer type. Such a proxy object might well forward methods directly to the underlying object via a conversion instead of stamping out a body for each cv-ref qualifier. > Granted, I think this type of use should also have some sort of warning > available as it is still weird. I disagree; conversion to your own type I think is a reasonable warning (unless you have a conversion operator in the same class) because it can come with a fixit hint (replace with reference to S instead). All other types are legit. > I think a warning for declaring an explicit object parameter as a pointer to > base, derived, or deduced type should be in, since a reference is probably the > best choice in that case. I definitely agree that this warning is reasonable. > Perhaps deduced type shouldn't be included in that > warning, as there are cases that are kind of compelling for having that, one > could trap implicit conversions to any pointer type that way on derived > classes. Yeah, deduced is legit, no warning for that one unless we discover active pathologies. > To elaborate on what I said above, I still think a warning when using a type > that is not related to the class should be provided. Strong disagree, that'll break a lot of code I actually intend to write. Not stamping out additional template instantiations / better ABI by having implicit conversions will, I expect, be quite the common implementation trick (for instance, any member algorithm on a vector that doesn't change size can be called on an equivalent span instead and therefore be passed in registers). This can be an implementation detail of vector, so that vector and array can share template instantiations, for instance. > Even given that my example > above presents a legitimate pattern, I think it's use is infrequent enough to > provide an optional warning for this. I question if there's any value in > suppressing the warning when there are legitimate conversions present, as it > would no longer inform the user that they might have done something by > mistake. I think my ruminations above give a good example of why such false positives should definitely be expected in well-behaved code. > Essentially, since it's not possible to warn that there are no viable > conversions without false positives occurring, I think the warning should be > present simply because you are doing something weird, not because you are > declaring a function that won't be selected by overload resolution. Yes, but you can get a pointer to it and call it directly. Might be a useful way to pass overload sets. > Just to reiterate, I fully agree that both warnings should be behind a flag. I > think I would propose that the first (warning for pointer to base, derived, or > deduced type in an explicit object parameter) should be turned on by default, > while the second should be turned off by default. I'm not sure the second one should even exist, as it's bound to be even more annoying than -Wshadow. > > struct S : B { > int f0(this B*) {} // warning 1, on by default > int f1(this S*) {} // warning 1, on by default > int f2(this auto*) {} // warning 1, on by default?, separate warning? > > int f3(this int) {} // warning 2, off by default(?) > }; I say no warning on f2. S could be a CRTP-sans-CRTP mixin that expect that conversion to exist. > > On the other hand, warning 2 could be split into 2 warnings, where one would > warn for a "weird" explicit object parameter, while the other would warn for > uncallable functions due t
[Bug c++/102609] [C++23] P0847R7 - Deducing this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 --- Comment #17 from Gašper Ažman --- Read through the patch quickly, want to suggest a few tests. When a lambda has captures, the explicit object parameter is used to get at them *silently*, if they are related, otherwise the program is ill-formed: int x = 42; auto f1 = [x](this auto&&) { return x; }; auto f2 = [](this auto&&) { return 42; } static_cast(decltype(f1)::operator()); // OK static_cast(decltype(f1)::operator()); // ERROR static_cast(decltype(f2)::operator()); // OK
[Bug c++/102609] [C++23] P0847R7 - Deducing this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 --- Comment #19 from Gašper Ažman --- Correct, the use of the capture is the source of the error, not the instantiation with an unrelated type. On Sat, Sep 2, 2023, 09:54 waffl3x at protonmail dot com < gcc-bugzi...@gcc.gnu.org> wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 > > --- Comment #18 from waffl3x --- > (In reply to Gašper Ažman from comment #17) > > Read through the patch quickly, want to suggest a few tests. > > > > When a lambda has captures, the explicit object parameter is used to get > at > > them *silently*, if they are related, otherwise the program is > ill-formed: > > > > int x = 42; > > auto f1 = [x](this auto&&) { > >return x; > > }; > > auto f2 = [](this auto&&) { return 42; } > > > > static_cast(decltype(f1)::operator()); // OK > > static_cast(decltype(f1)::operator()); // ERROR > > static_cast(decltype(f2)::operator()); // OK > > Ah I see, thanks for the input. I was actually wondering about that, > especially > if you were expected to use the explicit object parameter to access > captures. > Is my understanding correct that the second case would not be an error if > captures were not used in the body of the lambda? Based on your wording I > would > believe that is the case, so implementing this behavior would not be as > simple > as just disallowing unrelated deduced types when there are captures. > > Unfortunately, I will not have access to my computer for a while more, I > plan > on setting up an environment at another computer and fixing the formatting > errors that were noted, but I will wait until I have access to my computer > before I work on it more seriously I think. > > Thanks a lot for looking at the patch though, I really appreciate the time > you've taken. > > -- > You are receiving this mail because: > You are on the CC list for the bug.
[Bug c++/110380] New: [feature request] "-pg-constexpr=coverage-output" emit coverage metrics for constexpr code evaluated at compile time
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110380 Bug ID: 110380 Summary: [feature request] "-pg-constexpr=coverage-output" emit coverage metrics for constexpr code evaluated at compile time Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gasper.azman at gmail dot com Target Milestone: --- We've been converting so much code to constexpr that entire test suites are now evaluated at compile time. This is a problem because traditional coverage metrics have become useless, but compile time evaluation is desirable due to deep-UB checking. It would be nice if gcc could emit coverage metrics for code that it executed at compile time during the build, so that prof could combine it with the rest of the test coverage. Probably not a high priority, but a nice-to-have at some point.
[Bug c++/110380] [feature request] "-pg-constexpr=coverage-output" emit coverage metrics for constexpr code evaluated at compile time
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110380 --- Comment #2 from Gašper Ažman --- -fprofile-constexpr is perfectly fine :), as long as it gets a filename argument for the output; build automation will be thankful.
[Bug c++/110380] [feature request] "-pg-constexpr=coverage-output" emit coverage metrics for constexpr code evaluated at compile time
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110380 --- Comment #4 from Gašper Ažman --- John McFarlane noted that pre-initializing coverage datastructures with the results of the constexpr-evaluated traces would also be a possible direction. It does mean the linker needs to then correctly merge those, otherwise you lose constexpr coverage at link time.
[Bug c++/110441] c++17: temporary causes static member function call to confuse required copy elision
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110441 Gašper Ažman changed: What|Removed |Added CC||gasper.azman at gmail dot com --- Comment #1 from Gašper Ažman --- I hit this in gcc 10 as well when implementing sender/receiver. Was not able to reduce it this nicely, so I didn't report. Nice work, Eric.
[Bug c++/110441] c++17: temporary causes static member function call to confuse required copy elision
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110441 --- Comment #2 from Gašper Ažman --- Some more color from twitter, courtesy of @matthewecross: Interestingly both "return S::f();" and "auto s = S(); return s.f();" both pass. It's only when you create a temporary instance of S in the return statement that it fails.
[Bug c++/102609] [C++23] P0847R7 - Deducing this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 --- Comment #27 from Gašper Ažman --- I think there is an example in the standard that distinguishes those two as far as overload resolution is concerned. On Thu, Jan 11, 2024, 21:08 waffl3x at protonmail dot com < gcc-bugzi...@gcc.gnu.org> wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 > > --- Comment #26 from waffl3x --- > (In reply to corentinjabot from comment #25) > > Hey folks. > > Congrats on landing support for deducing this in GCC. > > Thanks! > > > While there is no spec for it, after discussion here, > > https://github.com/itanium-cxx-abi/cxx-abi/issues/148 explicit objects > > parameters are mangled with `H` > > This is the form that has been adopted for Clang. > > > > The reason we need mangling is because WG21 made the following > well-formed > > (and that was reaffirmed. In fact, some complexity was added by P2797) > > > > > >struct S { > > static void f(S); > > void f(this S); > >}; > > > > And we need a way to distinguish both functions > > I wasn't sure you were aware of this; I hope that form of mangling will > work > > for you. > > > > > > Thanks > > I don't have the experience to comment but my gut says this is a weird > outcome. Oh well! I think I know how to implement this so I'll give it > a go at some point today. If I have any trouble I'll leave it for > someone else. > > Thanks for informing us. > > -- > You are receiving this mail because: > You are on the CC list for the bug.
[Bug c++/102609] [C++23] P0847R7 - Deducing this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609 --- Comment #30 from Gašper Ažman --- I don't really understand what you meant by "they have corresponding object parameters" - you mean that the object parameters are equal in both constraint and type? "Corresponding" to my recollection is only used for argument-to-parameter correspondence, but I could be wrong.
[Bug c++/117983] New: [13.2 regression] -Wstringop-overflow false positive for __builtin_memmove from vector::insert
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117983 Bug ID: 117983 Summary: [13.2 regression] -Wstringop-overflow false positive for __builtin_memmove from vector::insert Product: gcc Version: 13.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gasper.azman at gmail dot com Target Milestone: --- Repro on GCC 13.3 and 14: https://godbolt.org/z/EdfGEfGcr code: ``` #include #include class buffer { void push(std::vector chunk); std::vector _data; }; void buffer::push(std::vector chunk) { if (_data.empty()) { _data.swap(chunk); } else { _data.insert(_data.end(), chunk.begin(), chunk.end()); } } ``` As you can see, perfectly normal. Compiling with `-Wall -Wextra -O3`: x86-64 gcc 14.2 - 661ms (257546B) ~16635 lines filtered In file included from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/vector:62, from :2: In static member function 'static _Up* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(_Tp*, _Tp*, _Up*) [with _Tp = unsigned char; _Up = unsigned char; bool _IsMove = false]', inlined from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned char*; _OI = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_algobase.h:521:30, inlined from '_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned char*; _OI = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_algobase.h:548:42, inlined from '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = __gnu_cxx::__normal_iterator >; _OI = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_algobase.h:555:31, inlined from '_OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator >; _OI = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_algobase.h:651:7, inlined from 'static _ForwardIterator std::__uninitialized_copy::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator >; _ForwardIterator = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_uninitialized.h:147:27, inlined from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator >; _ForwardIterator = unsigned char*]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_uninitialized.h:185:15, inlined from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator >; _ForwardIterator = unsigned char*; _Tp = unsigned char]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_uninitialized.h:373:37, inlined from 'void std::vector<_Tp, _Alloc>::_M_range_insert(iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = __gnu_cxx::__normal_iterator >; _Tp = unsigned char; _Alloc = std::allocator]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/vector.tcc:1022:38, inlined from 'std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(const_iterator, _InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator >; = void; _Tp = unsigned char; _Alloc = std::allocator]' at /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_vector.h:1488:19, inlined from 'void buffer::push(std::vector)' at :12:21: /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/stl_algobase.h:452:30: warning: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' writing between 2 and 9223372036854775807 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=] 452 | __builtin_memmove(__result, __first, sizeof(_Tp) * _Num); | ~^~~ In file included from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/x86_64-linux-gnu/bits/c++allocator.h:33, from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/allocator.h:46, from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/vector:63: In member function '_Tp* std::__new_allocator<_Tp>::allocate(size_type, const void*) [with _Tp = unsigned char]', inlined from 'static _Tp* std::allocator_traits >::allocate(allocator_type&, size_type) [with _Tp = unsigned char]' at /opt/compiler-explorer/gcc-14.2.0/incl