Message ID | 20240618143157.31204-1-polacek@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: ICE with __has_unique_object_representations [PR115476] | expand |
On 6/18/24 10:31, Marek Polacek wrote: > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14/13? Makes sense to me, though probably the [meta.unary.prop] table should be adjusted in the same way. Jonathan, what do you think? > -- >8 -- > Here we started to ICE with r13-25: in check_trait_type, for "X[]" we > return true here: > > if (kind == 1 && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) > return true; // Array of unknown bound. Don't care about completeness. > > and then end up crashing in record_has_unique_obj_representations: > > 4836 if (cur != wi::to_offset (sz)) > > because sz is null. > > https://eel.is/c++draft/type.traits#tab:meta.unary.prop-row-47-column-3-sentence-1 > says that the preconditions for __has_unique_object_representations are: > "T shall be a complete type, cv void, or an array of unknown bound" and > that "For an array type T, the same result as > has_unique_object_representations_v<remove_all_extents_t<T>>" so T[] > should be treated as T. So we should use kind==2 for the trait. > > PR c++/115476 > > gcc/cp/ChangeLog: > > * semantics.cc (finish_trait_expr) > <case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS>: Move below to call > check_trait_type with kind==2. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp1z/has-unique-obj-representations4.C: New test. > --- > gcc/cp/semantics.cc | 2 +- > .../cpp1z/has-unique-obj-representations4.C | 16 ++++++++++++++++ > 2 files changed, 17 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C > > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc > index 08f5f245e7d..42251b6764b 100644 > --- a/gcc/cp/semantics.cc > +++ b/gcc/cp/semantics.cc > @@ -12966,7 +12966,6 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) > case CPTK_HAS_NOTHROW_COPY: > case CPTK_HAS_TRIVIAL_COPY: > case CPTK_HAS_TRIVIAL_DESTRUCTOR: > - case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: > if (!check_trait_type (type1)) > return error_mark_node; > break; > @@ -12976,6 +12975,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) > case CPTK_IS_STD_LAYOUT: > case CPTK_IS_TRIVIAL: > case CPTK_IS_TRIVIALLY_COPYABLE: > + case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: > if (!check_trait_type (type1, /* kind = */ 2)) > return error_mark_node; > break; > diff --git a/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C b/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C > new file mode 100644 > index 00000000000..d6949dc7005 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C > @@ -0,0 +1,16 @@ > +// PR c++/115476 > +// { dg-do compile { target c++11 } } > + > +struct X; > +static_assert(__has_unique_object_representations(X), ""); // { dg-error "invalid use of incomplete type" } > +static_assert(__has_unique_object_representations(X[]), ""); // { dg-error "invalid use of incomplete type" } > +static_assert(__has_unique_object_representations(X[1]), ""); // { dg-error "invalid use of incomplete type" } > +static_assert(__has_unique_object_representations(X[][1]), ""); // { dg-error "invalid use of incomplete type" } > + > +struct X { > + int x; > +}; > +static_assert(__has_unique_object_representations(X), ""); > +static_assert(__has_unique_object_representations(X[]), ""); > +static_assert(__has_unique_object_representations(X[1]), ""); > +static_assert(__has_unique_object_representations(X[][1]), ""); > > base-commit: 7f9be55a4630134a237219af9cc8143e02080380
On Tue, 25 Jun 2024 at 03:12, Jason Merrill <jason@redhat.com> wrote: > > On 6/18/24 10:31, Marek Polacek wrote: > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14/13? > > Makes sense to me, though probably the [meta.unary.prop] table should be > adjusted in the same way. Jonathan, what do you think? Just to make sure I understand correctly, the suggestion is to change the precondition for the trait to something like: "remove_all_extents_t<T> shall be a complete type or cv void." i.e. if T is incomplete then T[] cannot be used with the trait, right? > > > -- >8 -- > > Here we started to ICE with r13-25: in check_trait_type, for "X[]" we > > return true here: > > > > if (kind == 1 && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) > > return true; // Array of unknown bound. Don't care about completeness. > > > > and then end up crashing in record_has_unique_obj_representations: > > > > 4836 if (cur != wi::to_offset (sz)) > > > > because sz is null. > > > > https://eel.is/c++draft/type.traits#tab:meta.unary.prop-row-47-column-3-sentence-1 > > says that the preconditions for __has_unique_object_representations are: > > "T shall be a complete type, cv void, or an array of unknown bound" and > > that "For an array type T, the same result as > > has_unique_object_representations_v<remove_all_extents_t<T>>" so T[] > > should be treated as T. So we should use kind==2 for the trait. > > > > PR c++/115476 > > > > gcc/cp/ChangeLog: > > > > * semantics.cc (finish_trait_expr) > > <case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS>: Move below to call > > check_trait_type with kind==2. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp1z/has-unique-obj-representations4.C: New test. > > --- > > gcc/cp/semantics.cc | 2 +- > > .../cpp1z/has-unique-obj-representations4.C | 16 ++++++++++++++++ > > 2 files changed, 17 insertions(+), 1 deletion(-) > > create mode 100644 gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C > > > > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc > > index 08f5f245e7d..42251b6764b 100644 > > --- a/gcc/cp/semantics.cc > > +++ b/gcc/cp/semantics.cc > > @@ -12966,7 +12966,6 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) > > case CPTK_HAS_NOTHROW_COPY: > > case CPTK_HAS_TRIVIAL_COPY: > > case CPTK_HAS_TRIVIAL_DESTRUCTOR: > > - case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: > > if (!check_trait_type (type1)) > > return error_mark_node; > > break; > > @@ -12976,6 +12975,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) > > case CPTK_IS_STD_LAYOUT: > > case CPTK_IS_TRIVIAL: > > case CPTK_IS_TRIVIALLY_COPYABLE: > > + case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: > > if (!check_trait_type (type1, /* kind = */ 2)) > > return error_mark_node; > > break; > > diff --git a/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C b/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C > > new file mode 100644 > > index 00000000000..d6949dc7005 > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C > > @@ -0,0 +1,16 @@ > > +// PR c++/115476 > > +// { dg-do compile { target c++11 } } > > + > > +struct X; > > +static_assert(__has_unique_object_representations(X), ""); // { dg-error "invalid use of incomplete type" } > > +static_assert(__has_unique_object_representations(X[]), ""); // { dg-error "invalid use of incomplete type" } > > +static_assert(__has_unique_object_representations(X[1]), ""); // { dg-error "invalid use of incomplete type" } > > +static_assert(__has_unique_object_representations(X[][1]), ""); // { dg-error "invalid use of incomplete type" } > > + > > +struct X { > > + int x; > > +}; > > +static_assert(__has_unique_object_representations(X), ""); > > +static_assert(__has_unique_object_representations(X[]), ""); > > +static_assert(__has_unique_object_representations(X[1]), ""); > > +static_assert(__has_unique_object_representations(X[][1]), ""); > > > > base-commit: 7f9be55a4630134a237219af9cc8143e02080380 >
On 6/25/24 07:15, Jonathan Wakely wrote: > On Tue, 25 Jun 2024 at 03:12, Jason Merrill <jason@redhat.com> wrote: >> >> On 6/18/24 10:31, Marek Polacek wrote: >>> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14/13? >> >> Makes sense to me, though probably the [meta.unary.prop] table should be >> adjusted in the same way. Jonathan, what do you think? > > Just to make sure I understand correctly, the suggestion is to change > the precondition for the trait to something like: > > "remove_all_extents_t<T> shall be a complete type or cv void." > > i.e. if T is incomplete then T[] cannot be used with the trait, right? Yes. Jason >> >>> -- >8 -- >>> Here we started to ICE with r13-25: in check_trait_type, for "X[]" we >>> return true here: >>> >>> if (kind == 1 && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) >>> return true; // Array of unknown bound. Don't care about completeness. >>> >>> and then end up crashing in record_has_unique_obj_representations: >>> >>> 4836 if (cur != wi::to_offset (sz)) >>> >>> because sz is null. >>> >>> https://eel.is/c++draft/type.traits#tab:meta.unary.prop-row-47-column-3-sentence-1 >>> says that the preconditions for __has_unique_object_representations are: >>> "T shall be a complete type, cv void, or an array of unknown bound" and >>> that "For an array type T, the same result as >>> has_unique_object_representations_v<remove_all_extents_t<T>>" so T[] >>> should be treated as T. So we should use kind==2 for the trait. >>> >>> PR c++/115476 >>> >>> gcc/cp/ChangeLog: >>> >>> * semantics.cc (finish_trait_expr) >>> <case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS>: Move below to call >>> check_trait_type with kind==2. >>> >>> gcc/testsuite/ChangeLog: >>> >>> * g++.dg/cpp1z/has-unique-obj-representations4.C: New test. >>> --- >>> gcc/cp/semantics.cc | 2 +- >>> .../cpp1z/has-unique-obj-representations4.C | 16 ++++++++++++++++ >>> 2 files changed, 17 insertions(+), 1 deletion(-) >>> create mode 100644 gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C >>> >>> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc >>> index 08f5f245e7d..42251b6764b 100644 >>> --- a/gcc/cp/semantics.cc >>> +++ b/gcc/cp/semantics.cc >>> @@ -12966,7 +12966,6 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) >>> case CPTK_HAS_NOTHROW_COPY: >>> case CPTK_HAS_TRIVIAL_COPY: >>> case CPTK_HAS_TRIVIAL_DESTRUCTOR: >>> - case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: >>> if (!check_trait_type (type1)) >>> return error_mark_node; >>> break; >>> @@ -12976,6 +12975,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) >>> case CPTK_IS_STD_LAYOUT: >>> case CPTK_IS_TRIVIAL: >>> case CPTK_IS_TRIVIALLY_COPYABLE: >>> + case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: >>> if (!check_trait_type (type1, /* kind = */ 2)) >>> return error_mark_node; >>> break; >>> diff --git a/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C b/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C >>> new file mode 100644 >>> index 00000000000..d6949dc7005 >>> --- /dev/null >>> +++ b/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C >>> @@ -0,0 +1,16 @@ >>> +// PR c++/115476 >>> +// { dg-do compile { target c++11 } } >>> + >>> +struct X; >>> +static_assert(__has_unique_object_representations(X), ""); // { dg-error "invalid use of incomplete type" } >>> +static_assert(__has_unique_object_representations(X[]), ""); // { dg-error "invalid use of incomplete type" } >>> +static_assert(__has_unique_object_representations(X[1]), ""); // { dg-error "invalid use of incomplete type" } >>> +static_assert(__has_unique_object_representations(X[][1]), ""); // { dg-error "invalid use of incomplete type" } >>> + >>> +struct X { >>> + int x; >>> +}; >>> +static_assert(__has_unique_object_representations(X), ""); >>> +static_assert(__has_unique_object_representations(X[]), ""); >>> +static_assert(__has_unique_object_representations(X[1]), ""); >>> +static_assert(__has_unique_object_representations(X[][1]), ""); >>> >>> base-commit: 7f9be55a4630134a237219af9cc8143e02080380 >> >
On Tue, 25 Jun 2024 at 16:17, Jason Merrill <jason@redhat.com> wrote: > > On 6/25/24 07:15, Jonathan Wakely wrote: > > On Tue, 25 Jun 2024 at 03:12, Jason Merrill <jason@redhat.com> wrote: > >> > >> On 6/18/24 10:31, Marek Polacek wrote: > >>> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14/13? > >> > >> Makes sense to me, though probably the [meta.unary.prop] table should be > >> adjusted in the same way. Jonathan, what do you think? > > > > Just to make sure I understand correctly, the suggestion is to change > > the precondition for the trait to something like: > > > > "remove_all_extents_t<T> shall be a complete type or cv void." > > > > i.e. if T is incomplete then T[] cannot be used with the trait, right? > > Yes. Thanks. This is now https://cplusplus.github.io/LWG/issue4113
On Tue, Jun 25, 2024 at 06:22:56PM +0100, Jonathan Wakely wrote: > On Tue, 25 Jun 2024 at 16:17, Jason Merrill <jason@redhat.com> wrote: > > > > On 6/25/24 07:15, Jonathan Wakely wrote: > > > On Tue, 25 Jun 2024 at 03:12, Jason Merrill <jason@redhat.com> wrote: > > >> > > >> On 6/18/24 10:31, Marek Polacek wrote: > > >>> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14/13? > > >> > > >> Makes sense to me, though probably the [meta.unary.prop] table should be > > >> adjusted in the same way. Jonathan, what do you think? > > > > > > Just to make sure I understand correctly, the suggestion is to change > > > the precondition for the trait to something like: > > > > > > "remove_all_extents_t<T> shall be a complete type or cv void." > > > > > > i.e. if T is incomplete then T[] cannot be used with the trait, right? > > > > Yes. > > Thanks. This is now https://cplusplus.github.io/LWG/issue4113 Looks good. Should I push my patch now? Marek
On 6/25/24 15:07, Marek Polacek wrote: > On Tue, Jun 25, 2024 at 06:22:56PM +0100, Jonathan Wakely wrote: >> On Tue, 25 Jun 2024 at 16:17, Jason Merrill <jason@redhat.com> wrote: >>> >>> On 6/25/24 07:15, Jonathan Wakely wrote: >>>> On Tue, 25 Jun 2024 at 03:12, Jason Merrill <jason@redhat.com> wrote: >>>>> >>>>> On 6/18/24 10:31, Marek Polacek wrote: >>>>>> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14/13? >>>>> >>>>> Makes sense to me, though probably the [meta.unary.prop] table should be >>>>> adjusted in the same way. Jonathan, what do you think? >>>> >>>> Just to make sure I understand correctly, the suggestion is to change >>>> the precondition for the trait to something like: >>>> >>>> "remove_all_extents_t<T> shall be a complete type or cv void." >>>> >>>> i.e. if T is incomplete then T[] cannot be used with the trait, right? >>> >>> Yes. >> >> Thanks. This is now https://cplusplus.github.io/LWG/issue4113 > > Looks good. Should I push my patch now? Yes, please. Jason
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 08f5f245e7d..42251b6764b 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -12966,7 +12966,6 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) case CPTK_HAS_NOTHROW_COPY: case CPTK_HAS_TRIVIAL_COPY: case CPTK_HAS_TRIVIAL_DESTRUCTOR: - case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: if (!check_trait_type (type1)) return error_mark_node; break; @@ -12976,6 +12975,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_STD_LAYOUT: case CPTK_IS_TRIVIAL: case CPTK_IS_TRIVIALLY_COPYABLE: + case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: if (!check_trait_type (type1, /* kind = */ 2)) return error_mark_node; break; diff --git a/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C b/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C new file mode 100644 index 00000000000..d6949dc7005 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations4.C @@ -0,0 +1,16 @@ +// PR c++/115476 +// { dg-do compile { target c++11 } } + +struct X; +static_assert(__has_unique_object_representations(X), ""); // { dg-error "invalid use of incomplete type" } +static_assert(__has_unique_object_representations(X[]), ""); // { dg-error "invalid use of incomplete type" } +static_assert(__has_unique_object_representations(X[1]), ""); // { dg-error "invalid use of incomplete type" } +static_assert(__has_unique_object_representations(X[][1]), ""); // { dg-error "invalid use of incomplete type" } + +struct X { + int x; +}; +static_assert(__has_unique_object_representations(X), ""); +static_assert(__has_unique_object_representations(X[]), ""); +static_assert(__has_unique_object_representations(X[1]), ""); +static_assert(__has_unique_object_representations(X[][1]), "");