[Bug libstdc++/94973] New: compile error when trying to use pointer-to-member function as invokable projection to ranges::find()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94973 Bug ID: 94973 Summary: compile error when trying to use pointer-to-member function as invokable projection to ranges::find() Product: gcc Version: 9.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- `range-v3` has the concept of "invocable projections", i.e. simple transformations that can be applied as predicates to its algorithms. Pointer-to-member-functions should be included and mean 'get the result of calling that on the current element'. However, it seems that invoking a pointer-to-member-function in g++ (but NOT clang++) causes the build to fail. Given the code, compiled with `g++ -std=c++17` against `ericniebler/range-v3` release `range-v3-0.10.0`, using `g++.exe (Rev2, Built by MSYS2 project) 9.3.0`: ```cpp #include #include auto main() -> int { struct S { int i{}; auto get_i() const { return i; } }; auto const ss = std::vector(10); ranges::find(ss, 1, &S::get_i); return 0; } ``` I get a spew of errors: ```none test.cpp: In function 'int main()': test.cpp:14:31: error: no match for call to '(const ranges::find_fn) (const std::vector&, int, int (main()::S::*)() const)' 14 | ranges::find(ss, 1, &S::get_i); | ^ In file included from FOO/include/range-v3/range/v3/range_fwd.hpp:24, from FOO/include/range-v3/range/v3/algorithm/find.hpp:18, from test.cpp:1: FOO/include/range-v3/range/v3/detail/config.hpp:618:27: note: candidate: 'template constexpr concepts::return_t && sentinel_for) && indirect_relation::apply, const V*>) && concepts::detail::CPP_true(concepts::detail::Nil{})), void>::type> ranges::find_fn::operator()(I, S, const V&, P) const' 618 | #define RANGES_FUNC(NAME) operator() RANGES_FUNC_CONST_ /**/ | ^~~~ FOO/include/range-v3/range/v3/algorithm/find.hpp:47:24: note: in expansion of macro 'RANGES_FUNC' 47 | constexpr auto RANGES_FUNC(find)(I first, S last, V const & val, P proj = P{}) |^~~ FOO/include/range-v3/range/v3/detail/config.hpp:618:27: note: template argument deduction/substitution failed: 618 | #define RANGES_FUNC(NAME) operator() RANGES_FUNC_CONST_ /**/ | ^~~~ FOO/include/range-v3/range/v3/algorithm/find.hpp:47:24: note: in expansion of macro 'RANGES_FUNC' 47 | constexpr auto RANGES_FUNC(find)(I first, S last, V const & val, P proj = P{}) |^~~ In file included from FOO/include/range-v3/range/v3/iterator/access.hpp:22, from FOO/include/range-v3/range/v3/iterator/concepts.hpp:30, from FOO/include/range-v3/range/v3/algorithm/find.hpp:22, from test.cpp:1: FOO/include/range-v3/std/detail/associated_types.hpp: In substitution of 'template using enable_if_t = typename ranges::detail::enable_if::apply [with bool B = ranges::readable >; T = std::vector]': FOO/include/range-v3/range/v3/iterator/concepts.hpp:561:19: required by substitution of 'template using apply = ranges::detail::enable_if_t<(bool)(readable), I> [with I = std::vector]' FOO/include/range-v3/range/v3/algorithm/find.hpp:48:15: required by substitution of 'template constexpr concepts::return_t && sentinel_for) && indirect_relation::apply, const V*>) && concepts::detail::CPP_true(concepts::detail::Nil{})), void>::type> ranges::find_fn::operator()(I, S, const V&, P) const [with I = std::vector; S = int; V = int (main()::S::*)() const; P = ranges::identity]' test.cpp:14:31: required from here FOO/include/range-v3/std/detail/associated_types.hpp:73:15: error: no class template named 'apply' in 'struct ranges::detail::enable_if' 73 | using enable_if_t = typename enable_if::template apply; | ^~~ In file included from FOO/include/range-v3/range/v3/range_fwd.hpp:24, from FOO/include/range-v3/range/v3/algorithm/find.hpp:18, from test.cpp:1: FOO/include/range-v3/range/v3/detail/config.hpp:618:27: note: candidate: 'template constexpr concepts::return_t >::apply())), ranges::dangling>, typename std::enable_if<((input_range && indirect_relation::apply()))>, const V*>) && concepts::detail::CPP_true(concepts::detail::Nil{})), void>::type> ranges::find_fn::operator()(Rng&&, const V&, P) const' 618 | #de
[Bug libstdc++/94973] compile error when trying to use pointer-to-member function as invokable projection to ranges::find()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94973 --- Comment #3 from DB --- > Please read https://gcc.gnu.org/bugs and provide the missing information. Fair point. Let me know if I missed anything still. the exact version of GCC; g++.exe (Rev2, Built by MSYS2 project) 9.3.0 the system type; Windows, g++ provided by MSYS2/MinGW64 projects the options given when GCC was configured/built; I didn't build it. Is there a switch that can get this for you? the complete command line that triggers the bug; g++ -I /home/ME/.local/include/range-v3 -std=c++17 -Wall -Wextra -Wpedantic test.cpp the compiler output (error messages, warnings, etc.); already included. the preprocessed file (*.i*) that triggers the bug, generated by adding -save-temps to the complete compilation command I will attach this next. > Why is this marked as a libstdc++ bug? I chose libstdc++ because I figured it was more likely that some corner case of std::invoke() was ultimately being hit, rather than the core compiler being at fault. I guess not. > I can't reproduce this using range-v3 0.10.0 and GCC 9.3.0 on GNU/Linux, the > example compiles fine. Curioser and curioser. It's fine on clang++ on Windows too. Seems a corner case.
[Bug libstdc++/94973] compile error when trying to use pointer-to-member function as invokable projection to ranges::find()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94973 --- Comment #4 from DB --- Created attachment 48470 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48470&action=edit test.ii from --save-temps
[Bug c++/94973] compile error when trying to use pointer-to-member function as invokable projection to ranges::find()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94973 --- Comment #8 from DB --- > I can reproduce it using x86_64-w64-mingw32-g++ 9.2.1 Thanks again for testing! > I'm not yet convinced this isn't a ranges-v3 bug. I will of course defer to your expertise! It could well be caused by something buried somewhere in range-v3's many layers of supporting code. If it can't be a g++ bug, of course just say the word, and I will just forward this all to them. > As it says on that page, "the first three of which can be obtained from the > output of gcc -v" D'oh. Here we are: $ g++ -v Using built-in specs. COLLECT_GCC=C:\msys64\mingw64\bin\g++.exe COLLECT_LTO_WRAPPER=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.3.0/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../gcc-9.3.0/configure --prefix=/mingw64 --with-local-prefix=/mingw64/local --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --with-native-system-header-dir=/mingw64/x86_64-w64-mingw32/include --libexecdir=/mingw64/lib --enable-bootstrap --with-arch=x86-64 --with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++ --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts=yes --enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --disable-isl-version-check --enable-lto --enable-libgomp --disable-multilib --enable-checking=release --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --enable-plugin --with-libiconv --with-system-zlib --with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64 --with-isl=/mingw64 --with-pkgversion='Rev2, Built by MSYS2 project' --with-bugurl=https://sourceforge.net/projects/msys2 --with-gnu-as --with-gnu-ld Thread model: posix gcc version 9.3.0 (Rev2, Built by MSYS2 project)
[Bug c++/94973] compile error when trying to use pointer-to-member function as invokable projection to ranges::find()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94973 --- Comment #15 from DB --- Aha, many thanks for the findings. IMO the MS extensions should really be off by default, esp if compiling in a Standard mode, until the user actually says they want them... right? They seem liable to lead to issues. And might explain lots of other weird warning spam I got earlier... (All I do special is pass -mwindows, just to avoid a spurious terminal)
[Bug c++/94973] compile error when trying to use pointer-to-member function as invokable projection to ranges::find()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94973 --- Comment #16 from DB --- > -fno-ms-extensions will allow you to compile it, as long as you aren't > relying on any of the other MSVC compatibility quirks. That indeed fixes the problem, as well as squashing lots of other spurious warnings (some of which default to errors!) from libsigc++ in the same project that were Windows-specific. Thanks!
[Bug c++/93050] New: throw within constructor initialisation list causes invalid free in destructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93050 Bug ID: 93050 Summary: throw within constructor initialisation list causes invalid free in destructor Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- I've come across this error at least twice when trying to throw from constructor initialisation lists, so I don't *think* I'm uniquely at fault here... All I want to do is move/copy an argument into a member if suitable, and throw if not, while not having to use the constructor body, instead the ctor init-list The below code, compiled with... * g++ --version: `g++.exe (Rev2, Built by MSYS2 project) 9.2.0` * compiler args: `g++ -std=c++17 -Wall -Wextra -Wpedantic test.cpp` ...correctly throws when Test() is called with an empty string, but with a non-empty string is crashes in free() via ~Test(). source: ```cpp #include #include struct Test final { std::string m_string; Test(std::string string) : m_string{ !string.empty() ? std::move(string) : throw std::invalid_argument{"string cannot be empty"} } {} }; auto main() -> int { auto test = Test{"2"}; return 0; } ``` gdb log, run on ``` Reading symbols from ./a.exe...done. (gdb) run Starting program: /tmp/Atm/build/a.exe [New Thread 3880.0x3c38] [New Thread 3880.0x2b68] [New Thread 3880.0x5624] [New Thread 3880.0x4a14] warning: Critical error detected c374 Thread 1 received signal SIGTRAP, Trace/breakpoint trap. 0x7ffdca4391f3 in ntdll!RtlIsNonEmptyDirectoryReparsePointAllowed () from /c/WINDOWS/SYSTEM32/ntdll.dll (gdb) bt #0 0x7ffdca4391f3 in ntdll!RtlIsNonEmptyDirectoryReparsePointAllowed () from /c/WINDOWS/SYSTEM32/ntdll.dll #1 0x7ffdca441622 in ntdll!RtlpNtMakeTemporaryKey () from /c/WINDOWS/SYSTEM32/ntdll.dll #2 0x7ffdca44192a in ntdll!RtlpNtMakeTemporaryKey () from /c/WINDOWS/SYSTEM32/ntdll.dll #3 0x7ffdca44a8e9 in ntdll!RtlpNtMakeTemporaryKey () from /c/WINDOWS/SYSTEM32/ntdll.dll #4 0x7ffdca38088d in ntdll!RtlGetCurrentServiceSessionId () from /c/WINDOWS/SYSTEM32/ntdll.dll #5 0x7ffdca37fc11 in ntdll!RtlFreeHeap () from /c/WINDOWS/SYSTEM32/ntdll.dll #6 0x7ffdc8fd9cfc in msvcrt!free () from /c/WINDOWS/System32/msvcrt.dll #7 0x00402ef8 in Test::~Test() () #8 0x004015d2 in main () (gdb) ``` Copying instead of `std::move()`ing the `string` doesn't seem to change anything Moving the check/throw into the constructor body works but shouldn't be needed.
[Bug c++/93152] New: Order of template args in decl makes std::invocable fail
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93152 Bug ID: 93152 Summary: Order of template args in decl makes std::invocable fail Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- This is as far as I've yet reduced this from my own project, compiling with `g++-10 (Debian 10-20191217-1) 10.0.0 20191217 (experimental) [trunk revision 279456]` From the comments below: // Putting Result as 1st template argument makes derived_from fail, // but putting derived_from 1st lets it compile without problem! // If you [constrain via static_assert] instead, both template arg orders work!! The failure occurs like so; it seems that somehow g++ concludes the wrong base for derived_from, and as mentioned that seems to be caused by template arg order >>> test3.cpp: In function ‘int main()’: test3.cpp:48:33: error: no match for call to ‘(const make_lambda(MemFun) [with Result = void; WeirdSub1 = WeirdSub; Args = {}; MemFun = void (WeirdSub::*)()]::) (WeirdSub, OtherSub)’ 48 | lambda( WeirdSub{}, OtherSub{} ); | ^ test3.cpp:28:9: note: candidate: ‘make_lambda(MemFun) [with Result = void; WeirdSub1 = WeirdSub; Args = {}; MemFun = void (WeirdSub::*)()]:: [with auto:1 = WeirdSub; auto:2 = OtherSub]’ 28 | return [] | ^ test3.cpp:28:9: note: constraints not satisfied In file included from test3.cpp:1: /usr/include/c++/10/concepts: In instantiation of ‘make_lambda(MemFun) [with Result = void; WeirdSub1 = WeirdSub; Args = {}; MemFun = void (WeirdSub::*)()]:: [with auto:1 = WeirdSub; auto:2 = OtherSub]’: test3.cpp:48:33: required from here /usr/include/c++/10/concepts:67:13: required for the satisfaction of ‘derived_from’ /usr/include/c++/10/concepts:67:28: note: ‘OtherSub’ is not a base of ‘WeirdSub’ 67 | concept derived_from = __is_base_of(_Base, _Derived) >>> Additionally, if you make the lambda instead take only derived_from, and dutifully pass only that... then an ICE occurs instead. I'll probably file a 2nd, simpler MCVE for that - unless it turns out to have the same root cause. >>> test3.cpp: In function ‘int main()’: test3.cpp:48:21: internal compiler error: Segmentation fault 48 | lambda( WeirdSub{} );//, OtherSub{} ); | ^ 0xbecf3f crash_signal ../../src/gcc/toplev.c:328 0x7fb9a36f30ff ??? /build/glibc-dEjGnz/glibc-2.29/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0 0x703e96 tsubst(tree_node*, tree_node*, int, tree_node*) ../../src/gcc/cp/pt.c:15083 0x707ac6 tsubst_template_args(tree_node*, tree_node*, int, tree_node*) ../../src/gcc/cp/pt.c:13099 0x625fa5 normalize_concept_check ../../src/gcc/cp/constraint.cc:685 0x625fa5 normalize_atom ../../src/gcc/cp/constraint.cc:719 0x625fa5 normalize_expression ../../src/gcc/cp/constraint.cc:748 0x6263da get_normalized_constraints ../../src/gcc/cp/constraint.cc:760 0x6263da get_normalized_constraints_from_info ../../src/gcc/cp/constraint.cc:778 0x629dfd get_normalized_constraints_from_decl ../../src/gcc/cp/constraint.cc:841 0x62a23a satisfy_declaration_constraints ../../src/gcc/cp/constraint.cc:880 0x62a578 constraint_satisfaction_value ../../src/gcc/cp/constraint.cc:2709 0x62a578 constraints_satisfied_p(tree_node*) ../../src/gcc/cp/constraint.cc:2730 0x5f7f11 add_function_candidate ../../src/gcc/cp/call.c:2280 0x5fa28d add_template_candidate_real ../../src/gcc/cp/call.c:3438 0x5fa7c4 add_template_candidate ../../src/gcc/cp/call.c:3479 0x5fa7c4 add_candidates ../../src/gcc/cp/call.c:5805 0x5ff654 add_candidates ../../src/gcc/cp/call.c:5720 0x5ff654 build_op_call_1 ../../src/gcc/cp/call.c:4768 0x5ff654 build_op_call(tree_node*, vec**, int) ../../src/gcc/cp/call.c:4864 >>> *** ``` #include #include struct WeirdBase {}; struct WeirdSub: WeirdBase { void mem_fun() {} }; struct OtherBase {}; struct OtherSub: OtherBase {}; template using MemFun = Result (Object::*)(Args...); // Putting Result as 1st template argument makes derived_from fail, #if 1 template WeirdSub1, typename... Args> // but putting derived_from 1st lets it compile without problem! #else template WeirdSub1, typename Result, typename... Args> #endif auto make_lambda( MemFun ) { return [] #if 1 (std::derived_from auto&&, std::derived_from auto&&) { // If you do the following instead, both template arg orders work!! #else (std::derived_from auto&& weird, std::derived_from auto&&)
[Bug c++/93152] Order of template arguments in declaration makes std::derived_from fail due to expecting wrong base class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93152 --- Comment #1 from DB --- I believe this is also probably related to the fact that the WeirdSub1 template argument is coming via a pointer-to-member function, although I haven't 100% narrowed that down yet, I don't think. The mentioned ICE can be minimised further, but this again works if the template argument orders are swapped, so I think/hope it might have the same root cause. ```#include struct WeirdBase {}; struct WeirdSub: WeirdBase { void mem_fun() {} }; template using MemFun = Result (Object::*)(Args...); #if 1 // fails template WeirdSub1, #else // works template WeirdSub1, typename Result, #endif typename... Args> auto make_lambda( MemFun ) { return [](std::derived_from auto&&){}; } auto main() -> int { auto const lambda = make_lambda(&WeirdSub::mem_fun); lambda( WeirdSub{} ); return 0; } ```
[Bug c++/93152] Order of template args in decl makes derived_from expect wrong base / causes ICE
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93152 --- Comment #2 from DB --- another reduction: the Args... are not required in the templates (since the member function takes none), and the same failure/success patterns occur either way.
[Bug c++/93050] throw within constructor initialisation list causes invalid free in destructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93050 --- Comment #1 from DB --- This bug does not seem to occur with g++ (Debian 9.2.1-21) 9.2.1 20191130 so either it was fixed between 9.2.0 and 9.2.1, or something peculiar to MSYS2/MinGW64/Windows is causing it.
[Bug c++/93152] Order of template args in decl makes derived_from expect wrong base / causes ICE
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93152 --- Comment #3 from DB --- The pointer-to-member-function and template argument deduction through it is not required; rather, simply the presence of any other template argument in the 1st position is sufficient: ``` #include #include struct WeirdBase {}; struct WeirdSub: WeirdBase {}; struct OtherBase {}; struct OtherSub: OtherBase {}; // Putting Result as 1st template argument makes derived_from fail, #if 1 template WeirdSub1> // but putting derived_from 1st lets it compile without problem! #else template WeirdSub1, typename Result> #endif auto make_lambda() { return [] #if 1 (std::derived_from auto&&, std::derived_from auto&&) { // If you do the following instead, both template arg orders work!! #else (std::derived_from auto&& weird, std::derived_from auto&&) { using WeirdSub2 = std::remove_reference_t< decltype(weird) >; static_assert( std::derived_from ); #endif }; } auto main() -> int { #if 1 auto const lambda = make_lambda(); #else auto const lambda = make_lambda(); #endif lambda( WeirdSub{}, OtherSub{} ); return 0; } ``` >>> test3.cpp: In function ‘int main()’: test3.cpp:44:33: error: no match for call to ‘(const make_lambda() [with Foo = int; WeirdSub1 = WeirdSub]::) (WeirdSub, OtherSub)’ 44 | lambda( WeirdSub{}, OtherSub{} ); | ^ test3.cpp:20:9: note: candidate: ‘make_lambda() [with Foo = int; WeirdSub1 = WeirdSub]:: [with auto:1 = WeirdSub; auto:2 = OtherSub]’ 20 | return [] | ^ test3.cpp:20:9: note: constraints not satisfied In file included from test3.cpp:1: /usr/include/c++/10/concepts: In instantiation of ‘make_lambda() [with Foo = int; WeirdSub1 = WeirdSub]:: [with auto:1 = WeirdSub; auto:2 = OtherSub]’: test3.cpp:44:33: required from here /usr/include/c++/10/concepts:67:13: required for the satisfaction of ‘derived_from’ /usr/include/c++/10/concepts:67:28: note: ‘OtherSub’ is not a base of ‘WeirdSub’ 67 | concept derived_from = __is_base_of(_Base, _Derived) >>>
[Bug c++/93152] Order of template args in decl makes derived_from expect wrong base / causes ICE
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93152 --- Comment #4 from DB --- Simplifying further, by getting rid of the Other structs/arguments, we get: ``` #include #include struct WeirdBase {}; struct WeirdSub: WeirdBase {}; template WeirdSub1> auto make_lambda() { return [](std::derived_from auto&&){}; } auto main() -> int { auto const lambda = make_lambda(); lambda( WeirdSub{} ); return 0; } ``` ...which again gives... >>> test3.cpp: In function ‘int main()’: test3.cpp:18:21: internal compiler error: Segmentation fault 18 | lambda( WeirdSub{} ); | ^ 0xbecf3f crash_signal ../../src/gcc/toplev.c:328 0x7efcb8d0c0ff ??? /build/glibc-dEjGnz/glibc-2.29/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0 0x703e96 tsubst(tree_node*, tree_node*, int, tree_node*) ../../src/gcc/cp/pt.c:15083 0x707ac6 tsubst_template_args(tree_node*, tree_node*, int, tree_node*) ../../src/gcc/cp/pt.c:13099 0x625fa5 normalize_concept_check ../../src/gcc/cp/constraint.cc:685 0x625fa5 normalize_atom ../../src/gcc/cp/constraint.cc:719 0x625fa5 normalize_expression ../../src/gcc/cp/constraint.cc:748 0x6263da get_normalized_constraints ../../src/gcc/cp/constraint.cc:760 0x6263da get_normalized_constraints_from_info ../../src/gcc/cp/constraint.cc:778 0x629dfd get_normalized_constraints_from_decl ../../src/gcc/cp/constraint.cc:841 0x62a23a satisfy_declaration_constraints ../../src/gcc/cp/constraint.cc:880 0x62a578 constraint_satisfaction_value ../../src/gcc/cp/constraint.cc:2709 0x62a578 constraints_satisfied_p(tree_node*) ../../src/gcc/cp/constraint.cc:2730 0x5f7f11 add_function_candidate ../../src/gcc/cp/call.c:2280 0x5fa28d add_template_candidate_real ../../src/gcc/cp/call.c:3438 0x5fa7c4 add_template_candidate ../../src/gcc/cp/call.c:3479 0x5fa7c4 add_candidates ../../src/gcc/cp/call.c:5805 0x5ff654 add_candidates ../../src/gcc/cp/call.c:5720 0x5ff654 build_op_call_1 ../../src/gcc/cp/call.c:4768 0x5ff654 build_op_call(tree_node*, vec**, int) ../../src/gcc/cp/call.c:4864 >>>
[Bug c++/93154] New: can't constrain captured functions to be invocable with lambda arg - unknown "constraints not satisfied"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93154 Bug ID: 93154 Summary: can't constrain captured functions to be invocable with lambda arg - unknown "constraints not satisfied" Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- Surely the below should work? I'm currently trying to go overboard with declaring constraints, and that `requires` clause - while perhaps a bit superfluous - seems totally correct... right? However, it doesn't compile, citing "constraints not satisfied" - and yet notably not bothering to mention WHICH constraint supposedly has the problem! g++-10 (Debian 10-20191217-1) 10.0.0 20191217 (experimental) [trunk revision 279456] ``` #include void f1(int) {} template requires (sizeof...(Fs) > 0) auto make_lambda(Fs... fs) { return [fs...] requires (std::invocable && ...) (Arg a) { (fs(a), ...); }; } auto main() -> int { auto const lambda = make_lambda(&f1); lambda(42); return 0; } ``` ...results in the error: >>> test5.cpp: In function ‘int main()’: test5.cpp:22:11: error: no match for call to ‘(const make_lambda(Fs ...) [with Fs = {void (*)(int)}]::) (int)’ 22 | lambda(42); | ^ test5.cpp:9:9: note: candidate: ‘make_lambda(Fs ...) [with Fs = {void (*)(int)}]:: [with Arg = int]’ 9 | return [fs...] | ^ test5.cpp:9:9: note: constraints not satisfied >>> preprocessed source:
[Bug c++/93154] can't constrain captured functions to be invocable with lambda arg - unknown "constraints not satisfied"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93154 --- Comment #1 from DB --- > preprocessed source: Ah, whoops. It's not interesting anyway, but maybe I just don't remember how to do it right... I just passed `-E`.
[Bug c++/93154] can't constrain captured functions to be invocable with lambda arg - unknown "constraints not satisfied"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93154 --- Comment #2 from DB --- A reduced version, without a variadic pack of functions... ``` #include void f1(int) {} template auto make_lambda(F f) { return [f] requires std::invocable (Arg a) { f(a); }; } auto main() -> int { auto const lambda = make_lambda(&f1); lambda(42); return 0; } ``` ...gives an error that is now specific, but which still seems clearly wrong: >>> test5.cpp: In function ‘int main()’: test5.cpp:19:11: error: no match for call to ‘(const make_lambda(F) [with F = void (*)(int)]::) (int)’ 19 | lambda(42); | ^ test5.cpp:9:9: note: candidate: ‘make_lambda(F) [with F = void (*)(int)]:: [with Arg = int]’ 9 | return [f] requires std::invocable (Arg a) | ^ test5.cpp:9:9: note: constraints not satisfied In file included from test5.cpp:1: /usr/include/c++/10/concepts: In instantiation of ‘make_lambda(F) [with F = void (*)(int)]:: [with Arg = int]’: test5.cpp:19:11: required from here /usr/include/c++/10/concepts:344:13: required for the satisfaction of ‘invocable’ /usr/include/c++/10/concepts:344:25: note: the expression ‘is_invocable_v<_Fn, _Args ...>’ evaluated to ‘false’ 344 | concept invocable = is_invocable_v<_Fn, _Args...>; >>> It looks like the compiler is mixing up the template arguments of the outer function and the inner lambda. In that sense, this might have the same root cause as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93152
[Bug c++/93152] Order of template args in decl makes derived_from expect wrong base / causes ICE
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93152 DB changed: What|Removed |Added See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=93154 --- Comment #5 from DB --- This might have the same root cause as 93154, as in both cases, it looks like the compiler is mixing up the template arguments of the outer function and the inner lambda. Here, we are told that "‘OtherSub’ is not a base of ‘WeirdSub’", despite that we never asked the compiler to make that constraint. and from 93154: ``` #include void f1(int) {} template auto make_lambda(F f) { return [f] requires std::invocable (Arg a) { f(a); }; } auto main() -> int { auto const lambda = make_lambda(&f1); lambda(42); return 0; } ``` ...which somehow ends up with the compiler trying to check whether `int` is `std::invocable`! >>> test5.cpp: In function ‘int main()’: test5.cpp:19:11: error: no match for call to ‘(const make_lambda(F) [with F = void (*)(int)]::) (int)’ 19 | lambda(42); | ^ test5.cpp:9:9: note: candidate: ‘make_lambda(F) [with F = void (*)(int)]:: [with Arg = int]’ 9 | return [f] requires std::invocable (Arg a) | ^ test5.cpp:9:9: note: constraints not satisfied In file included from test5.cpp:1: /usr/include/c++/10/concepts: In instantiation of ‘make_lambda(F) [with F = void (*)(int)]:: [with Arg = int]’: test5.cpp:19:11: required from here /usr/include/c++/10/concepts:344:13: required for the satisfaction of ‘invocable’ /usr/include/c++/10/concepts:344:25: note: the expression ‘is_invocable_v<_Fn, _Args ...>’ evaluated to ‘false’ 344 | concept invocable = is_invocable_v<_Fn, _Args...>; >>>
[Bug c++/93152] derived_from on lambda arg causes ICE / uses wrong base, for some orders of template args on containing function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93152 --- Comment #6 from DB --- still occurs with the new g++-10 (Debian 10-20200104-1) 10.0.0 20200104 (experimental) [trunk revision 279880]
[Bug c++/93154] can't constrain captured functions to be invocable w/ lambda arg - func/lambda template args mixed up?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93154 --- Comment #3 from DB --- still occurs with the new g++-10 (Debian 10-20200104-1) 10.0.0 20200104 (experimental) [trunk revision 279880]
[Bug libstdc++/82212] New: libstdc++ makes (integer|index)_sequence available with -std=c++11, but they're C++14 features
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82212 Bug ID: 82212 Summary: libstdc++ makes (integer|index)_sequence available with -std=c++11, but they're C++14 features Product: gcc Version: unknown URL: https://bugzilla.gnome.org/show_bug.cgi?id=787648 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/utility#L298 std::integer_sequence and std::index_sequence are defined under this condition: #if __cplusplus > 201103L However, these features debuted in the C++14 Standard, not in C++11. The symbols therefore should not be available in -std=c++11 mode. When users, for example, don't realise they only debuted in C++14, use them in -std=c++11 mode, and later compile that code using clang/libc++ in the same mode - they suddenly get compile errors and realise their project unwittingly started requiring C++14. See the URL for a downstream example of this causing a problem.
[Bug c++/80849] New: Brace-init causes multiple runs of virtual base ctor if its signature differs from its derived classes' ctors
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80849 Bug ID: 80849 Summary: Brace-init causes multiple runs of virtual base ctor if its signature differs from its derived classes' ctors Product: gcc Version: 6.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- This appears to be a lingering offshoot of this: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66617 which I was reminded of via: http://stackoverflow.com/questions/38466871/invoking-constructors-during-virtual-inheritance-with-c As the user on SO reported, and verified with GDB, when they are initialised using braces, the intermediate classes' constructors also invoke the virtual base class's constructor, redundantly. They were using 5.4.0 With additional testing, on 6.3.0, I determined that - much like that other old bug - this problem only occurs if the virtual base constructor and the constructors of the intermediate derived classes have different argument signatures. reduced test case: #include // Choose one: //#define DB_INITIALISE(...) (__VA_ARGS__) #define DB_INITIALISE(...) {__VA_ARGS__} struct V { V(int i) { std::cout << 'V' << i << std::endl; } }; struct A: virtual V { A(int i, char c): V DB_INITIALISE(i) { std::cout << 'A' << i << c << std::endl; } }; struct B: virtual V { B(int i, char c): V DB_INITIALISE(i) { std::cout << 'B' << i << c << std::endl; } }; struct C: A, B { C(int i, char c): V DB_INITIALISE(i), A DB_INITIALISE(i, c), B DB_INITIALISE(i, c) { std::cout << 'C' << i << c << std::endl; } }; int main() { C c{42, '?'}; } Expected output, obtained when DB_INITIALISE causes initialisation with (): V42 A42? B42? C42? Actual output, obtained when DB_INITIALISE causes initialisation with {}: V42 V42 A42? V42 B42? C42? Like the other bug, if you alter the constructors of V, A, and B to have the same number/type of arguments, then the problematic extra calls are suppressed.
[Bug c++/80849] Brace-init causes multiple runs of virtual base ctor if its signature differs from its derived classes' ctors
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80849 --- Comment #1 from DB --- (In reply to DB from comment #0) > With additional testing, on 6.3.0, I determined that - much like that other > old bug - this problem only occurs if the virtual base constructor and the > constructors of the intermediate derived classes have different argument > signatures. > [...] > Like the other bug, if you alter the constructors of V, A, and B to have the > same number/type of arguments, then the problematic extra calls are > suppressed. Huh, no. It seems that any number of arguments > 1 causes the problem, even if all the ctor signatures match. Thus I think the pattern is as follows: Only if the ctors are single-argument, will brace-initialisation not result in spurious extra calls to the virtual base constructor.
[Bug c++/55922] brace initializing parent cause bogus virtual base constructor calls
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55922 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #9 from DB --- *** Bug 80849 has been marked as a duplicate of this bug. ***
[Bug c++/80849] Brace-init causes multiple runs of virtual base constructor if any ctor in the hierarchy has >1 argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80849 DB changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |DUPLICATE --- Comment #2 from DB --- Whoops, this already exists as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55922 I'll link back to here with this test case, in case it's useful as another data point. *** This bug has been marked as a duplicate of bug 55922 ***
[Bug c++/80849] Brace-init causes multiple runs of virtual base constructor if any ctor in the hierarchy has >1 argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80849 DB changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|DUPLICATE |--- --- Comment #3 from DB --- Actually, I'm not sure whether this is directly related to that other one, so I'll reopen it and let the devs decide.
[Bug c++/55922] brace initializing parent cause bogus virtual base constructor calls
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55922 --- Comment #10 from DB --- *** Bug 80849 has been marked as a duplicate of this bug. ***
[Bug c++/80849] Brace-init causes multiple runs of virtual base constructor if any ctor in the hierarchy has >1 argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80849 DB changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |DUPLICATE --- Comment #4 from DB --- ...yeah, it's a dupe. By adding debug couts of the this pointer, we see that, like in the older bug, the spurious calls get different/wrong values for it: @0x7ffe9600e660: V42 @0x7ffe9600e660: V42 @0x7ffe9600e660: A42? @0x7ffe9600e668: V42 @0x7ffe9600e668: B42? @0x7ffe9600e660: C42? Specifically, in addition to the first call to V() with the correct address, there is an extra call to V() for every intermediate class (A and B), with the this pointer being the address of THAT subject, not the real address of V (although sometimes they happen to be the same). *** This bug has been marked as a duplicate of bug 55922 ***
[Bug c++/55922] brace initializing parent cause bogus virtual base constructor calls
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55922 --- Comment #11 from DB --- This still occurs in 6.3.0 In the duplicate https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80849 I showed that whether or not this occurs can sometimes (I say because my results don't seem consistent with everyone else's) depend on the number of arguments that are given to (all of) the constructors. I could not replicate the problem with my test case if the constructors were invoked with brace syntax and all had no or 1 argument, but I could when they had 2 or more arguments.
[Bug c++/80851] All versions that support C++11 are confused by combination of inherited constructors with member initializer that captures this
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80851 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #1 from DB --- This is presumably a duplicate of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67054 unless the OP has evidence that capturing *this is relevant to whether or not the problem occurs
[Bug c++/67054] Constructor inheritance with non-default constructible members
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67054 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #3 from DB --- Still occurs in 4.8 to 7.1, according to this duplicate https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80851 Also, could we perhaps get a more useful title for this one? It describes what is involved in the problem, but not what the problem is.
[Bug c++/69953] [5/6 Regression] Using lto causes gtkmm/gparted and gtkmm/inkscape compile to fail
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69953 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #30 from DB --- I get similar issues when compiling glibmm-2.4 from git with g++ 6.3 and LTO, but not without LTO: undefined references to destructors for Glib::RefPtr and Glib::RefPtr. Can this be related, or should I open another bug?
[Bug c++/69953] [5/6 Regression] Using lto causes gtkmm/gparted and gtkmm/inkscape compile to fail
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69953 --- Comment #31 from DB --- Uh, sorry. I mean when compiling my own application against glibmm and gtkmm, using LTO on my app (only).
[Bug c++/68070] Undefined reference to default constructor of member template class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68070 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #1 from DB --- Confirmed and discussed on Stack Overflow: https://stackoverflow.com/questions/44588166/default-value-of-function-parameter-initialized-by-list-initialization
[Bug c++/81140] New: Update docs to reflect P0612R0: clarify meaning of "volatile access" + that it includes any glvalue
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81140 Bug ID: 81140 Summary: Update docs to reflect P0612R0: clarify meaning of "volatile access" + that it includes any glvalue Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- As far as I can tell, according to P0162R0: NB comment CH 2 http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0612r0.html which was adopted earlier this year: https://isocpp.org/blog/2017/03/2017-03-post-kona-mailing-available the established, implementation-defined behaviour of g++ is now Standard behaviour in C++ (if not C). If so, then I guess this section of the documentation needs updated: 7.1 When is a Volatile C++ Object Accessed? https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Volatiles.html I don't know whether this is intended as a DR to be backported to older standards; my Standard-foo is not that strong.
[Bug c/33053] adopt accesses through a volatile-casted pointer as a GNU C extension
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33053 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #2 from DB --- As far as I can tell, according to P0162R0: http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0612r0.html which was adopted this month: https://isocpp.org/blog/2017/03/2017-03-post-kona-mailing-available the current behaviour of g++ is now Standard behaviour in C++ (if not C) If so, then I guess the documentation needs updated: https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Volatiles.html
[Bug c/44943] Need documentation on the intended semantics of "volatile" (in C)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44943 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #2 from DB --- As far as I can tell, according to P0162R0: http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0612r0.html which was adopted this month: https://isocpp.org/blog/2017/03/2017-03-post-kona-mailing-available the current behaviour of g++ is now Standard behaviour in C++ (if not C) If so, then I guess the documentation needs updated: https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Volatiles.html (I don't know yet whether this is intended as a DR to be backported to older standards.)
[Bug c++/81140] Update docs to reflect P0612R0: clarify meaning of "volatile access" + that it includes any glvalue
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81140 --- Comment #1 from DB --- Hm, in fact, I'm not sure the GCC/g++ docs ever address what happens when a declared non-volatile object is accessed through a volatile-qualified reference/pointer, which by my understanding is the crux of the NB issue. So maybe we need a totally new clause in the documentation.
[Bug c++/81140] Update docs to reflect P0612R0: clarify meaning of "volatile access" + that it includes any glvalue
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81140 DB changed: What|Removed |Added See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=33053 --- Comment #2 from DB --- yup: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33053
[Bug c++/53479] Control flow analysis reports warnings in switch over an enum class even if all possible values have their branches
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53479 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #5 from DB --- Sorry to wake the dead, but I'm wondering whether anyone has ever considered adding an opt-out for this diagnostic, or whether there's any other way to issue the following hint to g++: > "Believe me: you will only ever get one of these values, so don't worry about > it" Of course a malicious and/or absent-minded caller could pass in a value that the switch doesn't handle and invoke UB, but what about codebases that don't let in such callers? Should they have to artificially add a default/return/abort/whatever just to keep their build log readable? Interestingly, Clang is silent if you handle all your enum (including non-class) cases (and if you don't, says "control **may** reach end of non-void function [-Wreturn-type]") - which, yeah, seems nice initially - but arguably is a worse default, due to the aforementioned malicious caller and what Jonathan explained. So, I feel GCC could do one better by - quite rightly! - defaulting to warning about such callers - but, crucially, allowing the warning to be disabled by competent ones (willing to take the blame if they pass a duff value later) Anyway, just some idle thoughts and questions. I understand the current reasoning and don't disagree with the default, but think there's a potential gain here too.
[Bug c++/53479] Control flow analysis reports warnings in switch over an enum class even if all possible values have their branches
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53479 --- Comment #7 from DB --- Interesting switch, thanks - doesn't make any difference to warnings at the moment, though. But it hits on what I'm going for: ensuring the compiler that I'll only use named enumerator values. Ideally though, the Standard or compiler would provide a way to specify that as an attribute per enum, so the programmer could mix both schemes. I personally haven't used enums as bitmasks, so my programs have only used discrete enumerators, but the bitfield case seems allowed and common. Still, for cases where I'm not using it, I'd like a way to tell the compiler to trust me!
[Bug c++/53479] Control flow analysis reports warnings in switch over an enum class even if all possible values have their branches
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53479 --- Comment #10 from DB --- (In reply to Manuel López-Ibáñez from comment #8) Thanks for the thoughts! > Those "artificial kludges" not only silence the warning, but also make the > code more readable and help the optimizer. A call to abort() or to any > noreturn function, for example, assert(), will also silence the warning and > it is safer than adding a new option to silence it. Yeah, I've since thought of using abort(), which as you say, silences the warning - and indicates with sufficient strength that this shouldn't happen. assert() isn't much use since the warning would return as soon I compile in release mode... been there, tried that. :) > You can use #pragma GCC diagnostic to disable the warning for this > particular function. If that seems even more of kludge than adding assert(), > you are right. But then, adding a #pragma around your whole codebase (which > is what a new option amounts to) sounds even worse, no?(In reply to DB from > comment #7) Thanks for the hint, and yeah, that would probably produce even messier code ;-) Good to know it exists though. > Perhaps there are uses for an __attribute__((strict_enum)) that can be > attached to particular enums (it would be a more fine-grained version of > -fstrict-enums). However, the effort to implement such a thing and keep it > working seems huge for and the potential fallout for handling it wrong (or > users misusing the attribute). Such an attribute is basically giving even > more license to the compiler to optimize based on undefined behavior, and > users often find UB incomprehensible. Compare that with the effort of > asking users to add __builtin_unreachable() (if they are sure their code > will never be wrong) or add an assert(false) (if they are not completely > sure). Yeah, I think this would be best as a Standard thing, rather than adding another custom attribute to any given compiler. I don't see why it gives "even more licence" to optimise, though, since it'd be conditional per enum, rather than -fstrict-enums, which applies globally... so if anyone inadvertently invokes UB, they've got much more chance of being caught out if they're using the existing global option, than if there was a per-enum attribute for whether or not the value must be a named enumerator. > Perhaps I should add an entry to the FAQ summarizing the above (anyone feel > free to beat me to it...) Couldn't hurt. :) There are some great explanations collected around the net (including some on IRC, but I'm sure you know those ;) but it's hard to find a pre-emptive summary of why this isn't already done. Thanks!
[Bug c++/53479] Control flow analysis reports warnings in switch over an enum class even if all possible values have their branches
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53479 --- Comment #12 from DB --- (In reply to Jonathan Wakely from comment #11) > Given enum E { E1 = 1, E3 = 3 } the values of the type are 0, 1, 2 and 3 and > -fstrict-enums tells the compiler it will never have a value outside that > range. It does **not** tell it that the type will never have the value 0 or > 2. Huh. So allows non-named values and only enforces min/max, so doesn't account for folk doing bitwise ORing? Seems a little like the worst of both worlds. ;) Thanks for the info anyway.
[Bug c++/53479] Control flow analysis reports warnings in switch over an enum class even if all possible values have their branches
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53479 --- Comment #18 from DB --- (In reply to Jonathan Wakely from comment #17) > (In reply to DB from comment #12) > > (In reply to Jonathan Wakely from comment #11) > > > Given enum E { E1 = 1, E3 = 3 } the values of the type are 0, 1, 2 and 3 > > > and > > > -fstrict-enums tells the compiler it will never have a value outside that > > > range. It does **not** tell it that the type will never have the value 0 > > > or > > > 2. > > > > Huh. So allows non-named values and only enforces min/max, so doesn't > > account for folk doing bitwise ORing? > > Huh? I have no idea what you mean by doesn't account for bitwide ORing. The > fact you can have non-named values is essential for bitwide ORing. > > enum Bitmask { bit1 = 1, bit2 = 2, bit4 = 4 }; > Bitmask b = Bitmask(bit1|bit4); > > This creates a value that doesn't correspond to a named enumerator, but > obviously this is valid. (For this type the values of the type are [0,7] > because 7 is the highest value that can be represented in the minimum number > of bits needed to represent all the enumerators). My doubt ultimately arose from a momentary fail at bitwise arithmetic (thinking 1 | 3 == 4, how embarrassing), but I'm glad it elicited this confirmation! Thanks.
[Bug c++/53479] Control flow analysis reports warnings in switch over an enum class even if all possible values have their branches
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53479 --- Comment #19 from DB --- just for anyone finding this later, note this has been raised at the level of the C++ Standard - http://wg21.link/p0375r0 - with the conclusion being: > EWG pointed out that most enumerations are exhaustive, and > we want to be annotating the exception, not the norm. > However, there wasn’t much appetite for a “non-exhaustive” > annotation, either; implementers were of the opinion that > current heuristics for diagnostics for switch statements > on enumerations are sufficient. - via https://botondballo.wordpress.com/2016/07/06/trip-report-c-standards-meeting-in-oulu-june-2016/ I suspect that "most enumerations are exhaustive" is an overgeneralisation that only holds for some people you could ask, but hey.
[Bug c++/66617] New: C++11 {brace} initialisation of virtually inherited derived class = failure to override base virtual function, unless all base ctors have same signature
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66617 Bug ID: 66617 Summary: C++11 {brace} initialisation of virtually inherited derived class = failure to override base virtual function, unless all base ctors have same signature Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- Created attachment 35822 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35822&action=edit Original problem pattern Example steps: Create the following struct hierarchy: A > > C v v B With => struct A containing a pure virtual function => B and C taking public virtual inheritance from A. Now create struct D inheriting from B and C and implementing the pure virtual function. This will not work when D initialises its base classes using the new {brace} initialisation UNLESS, and only if, all base constructors have the same function signature/number of arguments. => Pure virtual function in base generates errors about being unable to allocate abstract classes B and C => Non-pure vfunc generates undefined references to the pure vfunc in B and C. Contructing D using (parentheses) initialisation works fine and leads to the expected result. This is as simple as replacing the brackets in the instantiation, nothing more. Supporting evidence are: => original thread on StackOverflow, by my handle @underscore_d - containing original problem code using {brace} initialisation as attached in "virtual2.cpp" - with working example (same ctor signatures) "virtual3.cpp" > http://stackoverflow.com/questions/30967490/virtual-inheritance-pure-v-function-in-base-fails-with-abstract-pure-error?noredirect=1#comment49967008_30967490 => minimal replication steps outlined by fellow SO user @0x499602D2 Attached also is "virtual4.cpp", which as mentioned, is merely "virtual2.cpp" with the instantiation of the final derived class changed to use (parenthesis) initialisation instead of {braces} Using G++ 4.9.2 from MSYS2 64-bit, latest version I was able to find. Many thanks Daniel B.
[Bug c++/66617] C++11 {brace} initialisation of virtually inherited derived class = failure to override base virtual function, unless all base ctors have same signature
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66617 --- Comment #1 from Daniel Boles --- Forgot to add the minimal replication steps mentioned, prepared by a fellow SO users: http://coliru.stacked-crooked.com/a/c4d031382115b59a thanks
[Bug c++/66617] C++11 {brace} initialisation of virtually inherited derived class = failure to override base virtual function, unless all base ctors have same signature
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66617 Daniel Boles changed: What|Removed |Added Attachment #35822|0 |1 is obsolete|| --- Comment #2 from Daniel Boles --- Comment on attachment 35822 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35822 Original problem pattern I think I got some files mixed up in the first upload. I am about to upload a fixed zip; please refer to that instead. However, the main text is the key thing :-)
[Bug c++/66617] C++11 {brace} initialisation of virtually inherited derived class = failure to override base virtual function, unless all base ctors have same signature
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66617 --- Comment #3 from Daniel Boles --- Created attachment 35824 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35824&action=edit 3 cpp files showing various permutations from totally broken braces, to fully working parentheses Revised version as I had saved a wrong file version in the last upload.
[Bug c++/66617] C++11 {brace} initialisation of virtually inherited derived class = failure to override base virtual function, unless all base ctors have same signature
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66617 --- Comment #4 from DB --- Attaching verbose output and tempfiles as recommended by bug reporting guide. $ gcc -v -save-temps -std=c++11 virtual2.cpp -o virtual2.exe Using built-in specs. COLLECT_GCC=C:\msys64\mingw64\bin\gcc.exe COLLECT_LTO_WRAPPER=C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/4.9.2/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../gcc-4.9.2/configure --prefix=/mingw64 --with-local-prefix=/mingw64/local --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --with-native-system-header-dir=/mingw64/x86_64-w64-mingw32/include --libexecdir=/mingw64/lib --with-gxx-include-dir=/mingw64/include/c++/4.9.2 --enable-bootstrap --with-arch=x86-64 --with-tune=generic --enable-languages=c,lto,c++,objc,obj-c++,fortran,ada --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-cloog-backend=isl --enable-version-specific-runtime-libs --disable-cloog-version-check --disable-isl-version-check --enable-lto --enable-libgomp --disable-multilib --enable-checking=release --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64 --with-isl=/mingw64 --with-cloog=/mingw64 --with-pkgversion='Rev5, Built by MSYS2 project' --with-bugurl=http://sourceforge.net/projects/msys2 --with-gnu-as --with-gnu-ld Thread model: posix gcc version 4.9.2 (Rev5, Built by MSYS2 project) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++11' '-o' 'virtual2.exe' '-mtune=generic' '-march=x86-64' C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/4.9.2/cc1plus.exe -E -quiet -v -D_REENTRANT virtual2.cpp -mtune=generic -march=x86-64 -std=c++11 -fpch-preprocess -o virtual2.ii ignoring nonexistent directory "/mingw64/include" ignoring duplicate directory "C:/msys64/mingw64/x86_64-w64-mingw32/include" #include "..." search starts here: #include <...> search starts here: C:/msys64/mingw64/include/c++/4.9.2 C:/msys64/mingw64/include/c++/4.9.2/x86_64-w64-mingw32 C:/msys64/mingw64/include/c++/4.9.2/backward C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/4.9.2/include C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/4.9.2/../../../../include C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/4.9.2/include-fixed C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/4.9.2/../../../../x86_64-w64-mingw32/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++11' '-o' 'virtual2.exe' '-mtune=generic' '-march=x86-64' C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/4.9.2/cc1plus.exe -fpreprocessed virtual2.ii -quiet -dumpbase virtual2.cpp -mtune=generic -march=x86-64 -auxbase virtual2 -std=c++11 -version -o virtual2.s GNU C++ (Rev5, Built by MSYS2 project) version 4.9.2 (x86_64-w64-mingw32) compiled by GNU C version 4.9.2, GMP version 6.0.0, MPFR version 3.1.2-p11, MPC version 1.0.3 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C++ (Rev5, Built by MSYS2 project) version 4.9.2 (x86_64-w64-mingw32) compiled by GNU C version 4.9.2, GMP version 6.0.0, MPFR version 3.1.2-p11, MPC version 1.0.3 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 31108f4eb997d1c5310b0f90916e0ed9 virtual2.cpp: In constructor 'Right_Bottom::Right_Bottom(int, int, int, int)': virtual2.cpp:51:6: error: cannot allocate an object of abstract type 'Left_Bottom' d{d} ^ virtual2.cpp:20:8: note: because the following virtual functions are pure within 'Left_Bottom': struct Left_Bottom: public virtual Left_Top ^ virtual2.cpp:12:15: note: virtual void Left_Top::pure_virtual() const virtual void pure_virtual() const = 0; ^ virtual2.cpp:51:6: error: cannot allocate an object of abstract type 'Right_Top' d{d} ^ virtual2.cpp:31:8: note: because the following virtual functions are pure within 'Right_Top': struct Right_Top: public virtual Left_Top ^ virtual2.cpp:12:15: note: virtual void Left_Top::pure_virtual() const virtual void pure_virtual() const = 0; ^
[Bug c++/66617] C++11 {brace} initialisation of virtually inherited derived class = failure to override base virtual function, unless all base ctors have same signature
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66617 --- Comment #5 from DB --- Created attachment 35847 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35847&action=edit -save-temps output files plus the triggering cpp file see corresponding -v output added in latest comment. Please advise when this issue has been received and reviewed. Thanks.
[Bug c++/66847] New: Derived class calling protected base ctor using C++11 {brace} init = spurious access denied error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66847 Bug ID: 66847 Summary: Derived class calling protected base ctor using C++11 {brace} init = spurious access denied error Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- Created attachment 35953 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35953&action=edit source file Possible duplicate of 63151. Probably related to the still-outstanding 66617 and references therein. G++ continues to have severe problems implementing the new {brace} initialisation syntax. The two problems I've observed so far seem to be instigated by use of virtual inheritance elsewhere in the class hierarchy, though I am not certain whether that is an essential component of the problem. Attaching cpp and processed output demonstrating that: - when {brace} call to protected parent ctor is used, G++ errors out and does not allow compilation. - Yet replacing that call with (parenthesis) syntax results in the proper behaviour. Similar to my previous ticket, maybe the same root cause. Please advise when we can expect this to be fixed. It is a basic element of a 4-year-old standard. Users should not be discouraged from adopting relatively up-to-date practices for fear that otherwise 'gold standard' compilers will not be able to handle them. G++ is usually a role model for standards compliance! Thanks, D.
[Bug c++/66847] Derived class calling protected base ctor using C++11 {brace} init = spurious access denied error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66847 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #1 from DB --- Created attachment 35954 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35954&action=edit compiler command line output when compiled with recommended safeguards
[Bug c++/66847] Derived class calling protected base ctor using C++11 {brace} init = spurious access denied error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66847 --- Comment #2 from DB --- Created attachment 35955 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35955&action=edit command line output after adding -v and -save-temps
[Bug c++/66847] Derived class calling protected base ctor using C++11 {brace} init = spurious access denied error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66847 --- Comment #3 from DB --- Created attachment 35956 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35956&action=edit -save-temps output .ii file
[Bug c++/63151] Accessibility error when brace-constructing base class with protected defaulted constructor and member variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63151 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #1 from DB --- Just ran into this one myself. Though mine seems contigent on virtual inheritance, so rather than sandwiching it in here, I opened a separate ticket just in case: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66847 Added a link back to this one.
[Bug c++/66617] C++11 {brace} initialisation of virtually inherited derived class = failure to override base virtual function, unless all base ctors have same signature
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66617 --- Comment #7 from DB --- I just found a similar, possibly related issue with {brace} ctor call and access specifiers https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66847 As mentioned in the comment there, we're looking forward to movement on these so that we can properly migrate to the C++11 syntax. Currently we have to selectively use (parentheses) in certain places to work around these issues with (the otherwise flawless) G++. Thanks, D.
[Bug c++/66847] Derived class calling protected base ctor using C++11 {brace} init = spurious access denied error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66847 --- Comment #4 from DB --- It should be noted that although I have a commented-out {brace} ctor for the final class in main(), that was just a test; both {brace} and (parenthesis) init in that context produce the same behaviour. That is: dependent upon the type of braces used by Derived to call Base ctor.
[Bug c++/66847] Derived class calling protected base ctor using C++11 {brace} init = spurious access denied error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66847 --- Comment #5 from DB --- Another note is that, as per the other tickets, G++ seems to have multiple possible causes of its confusion with brace-init: * presence of virtual base in class hierarchy * signature of calling class ctor vs base ctor * presence/absence of member variables * possible more...? Hopefully it points at a single cause that can be fixed fairly easily. As currently we have to selectively regress certain parts of our source, to work around G++, and add large comments explaining the inconsistency, which is far from ideal. It's also conceivable that certain situations couldn't be worked around by replacing the bracket type, though thankfully we've not had that yet. Cheers, D.
[Bug c++/71774] [5/6/7 regression] Bogus "is protected" error when list-initializing a base class with a defaulted protected constructor and a virtual function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71774 --- Comment #2 from DB --- see also 66847, 66617, 55922
[Bug c++/63151] [5/6/7 regression] Accessibility error when brace-constructing base class with protected defaulted constructor and member variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63151 --- Comment #3 from DB --- see also 66847, 66617, 55922
[Bug c++/71793] New: Volatile local variable passed by value is (wrongly?) optimised away, but the containing loop is not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71793 Bug ID: 71793 Summary: Volatile local variable passed by value is (wrongly?) optimised away, but the containing loop is not Product: gcc Version: 5.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- Here's the original SO thread with more info and/or meandering pondering: http://stackoverflow.com/questions/38235112/why-is-a-volatile-local-variable-optimised-differently-from-a-volatile-argument g++ seems to break in a simple situation involving a function argument passed by value and declared volatile, wherein it acts differently than if such variable is declared in-body. In the former case, it elides volatile reads. #include void f(void *const p, std::size_t n) { unsigned char *y = static_cast(p); volatile unsigned char const x = 42; while (n--) { *y++ = x; } } void g(void *const p, std::size_t n, volatile unsigned char const x) { unsigned char *y = static_cast(p); while (n--) { *y++ = x; } } void h(void *const p, std::size_t n, volatile unsigned char const &x) { unsigned char *y = static_cast(p); while (n--) { *y++ = x; } } int main(int, char **) { int y[1000]; f(&y, sizeof y); volatile unsigned char const x{99}; g(&y, sizeof y, x); h(&y, sizeof y, x); } => ASM main: .LFB3: .cfi_startproc # f() movb$42, -1(%rsp) movl$4000, %eax .p2align 4,,10 .p2align 3 .L21: subq$1, %rax movzbl -1(%rsp), %edx jne .L21 # x = 99 movb$99, -2(%rsp) movzbl -2(%rsp), %eax # g() movl$4000, %eax .p2align 4,,10 .p2align 3 .L22: subq$1, %rax jne .L22 # h() movl$4000, %eax .p2align 4,,10 .p2align 3 .L23: subq$1, %rax movzbl -2(%rsp), %edx jne .L23 Is g() non-conforming here because it elides reads to a volatile variable? That might represent a hardware register whose polling has side-effects, etc. And either way, how is it that the loop body can be totally elided, rightly or not - but the loop itself still executes? (It's like I'm back programming waits on a CPC 464! ;-) thanks
[Bug rtl-optimization/71793] Volatile local variable passed by value is (wrongly?) optimised away, but the containing loop is not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71793 --- Comment #2 from DB --- Thanks Richard! About this - > RTL expansion expands x as register copy for some reason - is this person's explanation about this originating in the ABI accurate? http://stackoverflow.com/a/38248847/2757035 If so - again not that I expect anyone really to use this pattern! - but from a Standard perspective, I'm interested whether it forbids such register allocation, and whether any workaround is feasible. In practical terms, a very academic exercise :-) but valuable for its implications wrt the Standard and ABI
[Bug c++/71909] New: g++ accepts an unreachable function catch block that lacks a corresponding try
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71909 Bug ID: 71909 Summary: g++ accepts an unreachable function catch block that lacks a corresponding try Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- via http://stackoverflow.com/questions/38415131 The Standard requires a function-try block to have a corresponding post-function catch block and vice-versa. But g++ will merrily compile the following without saying anything, even with -std=c++14 -Wall -Wextra -Wpedantic struct foo { void bar() { } catch (...) { } }; int main () { foo f; f.bar(); return 0; } I presume the parser never checks for this case - somewhat understandable as function-try is rare enough even when it _is_ used properly - but g++ should generate an error on this code because it is not well-formed.
[Bug rtl-optimization/71793] Volatile local variable passed by value is (wrongly?) optimised away, but the containing loop is not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71793 --- Comment #4 from DB --- (In reply to Richard Biener from comment #3) > Well, if you look at the out-of-line copies of the function then he is > correct. > But the inline copy in main() does not have this constraint and is still > mishandled. Note I didn't yet investigate closer what is going on. For the out-of-line copies, surely they are not allowed to leave a declared as volatile argument in a register and thereby break volatility? That seems contrary to the requirements of the storage class. I'd expect special handling to allocate a value on the stack prior to calling and refer to that in the function instead.
[Bug c++/66847] Derived class calling protected base ctor using C++11 {brace} init = spurious access denied error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66847 --- Comment #9 from DB --- Will the fix hit any previous major versions, esp. 6?
[Bug libstdc++/58876] No non-virtual-dtor warning in std::unique_ptr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58876 DB changed: What|Removed |Added CC||db0451 at gmail dot com --- Comment #10 from DB --- Sorry to pester, but is this likely to get anywhere, any time soon? I fixed a bug in one of my projects recently by using AddressSanitizer, which this would've caught if it warned on non-polymorphic deletion via unique_ptr, so it'd be nice to see. I presume the same goes for std::shared_ptr, too.