[cfe-users] Code which compiles with g++ but not with clang++
Hello, I would like to ask what is wrong with the following code: ``` #include struct S { S& operator=(S&) { return *this; }; }; void thisWillNotCompileInClang() { std::optional a; } ``` Compilation command is `g++ or clang++ -std=c++17 -c source.cpp`. It compiles without problems with g++ 9.3.0, but not with clang++ 10.0.0 (both from current stable Ubuntu 20). This code is simplification of code using widely adopted rapidjson library which uses assignment operator with non-const parameter a lot. Earlier versions of clang did not complain (tried with 7.0.1 on currently stable Debian Buster). Thank you very much for your time and explanation. Kind regards, Pavel Cernohorsky ___ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
Re: [cfe-users] Code which compiles with g++ but not with clang++
> On Nov 5, 2020, at 6:34 AM, Pavel Černohorský via cfe-users > wrote: > > Hello, > > I would like to ask what is wrong with the following code: > ``` > > #include > > struct S > { > S& operator=(S&) { return *this; }; > }; > > void thisWillNotCompileInClang() > { > std::optional a; > } > > ``` > > Compilation command is `g++ or clang++ -std=c++17 -c source.cpp`. It compiles > without problems with g++ 9.3.0, but not with clang++ 10.0.0 (both from > current stable Ubuntu 20). This code is simplification of code using widely > adopted rapidjson library which uses assignment operator with non-const > parameter a lot. Earlier versions of clang did not complain (tried with 7.0.1 > on currently stable Debian Buster). I tried this code on compiler explorer. It compiles w/o error with clang + libc++ It fails to compile with clang and libstdc++ The error message given is: In file included from :1: /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:158:7: error: the parameter for this explicitly-defaulted copy assignment operator is const, but a member or base requires it to be non-const operator=(const _Optional_payload_base&) = default; ^ /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:357:7: note: in instantiation of template class 'std::_Optional_payload_base' requested here : _Optional_payload_base<_Tp> ^ /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:631:30: note: in instantiation of template class 'std::_Optional_payload' requested here _Optional_payload<_Tp> _M_payload; ^ /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:660:15: note: in instantiation of template class 'std::_Optional_base' requested here : private _Optional_base<_Tp>, ^ :10:20: note: in instantiation of template class 'std::optional' requested here std::optional a; ^ 1 error generated. — Marshall___ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
Re: [cfe-users] Code which compiles with g++ but not with clang++
On 05. 11. 20 15:47, Marshall Clow via cfe-users wrote: I tried this code on compiler explorer. It compiles w/o error with clang + libc++ It fails to compile with clang and libstdc++ The error message given is: In file included from :1: /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:158:7: error: the parameter for this explicitly-defaulted copy assignment operator is const, but a member or base requires it to be non-const operator=(const _Optional_payload_base&) = default; ^ /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:357:7: note: in instantiation of template class 'std::_Optional_payload_base' requested here : _Optional_payload_base<_Tp> ^ /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:631:30: note: in instantiation of template class 'std::_Optional_payloadtrue, false, false>' requested here _Optional_payload<_Tp> _M_payload; ^ /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:660:15: note: in instantiation of template class 'std::_Optional_basetrue>' requested here : private _Optional_base<_Tp>, ^ :10:20: note: in instantiation of template class 'std::optional' requested here std::optional a; ^ 1 error generated. I got exactly the same error, but the question is why. Shouldn't both g++ and clang++ behave the same way even on the libstdc++ (which is the default library clang uses on a lot of distros)? Is this gcc being too permissive to some bug in libstdc++ or is it a clang bug? Should I file a bug report to clang? ___ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
Re: [cfe-users] Code which compiles with g++ but not with clang++
On Thu, Nov 5, 2020 at 11:06 connor horman wrote: > Looking at https://eel.is/c++draft/optional.optional and optional.assign, > it shouldn't be ill-formed to have a non copy-constructible type, the copy > constructor of optional should be defined as deleted. > [optional.optional.general] clause 3 "T shall be a type other than cv > in_place_t or cv nullopt_t that meets the Cpp17Destructible requirements" > [optional.assign] clause 7 "This operator is defined as deleted unless > is_copy_constructible_v is true and is_copy_assignable_v is true" > > I presume it's the same or similar in both C++17 and C++20 (published) > (with Cpp17Destructible being just Destructible in C++17). > > > On Thu, Nov 5, 2020 at 10:07 Pavel Černohorský via cfe-users < > cfe-users@lists.llvm.org> wrote: > >> On 05. 11. 20 15:47, Marshall Clow via cfe-users wrote: >> >> I tried this code on compiler explorer. >> It compiles w/o error with clang + libc++ >> It fails to compile with clang and libstdc++ >> >> The error message given is: >> >> In file included from :1: >> /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:158:7: >> error: the parameter for this explicitly-defaulted copy assignment operator >> is const, but a member or base requires it to be non-const >> operator=(const _Optional_payload_base&) = default; >> ^ >> /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:357:7: >> note: in instantiation of template class 'std::_Optional_payload_base' >> requested here >>: _Optional_payload_base<_Tp> >> ^ >> /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:631:30: >> note: in instantiation of template class 'std::_Optional_payload> false, false>' requested here >> _Optional_payload<_Tp> _M_payload; >> ^ >> /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:660:15: >> note: in instantiation of template class 'std::_Optional_base> true>' requested here >>: private _Optional_base<_Tp>, >> ^ >> :10:20: note: in instantiation of template class >> 'std::optional' requested here >> std::optional a; >> ^ >> 1 error generated. >> >> I got exactly the same error, but the question is why. Shouldn't both g++ >> and clang++ behave the same way even on the libstdc++ (which is the default >> library clang uses on a lot of distros)? Is this gcc being too permissive >> to some bug in libstdc++ or is it a clang bug? Should I file a bug report >> to clang? >> ___ >> cfe-users mailing list >> cfe-users@lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users >> > ___ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
Re: [cfe-users] Code which compiles with g++ but not with clang++
I've actually reduced the problem to the defaulted copy assignment operator itself: gcc: https://godbolt.org/z/83Gjdb clang: https://godbolt.org/z/z35x4K The controlling clause would seem to be https://eel.is/c++draft/class.copy.assign#7.4. In particular, because overload resolution cannot find this->_m.operator=(rhs._m), the operator should be defined as deleted (which seems to be the behaviour of gcc, https://godbolt.org/z/bs5aPY). On Thu, 5 Nov 2020 at 11:08, connor horman wrote: > > > On Thu, Nov 5, 2020 at 11:06 connor horman wrote: > >> Looking at https://eel.is/c++draft/optional.optional and >> optional.assign, it shouldn't be ill-formed to have a non >> copy-constructible type, the copy constructor of optional should be defined >> as deleted. >> [optional.optional.general] clause 3 "T shall be a type other than cv >> in_place_t or cv nullopt_t that meets the Cpp17Destructible requirements" >> [optional.assign] clause 7 "This operator is defined as deleted unless >> is_copy_constructible_v is true and is_copy_assignable_v is true" >> >> I presume it's the same or similar in both C++17 and C++20 (published) >> (with Cpp17Destructible being just Destructible in C++17). >> >> >> On Thu, Nov 5, 2020 at 10:07 Pavel Černohorský via cfe-users < >> cfe-users@lists.llvm.org> wrote: >> >>> On 05. 11. 20 15:47, Marshall Clow via cfe-users wrote: >>> >>> I tried this code on compiler explorer. >>> It compiles w/o error with clang + libc++ >>> It fails to compile with clang and libstdc++ >>> >>> The error message given is: >>> >>> In file included from :1: >>> /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:158:7: >>> error: the parameter for this explicitly-defaulted copy assignment operator >>> is const, but a member or base requires it to be non-const >>> operator=(const _Optional_payload_base&) = default; >>> ^ >>> /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:357:7: >>> note: in instantiation of template class 'std::_Optional_payload_base' >>> requested here >>>: _Optional_payload_base<_Tp> >>> ^ >>> /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:631:30: >>> note: in instantiation of template class 'std::_Optional_payload>> false, false>' requested here >>> _Optional_payload<_Tp> _M_payload; >>> ^ >>> /opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../include/c++/10.2.0/optional:660:15: >>> note: in instantiation of template class 'std::_Optional_base>> true>' requested here >>>: private _Optional_base<_Tp>, >>> ^ >>> :10:20: note: in instantiation of template class >>> 'std::optional' requested here >>> std::optional a; >>> ^ >>> 1 error generated. >>> >>> I got exactly the same error, but the question is why. Shouldn't both >>> g++ and clang++ behave the same way even on the libstdc++ (which is the >>> default library clang uses on a lot of distros)? Is this gcc being too >>> permissive to some bug in libstdc++ or is it a clang bug? Should I file a >>> bug report to clang? >>> ___ >>> cfe-users mailing list >>> cfe-users@lists.llvm.org >>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users >>> >> ___ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users
Re: [cfe-users] Code which compiles with g++ but not with clang++
On Nov 5, 2020, at 6:34 AM, Pavel Černohorský via cfe-users wrote: > > Hello, > > I would like to ask what is wrong with the following code: > ``` > > #include > > struct S > { >S& operator=(S&) { return *this; }; > }; > > void thisWillNotCompileInClang() > { > std::optional a; > } > > ``` > > Compilation command is `g++ or clang++ -std=c++17 -c source.cpp`. It compiles > without problems with g++ 9.3.0, but not with clang++ 10.0.0 (both from > current stable Ubuntu 20). This code is simplification of code using widely > adopted rapidjson library which uses assignment operator with non-const > parameter a lot. Earlier versions of clang did not complain (tried with 7.0.1 > on currently stable Debian Buster). A note from the libstdc++ maintainer: > I think there was a core change in C++20 to make the =default do the right > thing (which is delete it, I think). > Clang does compile it with -std=c++20 just not -std=c++17. — Marshall ___ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users