RE: [EXTERNAL] Re: GCC selftest improvements
Hey all, I'm picking this work up from Andrew. Last time it was decided that the timing wasn't right to upgrade the minimum version to C++11. Is the timing better now to get this change through? I've attached the patch Andrew prepared. Can I get feedback on the change and some help testing on the broader range of architectures/platforms? Thanks, Modi c++11.patch Description: c++11.patch
RE: [EXTERNAL] Re: GCC selftest improvements
> On 2/12/20 8:53 PM, David Malcolm wrote: > > Thanks for the patch. > > > > Some nitpicks: > > > > Timing-wise, the GCC developer community is focusing on gcc 10 > > bugfixing right now (aka "stage 4" of the release cycle). So this > > patch won't be suitable to commit to master until stage 1 of the > > release cycle for gcc 11 (in April, hopefully). > > Ah I should've looked a bit harder for timelines before asking https://gcc.gnu.org/develop.html. Appreciate the response here! > > But yes, it's probably a good idea to get feedback on the patch given > > the breadth of platforms we support. > > > > The patch will need an update to the docs; search for "Tools/packages > > necessary for building GCC" in gcc/doc/install.texi, which currently > > has some paragraphs labelled: > >@item ISO C++98 compiler > > that will need changing. > > > > I think Richi mentioned that the minimum gcc version should be 4.8.2 > > as he recalled issues with .1, so maybe the error message and docs > > should reflect that? > > > > https://gcc.gnu.org/ml/gcc/2019-10/msg00180.html > > Segher here suggests 4.8.5 instead of 4.8.2: https://gcc.gnu.org/ml/gcc/2019-11/msg00192.html Looking at release dates 4.8.5 was in June 2015 while 4.8.2 in October 2013 which is a pretty big gap. I'd for moving the needle as far as we reasonably can since this is a leap anyways. @Segher do you have a reason in mind for the higher versioning? > > This may be opening a can of worms that should wait until we're done > > with the GCC 10 release, but there's probably an eventual wider > > discussion about what parts of C++11 we should use; pragmatically > > we're also limited by gengtype, the tool that scrapes the source code > > looking for garbage-collector markup, as that imposes a subset of C++ on us. > > > > I'd love to be able to rely on move semantics and thus use e.g. > > std::unique_ptr to capture more of our memory-management in the type > > system (we currently have a limited C++98-compatible implementation in > > the tree in the form of gnu::unique_ptr). > > > > How much of the stdlib do we see ourselves using? I think we've > > avoided std::string and the <<-style stream APIs; is there a case for > > using some of the other data structures? > > > > For reference, see > > > > https://gcc.gnu.org/codingconventions.html#Cxx_Conventions > > > > Hope this is constructive. > > Dave > Dave, > > I recall originally bringing up the move. From memory I recall that these were > the features we wanted or the people in the discussion wanted from C++11: > 1. Better Rounding and Stricter Integer and other number type rules 2. > Template > Aliasing 3. Auto and for each style loops 4. Move and R Value Semantics > Agreed on these features. I really like having access to 'for (const auto & foo : bar)' > There was a little discussion about lambas and anonymous functions but I don't > recall that being clear in terms of one of the above areas for sure. > > Maybe that helps, > Nick
RE: [EXTERNAL] Re: GCC selftest improvements
> On 2/12/20 8:53 PM, David Malcolm wrote: > The patch will need an update to the docs; search for > "Tools/packages necessary for building GCC" in > gcc/doc/install.texi, which currently has some paragraphs labelled: >@item ISO C++98 compiler > that will need changing. Added this change in the attached patch. I looked through the rest of the docs folder for "C++98" mentions and found only those pertaining to using it in GCC rather than anything related to bootstrapping. Also did a grep for "C++98" in gcc as a whole and didn’t see any other places regarding bootstrapping. I modified how we check for C++11 to use "__cplusplus" since type_traits.h can be present even without full C++11 support. Testing on x86_64 on Ubuntu 18.04 with gcc 7.4.0 passes. Forcing bootstrap to use gcc 4.7 results in the following configure time error: **checking that the compiler supports c++11... configure: error: Building GCC requires a compiler that supports c++11, such as GCC 4.8.5 or newer** I believe RedHat has access to bootstrapping on a variety of platforms/native targets so if I can get someone to validate on those that would be great! That will also give a preview of what targets may have issues before this goes live. > From: gcc-ow...@gcc.gnu.org On Behalf Of Mike > Stump > Sent: Friday, February 14, 2020 12:50 PM > I think we should pick not on the basis something unspecific, rather, I'd list > the 3 5 or 9 systems we check against, and then pick the minimum of them. > Above I picked 7.4 because it's on 18.04. I think this makes for a better > policy as it's predicable, stable, and in 100 years, I don't think I see the > need > to change the policy. I agree with Mike on having a policy in place to guide future efforts in this area. I'm not certain what type of upgrade cadence is needed (check versioning every major Release? Every 2? Note: this doesn't have to be part of the policy) but something consistent means (echoing Mike) there's a default mechanism and a "schedule" of when things are likely to come down the pipeline. Also Segher earlier in the thread linked to a great list compiled by Arnd Bergmann that shows Linux recommendations for GCC versioning which looks like a reasonable set of systems to check against. Here's the link again for ease of finding: https://lore.kernel.org/lkml/CAK8P3a3JfUjm88CLqkvAmCoEA1FsmQ33sfHGK4=y5iuhwxe...@mail.gmail.com/ Changelog entry for this patch: ChangeLog: 2020-02-25 Di Mo * configure.ac: Change bootstrap to test for and require C++11 support * configure: regenerate * gcc/doc/install.texi: Change bootstrapping requirement to C++11 Modi c++11.patch Description: c++11.patch
RE: [EXTERNAL] Re: GCC selftest improvements
> From: David Malcolm > > Thanks Modi. > > Before looking at the updated patch in detail, we ought to also address the > legal prerequisites for contributing. > > Does your employer have legal paperwork in place with the FSF for such > contributions? See: > > https://gcc.gnu.org/contribute.html#legal > > I'm not sure what the threshold is for a contribution to be regarded as > "significant", but it seems that we ought to be fastidious here, given > historical > attitudes between Microsoft and the FLOSS community. > > (I'm not speaking on behalf of anyone other than myself here, as a GCC > maintainer, and I don't mean for this to come across as personal) > > Thanks > Dave Guidance from my side is to get an individual's license to proceed. Can you send me over the forms to get that done? Modi
FYI: New Clang flag "-fnew-infallible" to mark C++ new as "throw()" and "returns_nonnull"
Hi all, I recently committed support for the "-fnew-infallible" flag in Clang (https://reviews.llvm.org/D105225) to improve non-exceptional performance for code that contains exceptions. Having "new" terminate immediately on failure stops upward exception propagation and leads to significantly less landing pads generated. Posting here for visibility and to reduce the chance that a similar feature may manifest under a different flag for GCC. Thanks, Modi
Re: New Clang flag "-fnew-infallible" to mark C++ new as "throw()" and "returns_nonnull"
On 8/3/21, 1:51 PM, "Jonathan Wakely" wrote: > >Could you explain this sentence in the commit message: >"Note that the definition of global new is user-replaceable so users >should ensure that the one used follows these semantics." AFAICT based on the C++ standard, the user can replace the definition of operator new with anything they want. In the current implementation we're using an un-enforced "throw()" annotation so it's up to the implementation of ::new (in libstdc++/jemalloc etc.) to comply properly or risk UB. Marking ::new as noexcept is more rigid of an enforcement but I believe it's implementation defined as to how exception specifications are merged and because noexcept is not part of the mangled name link-time replacement would encounter the same issue. >What happens if operator new does throw? Is that just treated like any >other noexcept function that throws, i.e. std::terminate()? Or is it >undefined behaviour? It gets treated like the older "throw()" annotation where it's UB, there's no enforcement. >And what if you use ::new(std::nothrow) and that fails, returning >null. Is that undefined? This change doesn't affect ::new(std::nothrow) ATM. Nathan Sidwell suggested that we may want to change semantics for non-throwing as well to be truly "infallible" but we don't have a use-case for this scenario as of yet. >It seems to me that the former case (a potentially-throwing allocation >function) could be turned into a std::terminate call fairly easily >without losing the benefits of this option (you still know that no >call to operator new will propagate exceptions). Could you elaborate? That would be great if there's a way to do this without requiring enforcement on the allocator definition. >But for the latter case the program *must* replace operator new to ensure > that the >nothrow form never returns null, otherwise you violate the promise >that the returns_nonnull attribute makes, and have undefined >behaivour. Is that right? Yes good insight. That's another tricky aspect to implementing this for non-throwing new.
Re: New Clang flag "-fnew-infallible" to mark C++ new as "throw()" and "returns_nonnull"
On 8/3/21, 4:57 PM, "Jonathan Wakely" wrote: > On Tue, 3 Aug 2021, 23:10 Modi Mo, wrote: > > > > On 8/3/21, 1:51 PM, "Jonathan Wakely" wrote: > > > > > >Could you explain this sentence in the commit message: > > >"Note that the definition of global new is user-replaceable so users > > >should ensure that the one used follows these semantics." > > > > AFAICT based on the C++ standard, the user can replace the definition of > > operator new with anything they want. > > > No, they have to meet certain requirements. > > If any operator new is potentially throwing (i.e. not declared > noexcept) and it returns null, you get UB. A potentially throwing > operator new *must* return non-null, or throw something they can be > caught by catch(bad_alloc const&), or not return (e.g. terminate). > If any operator new is noexcept, then it reports failure by returning > null instead of throwing. Ah right, I found this out when implementing which is the main motivation behind using "throw()" as noexcept will categorize all ::new as ::new(std::nothrow) which isn't what we're after in this implementation. > So if the user replaces the global operator new(size_t), then their > replacement must never return null, because it's declared without > noexcept. > > > > > > In the current implementation we're using an un-enforced "throw()" > > annotation so it's up to the implementation of ::new (in libstdc++/jemalloc > > etc.) to comply properly or risk UB. > > That's what I was afraid of. The implementation in libstdc++ cannot > know the user passed -fnew-infallible so has no way of knowing whether > it's allowed to throw, or if it has to terminate on failure. So it > will throw in failure, which will then be undefined. > > So it seems the user must either provide a replacement operator new > which terminates, or simply ensure that their program never exceeds > the system's available memory. In the latter case, the > -fnew-infallible option is basically a promise to the compiler that > the system has "infinite" memory (or enough for the program's needs, > if not actually infinite). Yeah, there's a disconnect between declaration (what -fnew-infallible does) and definition (libstdc++). I don't know of a way to enforce this automatically without creating a shim like you suggested. > > Marking ::new as noexcept is more rigid of an enforcement but I believe > > it's implementation defined as to how exception specifications are merged > > I think it's undefined if two declarations of the same function have > different exception specifications. I might be wrong. The main reason I didn't do this is as you identified above, marking it noexcept from a standard viewpoint changes ::new to : :new(std::nothrow). > Making it noexcept would currently mean that the compiler must assume > it can return null, and so adds extra checks to a new-expression so > that if operator new returns null no object is constructed. But if > it's noexcept *and* return_nonnull I guess that check can be elided. I think doing this could work though I feel like there'll be some rough edges that have to be filed down. > > >What happens if operator new does throw? Is that just treated like any > > >other noexcept function that throws, i.e. std::terminate()? Or is it > > >undefined behaviour? > > > > It gets treated like the older "throw()" annotation where it's UB, there's > > no enforcement. > > > It's not UB for a throw() function to throw. In C++03 it would call > std::unexpected() which by default calls std::terminate(). So throw() > is effectively the same as noexcept. What's getting altered ATM is the implicit declaration of "new" that doesn't actually require the header to be copied in: These implicit declarations introduce only the function names operator new, operator new[], opera- tor delete, and operator delete[]. [Note: The implicit declarations do not introduce the names std, std::size_t, std::align_val_t, or any other names that the library uses to declare these names. Thus, a new-expression, delete-expression, or function call that refers to one of these functions without importing or including the header (17.6.1) is well-formed. The definition though doesn't have to abide by this and if it doesn't then UB gets triggered. > > >And what if you use ::new(std::nothrow) and that fails, returning > > >null. Is that undefined? > > > > This change doesn't affect ::new(std::nothrow) ATM. Nathan Sidwell > > suggested that we may want to change semantics for non-throwing as well to > > be truly "infallible" but we don't have a use-case for this scenario as of > > yet. > > Ah, I see. So it only affects operator new(size_t)? > And operator new(size_t, align_val_t) too? > And the corresponding operator new[] forms? Yep. > > >It seems to me that the former case (a potentially-throwing allocation > > >function) could be turned into a std::terminate call fairly easily > > >without losing t