From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 17A47385040C; Thu, 15 Oct 2020 00:10:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 17A47385040C From: "peifeng2005 at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/97432] New: Casting away constness in the drafts [conv.qual] a cv-decomposition exists in the following examples but fails in gcc Date: Thu, 15 Oct 2020 00:10:37 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 11.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: peifeng2005 at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Oct 2020 00:10:38 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D97432 Bug ID: 97432 Summary: Casting away constness in the drafts [conv.qual] a cv-decomposition exists in the following examples but fails in gcc Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: peifeng2005 at gmail dot com Target Milestone: --- In C++, the concept of [casting away constness](https://timsong-cpp.github.io/cppwp/expr.const.cast#7) is rigoro= usly defined by the standard. Casts such as `static_cast` and `reinterpret_cast`= are not allowed to cast away constness in the explicit conversion. The definiti= on of casting away constness heavily relies on the qualification conversion definition, which says that two types can perform a qualification conversio= n up to [similar](https://timsong-cpp.github.io/cppwp/conv.qual#2) type. `reinterpret_cast` can then perform the cast on the non-similar parts, for example. Here is an example also available in [godbolt](https://godbolt.org/z/Y7qEcY= ): ```c++ struct T{}; struct F{}; void f() { const int* const T::* const * const * const x {}; // pointer to array - works in clang (trunk), // works in gcc (trunk) reinterpret_cast(x); // member pointer to pointer - works in clang (trunk),=20 // fails in gcc (trunk) reinterpret_cast(x); // member pointer to another member pointer type - fails in clang (trun= k), // fails in gcc (trunk) reinterpret_cast(x); } ``` Recall the definition of similar. The types at each level must be of the categories: > ... each Pi is =E2=80=9Cpointer to=E2=80=9D ([dcl.ptr]), =E2=80=9Cpointer= to member of class Ci of type=E2=80=9D ([dcl.mptr]), =E2=80=9Carray of Ni= =E2=80=9D, or =E2=80=9Carray of unknown bound of=E2=80=9D ([dcl.array]) To be similar, each Pi must belong to the same category: > ... corresponding Pi components are either the same or one is =E2=80=9Car= ray of Ni=E2=80=9D and the other is =E2=80=9Carray of unknown bound of=E2= =80=9D In the first case, array and pointers are NOT similar. GCC and clang correc= tly says that the types `X[]` and `X*` are not similar and thus `reinterpret_ca= st` kicks in to ignore any const qualifiers past the array (so `const int* cons= t` could be converted to `int*`). Everything is good. In the second case, pointers and member pointers should NOT be similar. cla= ng correctly says that the types are not similar and thus `reinterpret_cast` k= icks in. *GCC says the types are similar and thus we are casting away constness*. I'm pretty sure GCC is wrong here. In the third case, we are comparing **two member pointers of different classes**. Both clang and GCC believes they are similar, but if we carefully look at the draft, it says **"pointer to member of class Ci of type"**. If they're of different types, shouldn't we consider them to be not-similar? A= re both clang and gcc wrong here? By the way, MSVC allows all of the above with no warnings (x64 msvc 19.27 on godbolt).=