https://gcc.gnu.org/g:b0426fbc85333775ef97cc135e87dd6cae876af7

commit r13-9291-gb0426fbc85333775ef97cc135e87dd6cae876af7
Author: Marek Polacek <pola...@redhat.com>
Date:   Mon Jun 17 17:53:12 2024 -0400

    c++: ICE with __has_unique_object_representations [PR115476]
    
    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.
    
    (cherry picked from commit c314867fc06d475e3c2ace32032e0d72e3915b55)

Diff:
---
 gcc/cp/semantics.cc                                      |  2 +-
 .../g++.dg/cpp1z/has-unique-obj-representations4.C       | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 079ad5c93bf1..886186403691 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12246,7 +12246,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;
@@ -12256,6 +12255,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 000000000000..d6949dc7005e
--- /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]), "");

Reply via email to