[Bug c++/93870] New: User-defined conversion function not working in evaluation of template argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93870 Bug ID: 93870 Summary: User-defined conversion function not working in evaluation of template argument Product: gcc Version: 7.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: o_kniemeyer at maxon dot net Target Milestone: --- According to gcc.godbolt.org GCC 7.1 up to 9.2 fail to compile this piece of code: template struct EnumWrapper { ENUM value; constexpr operator ENUM() const { return value; } }; enum E : int { V }; constexpr EnumWrapper operator ~(E a) { return {E(~int(a))}; } template struct R { static void Func(); }; template struct S : R<~X> { }; void Test() { S::Func(); } The can't evaluate the template argument ~X for R: : In instantiation of 'struct S<(E)0>': :32:12: required from here :26:31: error: taking address of temporary [-fpermissive] template struct S : R<~X> ^ :26:31: error: no matching function for call to 'EnumWrapper::operator E(EnumWrapper*)' :5:12: note: candidate: constexpr EnumWrapper::operator ENUM() const [with ENUM = E] constexpr operator ENUM() const ^~~~ :5:12: note: candidate expects 0 arguments, 1 provided : In function 'void Test()': :32:14: error: 'Func' is not a member of 'S<(E)0>' S::Func(); ^~~~ All other compiler are fine. A workaround is to convert to E explicitly by writing R.
[Bug c++/87841] Member of class template hides template parameter of another member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87841 --- Comment #5 from Ole Kniemeyer --- Thanks for asking the committee. I think the standard makes sense as it is, because otherwise there is no chance to name the template parameter (that's what I need in my specific situation where I found the bug). Also the standard is what I would expect as the template parameter is "closer" to the function template as a member type of the enclosing class.
[Bug c++/88221] New: Only restricted set of balanced token sequences allowed for attributes
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88221 Bug ID: 88221 Summary: Only restricted set of balanced token sequences allowed for attributes Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: o_kniemeyer at maxon dot net Target Milestone: --- Attribute arguments may be arbitrary token sequences as long as they are balanced regarding () [] {}. From C++17 10.6.1: attribute-argument-clause : ( balanced-token-seq opt ) balanced-token-seq : balanced-token balanced-token-seq balanced-token balanced-token : ( balanced-token-seqopt ) [ balanced-token-seqopt ] { balanced-token-seqopt } any token other than a parenthesis, a bracket, or a brace However GCC only allows a quite restricted set. For example the following arguments are rejected: [[myattribute(a)]] void Func(); [[myattribute(void)]] void Func(); [[myattribute(1 2)]] void Func(); [[myattribute(1:2)]] void Func(); [[myattribute([1])]] void Func();
[Bug c++/87841] Member of class template hides template parameter of another member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87841 --- Comment #3 from Ole Kniemeyer --- Yes, I also tried other compilers, and all of them fail. But in [temp.local] it is explicitly stated that "the name of a member of the class template hides the name of a template-parameter of any enclosing class templates (BUT NOT A TEMPLATE-PARAMETER OF THE MEMBER IF THE MEMBER IS A CLASS OR FUNCTION TEMPLATE)". (Bold by me, that's the case of this bug.)
[Bug c++/87841] New: Member of class template hides template parameter of another member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87841 Bug ID: 87841 Summary: Member of class template hides template parameter of another member Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: o_kniemeyer at maxon dot net Target Milestone: --- The following code example from C++17 standard 17.6.1.7 does not compile: template struct A { struct B { /* ... */ }; typedef void C; void f(); template void g(U); }; template void A::f() { B b; // A's B, not the template parameter } template template void A::g(C) { B b; // A's B, not the template parameter C c; // the template parameter C, not A's C } This is because GCC uses A's C instead of the template parameter C of A::g.
[Bug c++/87842] New: Member of class template hides template parameter of another member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87842 Bug ID: 87842 Summary: Member of class template hides template parameter of another member Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: o_kniemeyer at maxon dot net Target Milestone: --- The following code example from C++17 standard 17.6.1.7 does not compile: template struct A { struct B { /* ... */ }; typedef void C; void f(); template void g(U); }; template void A::f() { B b; // A's B, not the template parameter } template template void A::g(C) { B b; // A's B, not the template parameter C c; // the template parameter C, not A's C } This is because GCC uses A's C instead of the template parameter C of A::g.
[Bug c++/79101] New: Registers aren't used for passing and returning objects when there is a move constructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79101 Bug ID: 79101 Summary: Registers aren't used for passing and returning objects when there is a move constructor Product: gcc Version: 6.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: o_kniemeyer at maxon dot net Target Milestone: --- According to the calling conventions of System V AMD64 ABI (e.g. https://www.uclibc.org/docs/psABI-x86_64.pdf) a simple class with trivial copy constructor and trivial destructor is passed and returned in a register, no matter if there is a non-trivial move constructor or not. However this code: struct X { X(char* p = nullptr) : ptr(p) { } X(const X& src) = default; X(X&& src) : ptr(src.ptr) { src.ptr = nullptr; } X& operator=(const X&) = default; char* ptr; }; X Test(X x) { return x.ptr+1; } is (wrongly) compiled to Test(X): mov rdx, QWORD PTR [rsi] mov rax, rdi add rdx, 1 mov QWORD PTR [rdi], rdx ret whereas the code without move constructor is correctly compiled to Test(X): lea rax, [rdi+1] ret I checked this with all GCC versions on http://gcc.godbolt.org. Clang correctly compiles the code to the two-liner with or without the move constructor.
[Bug c++/65866] New: Wrong warning when using list-initialization: operation on 'b' may be undefined [-Wsequence-point]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65866 Bug ID: 65866 Summary: Wrong warning when using list-initialization: operation on 'b' may be undefined [-Wsequence-point] Product: gcc Version: 5.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: o_kniemeyer at maxon dot net This is related to Bug 51253: While that bug was about wrong compiled code and is reported to be fixed, GCC 5.1.0 still produces a warning in code like struct X { template typename... ARGS X(ARGS...); }; void test() { bool b = false; X{b = true, b = true}; } warning: operation on 'b' may be undefined [-Wsequence-point] Because list-initialization has to be done from left to right, the warning is wrong.
[Bug c++/57610] New: Result of conversion
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610 Bug ID: 57610 Summary: Result of conversion Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: o_kniemeyer at maxon dot net
[Bug c++/57610] Result of conversion
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610 --- Comment #2 from Ole Kniemeyer o_kniemeyer at maxon dot net --- Created attachment 30301 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30301action=edit cpp file (without any #includes) which shows the bug
[Bug c++/57610] Reference initialized with temporary instead of sub-object of conversion result
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610 Ole Kniemeyer o_kniemeyer at maxon dot net changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #3 from Ole Kniemeyer o_kniemeyer at maxon dot net --- In the example X can be converted to B which is a derived class of A. When an A reference is initialized with an X object, the result of the X::operator B() should be used directly for the A reference, but GCC creates a temporary A object and initializes this by copy-construction from the conversion result. At least if the classes use virtual functions, this leads to wrong results.
[Bug c++/57610] Reference initialized with temporary instead of sub-object of conversion result
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610 --- Comment #4 from Ole Kniemeyer o_kniemeyer at maxon dot net --- As I commented in the cpp example, the C++11 standard shows exactly this example in sections 8.5.3. So this is definitely a bug according to C++11. I think the GCC behaviour is correct according to older C++11 standards.
[Bug c++/57610] Reference initialized with temporary instead of sub-object of conversion result
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610 --- Comment #5 from Ole Kniemeyer o_kniemeyer at maxon dot net --- Ops, sorry, of course I meant ... to older C++ standards.
[Bug c++/57610] Reference initialized with temporary instead of sub-object of conversion result
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57610 --- Comment #7 from Ole Kniemeyer o_kniemeyer at maxon dot net --- OK, thanks for your comments. I wasn't aware of the ongoing discussion about this issue (I was referring to the the draft version N3376 of the C++11 standard). A B-copy would be OK, but as I said copying B into A is not a good idea if those classes have virtual functions. The N3376 wording would be much better for such cases. In my case A is an interface (with dummy implementations of the virtual functions), B an implementation of A and X an unrelated class with conversion operator to B. Now if a function has a const A parameter (so it works with the interface), N3376 allows me to pass an X object to this function by implicitly creating a temporary B object which makes X look like an A. With the variant discussed in the links you posted this wouldn't work (copying B into A makes no sense).