[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 Dimitry Andric changed: What|Removed |Added CC||cperc...@freebsd.org --- Comment #16 from Dimitry Andric --- At some point during libc++ 18 development, the old assertions-on/off mechanism (using _LIBCPP_ENABLE_ASSERTIONS) was replaced with various "hardening modes". (See https://discourse.llvm.org/t/rfc-hardening-in-libc/73925 and various other places.) With upstream's libc++ builds, the hardening mode with which libc++.so itself is built is chosen at configuration time, via the CMake LIBCXX_HARDENING_MODE variable. It can be set to "none", "fast", "extensive" and "debug". In the CMakeLists.txt there is the following comment: "Specify the default hardening mode to use. This mode will be used inside the compiled library and will be the default when compiling user code. Note that users can override this setting in their own code. This does not affect the ABI. Supported values are ${LIBCXX_SUPPORTED_HARDENING_MODES}.") In any case, libc++ never used NDEBUG for these internal checks. In -CURRENT, the precompiled shared and static libraries installed in the base system use the mode selected in lib/libc++/__config_site, which is generated by a CMake build with hardening mode set to "extensive" (aka 16). I think it may make sense to tune down the level of the shared and static libraries to "fast" for release branches, or maybe even stable branches, as the "extensive" setting is slightly more expensive. For a particular port that wants to change libc++'s defaults, they should use e.g.: -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE or one of the other non-default settings. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #15 from Mark Millard --- (In reply to huanghwh from comment #14) FYI for folks reading the diff that might want to know the symbolic names for the 2 vs. 16: /usr/include/c++/v1/__config:# define _LIBCPP_HARDENING_MODE_NONE (1 << 1) /usr/include/c++/v1/__config:# define _LIBCPP_HARDENING_MODE_FAST (1 << 2) /usr/include/c++/v1/__config:# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered. /usr/include/c++/v1/__config:# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3) In symbolic terms: So the diff changes: _LIBCPP_HARDENING_MODE_EXTENSIVE into:_LIBCPP_HARDENING_MODE_NONE Notes: That change is not a good match to unoptimized/debug builds. No single value is generally appropriate. May be something like the default values for _LIBCPP_HARDENING_MODE (for libc++ vintages based on such) being branch based: main (a.k.a. CURRENT) : _LIBCPP_HARDENING_MODE_EXTENSIVE stable/* , releng/*.* : _LIBCPP_HARDENING_MODE_NONE If some other value is desired for a context: Be explicit, causing (for some ?): -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_? -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 huang...@gmail.com changed: What|Removed |Added CC||huang...@gmail.com --- Comment #14 from huang...@gmail.com --- Created attachment 252237 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=252237&action=edit __config_site.diff -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #13 from Paul Floyd --- (In reply to Mark Millard from comment #9) (In reply to Mark Millard from comment #9) The original comment said > It should be possible to get an address of the end of the std::vector object, > even though it doesn't point to an allocated byte. This is precisely the purpose of std::end() (or std::vector::end(), std::end() has the advantage that it will also work with raw arrays). > I kept to a fairly minimal > style change compared to &buf[cb] and what it means in C and > some parts of C++ for my test example, using notation showing > specific distinctions that other C++ notations could hide and > so be less clear. As I see it you were using idiomatic C to show how to do the wrong thing rather than using idiomatic C++ to do the right thing. It looks like Yuri is getting things sorted out. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #12 from Yuri Victorovich --- (In reply to Yuri Victorovich from comment #11) And the port will be fixed soon. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #11 from Yuri Victorovich --- (In reply to Paul Floyd from comment #10) Asserts are already supposed to be turned off. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #10 from Paul Floyd --- (In reply to Yuri Victorovich from comment #8) I say that you should fix the UB and then optionally turn off asserts. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #9 from Mark Millard --- (In reply to Paul Floyd from comment #7) Yuri had specified that the code was analogous to upstream for devel/hpx, if I understood right. I kept to a fairly minimal style change compared to &buf[cb] and what it means in C and some parts of C++ for my test example, using notation showing specific distinctions that other C++ notations could hide and so be less clear. I was making no claim that such was the best way to rewrite the related devel/hpx source: a limited purpose example. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #8 from Yuri Victorovich --- (In reply to Paul Floyd from comment #7) That's not the point. The point is that enabling asserts in the optimized production code reduces its performance, regardless whether the code is correct or incorrect. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 Paul Floyd changed: What|Removed |Added CC||pjfl...@wanadoo.fr --- Comment #7 from Paul Floyd --- (In reply to Mark Millard from comment #1) Why not write it in clean C++ style rather than taking pointers in crappy UB C style? std::copy( std::begin(buf), std::end(buf), std::back_inserter(r) ); That way you don’t need to cross your fingers and hope that the compiler does what you imagined it should do. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #6 from Mark Millard --- (In reply to Mark Millard from comment #5) Testing -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE for the code having: std::copy( &buf[0], &buf[cb], // !!! ASSERTs HERE !!! //&buf[0] + cb, std::back_inserter(r) ); # c++ -g -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE get_executable_filename.cpp # gdb a.out . . Reading symbols from a.out... (gdb) run Starting program: /usr/home/root/c_tests/a.out /usr/home/root/c_tests/a.out [Inferior 1 (process 66950) exited normally] In a more general context you might need both -DNDEBUG for the non-libc++ code and also the -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE for the libc++ code that is involved for one compile command. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #5 from Mark Millard --- (In reply to Yuri Victorovich from comment #4) FYI: for NDEBUG vs. _LIBCPP_HARDENING_MODE # grep -r "NDEBUG" /usr/include/c++/v1/ | more /usr/include/c++/v1/module.modulemap: // 's use of NDEBUG requires textual inclusion. Nothing in the standards say that the C++ standard library has to ever use assert from . NDEBUG is only defined relative to and its assert use, not for any other context. _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS does not trace back to a use of assert in the libc++ code. # grep -r "cassert" /usr/include/c++/v1/ | more /usr/include/c++/v1/cassert:cassert synopsis /usr/include/c++/v1/__std_clang_module:#include /usr/include/c++/v1/module.modulemap:module std_cassert [system] { /usr/include/c++/v1/module.modulemap: // 's use of NDEBUG requires textual inclusion. /usr/include/c++/v1/module.modulemap: textual header "cassert" libc++ does not use or its assert(. . .), which is completely standard compliant. There is a separate libc++ specific mechanism that does not involve assert or NDEBUG : alternate values for _LIBCPP_HARDENING_MODE /usr/include/c++/v1/__config indicates: // The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values: // // - `_LIBCPP_HARDENING_MODE_NONE`; // - `_LIBCPP_HARDENING_MODE_FAST`; // - `_LIBCPP_HARDENING_MODE_EXTENSIVE`; // - `_LIBCPP_HARDENING_MODE_DEBUG`. // // These values have the following effects: // // - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks; // // - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks // that can be done with relatively little runtime overhead in constant time; // // - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of // the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors // but are not necessarily security-critical; // // - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive // mode and enables all checks available in the library, including internal assertions. Checks that are part of the // debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #4 from Yuri Victorovich --- (In reply to Mark Millard from comment #3) &v[v.size()] should take the vector's base address, add the size to it, and return the result. This is technically an incorrect code, it would cause an assert, it it should produce the correct expected pointer. Standards aside, in the absence of asserts there should be nothing in the compiled program that is in the way of returning the correct pointer in this specific situation. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #3 from Mark Millard --- cppreference.com reports the following for C only: 3) special case: & and * cancel each other, neither one is evaluated 4) special case: & and the * that is implied in [] cancel each other, only the addition implied in [] is evaluated. For C++ it reports: Note that, unlike C99 and later C versions, there's no special case for the unary operator& applied to the result of the unary operator*. But I've not tried to see what any fairly modern C++ standard says about such and cppreference.com is not explicit about the & and [] combination in contexts that could possibly use &*(a+i) as a valid translation. If cppreference.com is correct, modern C++ may well require avoiding the &a[i] notation for the non-dereferenceable case: only use such for dereferenceable accesses, even for for likes of std::contiguous_iterator contexts. Again, I'm not sure because I've not analyzed any relevant version of the standard for the issue. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 --- Comment #2 from Yuri Victorovich --- "&buf[0] + cb" is certainly correct, but the problem is that the "gray area" case "&buf[cb]" should also work in the optimized code. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 Mark Millard changed: What|Removed |Added CC||marklmi26-f...@yahoo.com --- Comment #1 from Mark Millard --- I tried the code that is based on: std::copy( &buf[0], &buf[cb], // !!! ASSERTs HERE !!! std::back_inserter(r) ); via: # c++ -g get_executable_filename.cpp # gdb a.out . . Reading symbols from a.out... (gdb) run Starting program: /usr/home/root/c_tests/a.out Program received signal SIGILL, Illegal instruction. Privileged opcode. 0x00203faa in std::__1::vector >::operator[][abi:se180100](unsigned long) (this=0x7fffe940, __n=29) at /usr/include/c++/v1/vector:1393 1393 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds"); Then I tried that sequence based on: std::copy( &buf[0], //&buf[cb], // !!! ASSERTs HERE !!! &buf[0] + cb, std::back_inserter(r) ); # c++ -g get_executable_filename.cpp # gdb a.out . . Reading symbols from a.out... (gdb) run Starting program: /usr/home/root/c_tests/a.out /usr/home/root/c_tests/a.out [Inferior 1 (process 66199) exited normally] I'm not so sure that C++ defines &buf[cb] as equivalent to &buf[0] + cb for std::contiguous_iterator contexts relative to all issues. cppreference.com reports for std::contiguous_iterator : QUOTE Semantic requirements Let a and b be dereferenceable iterators and c be a non-dereferenceable iterator of type I such that b is reachable from a and c is reachable from b. The type I models contiguous_iterator only if all the concepts it subsumes are modeled and: std::to_address(a) == std::addressof(*a), std::to_address(b) == std::to_address(a) + std::iter_difference_t(b - a), and std::to_address(c) == std::to_address(a) + std::iter_difference_t(c - a). END QUOTE &buf[0] + cb notation does avoid any suggestion of dereferencing buf[cb] at any stage. -- You are receiving this mail because: You are the assignee for the bug.
[Bug 279443] LIBCPP assertions are enabled in optimized builds when -DNDEBUG is given to clang
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=279443 Yuri Victorovich changed: What|Removed |Added Assignee|b...@freebsd.org|toolchain@FreeBSD.org CC||d...@freebsd.org -- You are receiving this mail because: You are the assignee for the bug.