[Bug c++/57825] New: Template specialization for ref qualified member pointers
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57825 Bug ID: 57825 Summary: Template specialization for ref qualified member pointers Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tomaszkam at gmail dot com Created attachment 30460 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=30460&action=edit Bugus code exmaple The class template specialization for member pointers that differs only on ref qualification issue double redefinition error. For example the compilation of following code: template struct target_class {}; template struct target_class {}; template struct target_class {}; template struct target_class {}; Will result in the following buggy errors: template_ref_bug.cpp:10:8: error: redefinition of ‘struct target_class’ struct target_class ^ template_ref_bug.cpp:6:8: error: previous definition of ‘struct target_class’ struct target_class ^ template_ref_bug.cpp:14:8: error: redefinition of ‘struct target_class’ struct target_class ^ template_ref_bug.cpp:6:8: error: previous definition of ‘struct target_class’ struct target_class
[Bug c++/57825] Template specialization for ref qualified member pointers
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57825 --- Comment #2 from Tomasz Kamiński --- Propably this is also causing the problem with the standard library is_function and is_member function traits, because they cannot be implemented correclty. Example: struct A { void f_n() {} void f_l() &{} void f_r() &&{} }; The following assertions fails incorrectly. static_assert(std::is_function::value, "function"); static_assert(std::is_member_pointer::value, "member function"); static_assert(std::is_function::value, "function"); static_assert(std::is_member_pointer::value, "member function");
[Bug c++/57825] Template specialization for ref qualified member pointers
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57825 --- Comment #7 from Tomasz Kamiński --- > No, this was a different problem and it became fixed. Your example code > works fine gcc 4.9.0 20130616 (experimental) (I do know this, because I > recently completed the implementation of std::function for gcc) Thank you. I assumed that this is not working also for normal functions.
[Bug c++/66139] destructor not called for members of partially constructed anonymous struct/array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66139 --- Comment #2 from Tomasz Kamiński --- Example of some real life safe-code (now raw allocations, STL container used), that is leaking: #include #include #include using namespace std; struct Test { string a; string b; }; Test make_test() { vector strings {"123456789abcdef0"}; return Test { strings.at(0), strings.at(2) // throws; the destructor for a copy of strings.at(0) is not called and memory leakds }; } int main() { try { Test test = make_test(); } catch (exception &e) { cerr << e.what() << endl; } } Live code proving leaks: https://wandbox.org/permlink/GjjxFw9jAE9bfvyS
[Bug libstdc++/77727] New: Unwrapping std::optional constructor is not working for non-transferable object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77727 Bug ID: 77727 Summary: Unwrapping std::optional constructor is not working for non-transferable object Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: tomaszkam at gmail dot com Target Milestone: --- The following code does not compile: #include struct NonTransferable { NonTransferable(int) {} NonTransferable(NonTransferable&&) = delete; NonTransferable& operator=(NonTransferable&&) = delete; }; int main() { std::optional oi; std::optional ot(std::move(oi)); std::optional oi2(10); std::optional ot2(oi2); } Both the construction of the ot and ot2 shall be well-formed according to specification from http://cplusplus.github.io/LWG/lwg-active.html#2756 and call: optional::optional(optional&&); optional::optional(optional const&); constructors respectively as: is_constructible_v is_constructible_v are true, and the NonTransferable class cannot be constructed/converted from optional.
[Bug c++/77976] `auto x = type{…}` initialization syntax rejects `explicit` user-defined conversion
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77976 Tomasz Kamiński changed: What|Removed |Added CC||tomaszkam at gmail dot com --- Comment #1 from Tomasz Kamiński --- Duplicate of: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63999
[Bug c++/78420] New: std::less is not an total order with optimization enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78420 Bug ID: 78420 Summary: std::less is not an total order with optimization enabled Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tomaszkam at gmail dot com Target Milestone: --- The 20.14.6 [comparisons] p14: For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <= , >= do not. Requires that the less is an total order, which means that the one of the following is true for every pair of pointer values a,b: 1) lt(a, b) 2) lt(b, a) 3) !lt(a,b) && !lt(b, a) //i.e. a == b, where equality is generated from lessw where lt is object on less. This does not hold for following code snippet when compared with O2: #include int b[8]; int a[8]; int main() { auto p = a + 8; std::less lt; std::cout << p << ' ' << b << ' ' << lt(p, b) << ' ' << lt(b, p) << ' ' << (!lt(p, b) && !lt(b, p)) << std::endl; } The output is: 0x6015c0 0x6015c0 0 0 0 (link to live example, require optimization to be enabled: http://melpon.org/wandbox/permlink/vyY82MsxrxWNyOOJ#).
[Bug c++/78420] std::less is not an total order with optimization enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78420 --- Comment #1 from Tomasz Kamiński --- This is probably effect on changing !lt(a,b) && !lt(b, a) into !(a
[Bug c++/78420] std::less is not a total order with -O2 enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78420 --- Comment #3 from Tomasz Kamiński --- > I don't see this as prohibiting the transformation. The standard seems to be > saying that they might or might not compare as equal, which presumably > depends on how variables are laid out in memory. The optimization seems > wrong to me. But, the code snippet is not using == on this pointer, but std::less specialization that is required to form total order, but in the attached scenario as not because for p and b nor of following hold: 1) r(p, b) 2) r(b, p) 3) b is same as p (!r(p, b) && !r(b, p)) Which proves that r is not an total order. So the guarantee on the less is no longer provided.
[Bug c++/78420] std::less is not a total order with -O2 enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78420 --- Comment #4 from Tomasz Kamiński --- Oh, you mean that compiler is not allowed to turn comparison of p == b into false at compile time, using 5.10 [expr.eq] p2.1? Some reference from clang: https://llvm.org/bugs/show_bug.cgi?id=13507. Note that I am unable to reproduce problem on clang.
[Bug c++/78420] std::less is not a total order with -O2 enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78420 --- Comment #7 from Tomasz Kamiński --- > No, it's very much allowed to do that. But I'm skeptical that it's allowed > to turn !(a{}(a,b) && !std::less(b,a) being false, when std::less{}(a,b) and std::less{}(b,a) are both false, and in contrast to raw operator<, std::less is required to provide total order, which is no longer the case. And my complain, is about behavior of std::less, that is not standard compliant. If it can be changed without changing <, I am fine with it.
[Bug c++/63999] New: Explcit conversion operators are not considered for explicit cast using brace
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63999 Bug ID: 63999 Summary: Explcit conversion operators are not considered for explicit cast using brace Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tomaszkam at gmail dot com For the following code: struct bool_convert { explicit operator bool() { return true; } }; bool x(bool_convert());//1 bool x1{bool_convert{}}; //2 bool x2 = bool{bool_convert{}}; //3 Both line 1 and 2 compiles correcty, while the line 3 produces following error: error: cannot convert 'bool_convert' to 'bool' in initialization. According to the standard section $5.2.3 [expr.type.conv]/3: Similarly, a simple-type-specifier or typename-specifier followed by a braced-init-list creates a temporary object of the specified type direct-list-initialized (8.5.4) with the specified braced-init-list, and its value is that temporary object as a prvalue. That means that cast notation from the line 3 should have equivalent semantics to the one from line 2. Section $12.3.2 [class.conv.fct]/2: A conversion function may be explicit (7.1.2), in which case it is only considered as a user-defined conversion for direct-initialization (8.5). Otherwise, user-defined conversions are not restricted to use in assignments and initializations. Explicit conversion operator should be invoked for direct initialization so behaviour for line 3 is incoorect and conversion operator should be used.
[Bug libstdc++/66998] New: not_fn invocation is not SFINAE friendly
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66998 Bug ID: 66998 Summary: not_fn invocation is not SFINAE friendly Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: tomaszkam at gmail dot com Target Milestone: --- According to the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4529.html#func.not_fn the following invocations not_fn(f)(args...) and !INVOKE(f, args...) (in case when f is function object it can be simplified to !f(args)). However the in current implementation they behavior differs in case when they are used in SFINAE context. For example: #include template auto foo1(F f, Arg arg) -> decltype(!f(arg)) { return !f(arg); } template auto foo1(F f, Arg arg) -> decltype(!f()) { return !f(); } template auto foo2(F f, Arg arg) -> decltype(not_fn(f)(arg)) { return not_fn(f)(arg); } template auto foo2(F f, Arg arg) -> decltype(not_fn(f)()) { return not_fn(f)(); } struct negator { bool operator()(int) const { return false; } void operator()() const {} }; int main() { foo1(negator{}, 1); //foo2(negator{}, 1)); //Shall be equivalent to line above. Produces an compilation error cause by instatiation error during return type deduction. }; The problem is caused by the use of return type deduction (decltype(auto)) instead of decltype(expr) in the implementation of not_fn. Notice that such use does not break the function precondition placed in requires clause.
[Bug libstdc++/66998] not_fn invocation is not SFINAE friendly
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66998 --- Comment #2 from Tomasz Kamiński --- Sorry for missing using declaration. > It's certainly a nice QoI improvement. I was basically lazy when I > implemented it and used decltype(auto) because it's convenient. Yes, the decltype(auto) is convenient but the hard error produced in SFINAE context make it acutally unusable in library. Just think of the mess that would be caused by: template delctype(auto) begin(C&& c) { return std::forward(c).begin(); } The not_fn is also not working with member pointers: #include using namespace std::experimental; struct A { bool mem; }; int main() { not_fn(&A::mem)(A{}); }; Should I create separate issue?
[Bug c++/71886] New: Incorrect error on operator() being an member in template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71886 Bug ID: 71886 Summary: Incorrect error on operator() being an member in template Product: gcc Version: 5.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tomaszkam at gmail dot com Target Milestone: --- Following class correctly compiles without any error in GCC 5.1.0: struct NonTemplate { typedef void type(); type operator(); //Actually declares an member function. }; However in case of the class template: template struct Template { typedef T type; T operator(); }; Followinge error is generated: error: declaration of 'operator()' as non-function T operator(); Despite the fact that Template is identical to NonTemplate.
[Bug c++/71886] Incorrect error on operator() being an member in template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71886 --- Comment #1 from Tomasz Kamiński --- Such code is useful, for example in case of variant universal constructor from U&&, where there is a need to determine best candidate among the function taking parameter each type be value. This may be implemented using: template struct single_call { Sig operator(); }; template struct multiple_calls : single_call... { using single_call::operator()...; }; Then to determine an index of type to be constructed can be done by: decltype(multiple_calls(Ts)...>)::value Where Is is [0,1,2] and Ts is [T0, T1, T2].
[Bug c++/117849] constraint variable in requires expression rejected, but P2280R4 made it valid
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117849 --- Comment #7 from Tomasz Kamiński --- >> I also added a 'size(t) > 0' check and a check for a type that is not >> >> statically sized, where the concept shouldn't become ill-formed either. > > FWIW I think GCC is correct to diagnose this due to > https://eel.is/c++draft/temp.constr#atomic-3, which mandates that an atomic > constraint after substitution yields a constant expression of type bool, but > here it's non-constant. Isn't check `typename i;` (that is placed before) guarding the later requires? It can only pass if size(t) is constant. Or requirements inside require expr do not short-circuit?