]> gcc.gnu.org Git - gcc.git/commitdiff
c++: traits, array of unknown bound of incomplete
authorJason Merrill <jason@redhat.com>
Wed, 23 Mar 2022 16:25:18 +0000 (12:25 -0400)
committerJason Merrill <jason@redhat.com>
Fri, 29 Apr 2022 03:02:11 +0000 (23:02 -0400)
My r161129 changed check_trait_type to reject arrays of unknown bound of
incomplete type, but I can't find a rationale for that, and now think it's
wrong: the standard just requires that the type be "complete, cv void, or an
array of unknown bound."  I imagine that allowing arrays of unknown bound is
because an array of unknown bound can't change from incomplete to complete
later in the translation unit, so there's no caching problem.

gcc/cp/ChangeLog:

* semantics.cc (check_trait_type): Don't check completeness
of element type of array of unknown bound.

gcc/testsuite/ChangeLog:

* g++.dg/ext/unary_trait_incomplete.C: Adjust.

gcc/cp/semantics.cc
gcc/testsuite/g++.dg/ext/unary_trait_incomplete.C

index 9567559c96220745d8025083fb8f5124dcf3e5e2..377f61113c0d3d915c7db05d71376a63073a1a75 100644 (file)
@@ -11978,8 +11978,7 @@ check_trait_type (tree type)
     return (check_trait_type (TREE_VALUE (type))
            && check_trait_type (TREE_CHAIN (type)));
 
-  if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)
-      && COMPLETE_TYPE_P (TREE_TYPE (type)))
+  if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
     return true;
 
   if (VOID_TYPE_P (type))
index b60ce84dcb2323396338f58c445d68ed1c121bbd..6c83279c030f73891fe891a470f5ddbe57ce4218 100644 (file)
@@ -5,72 +5,72 @@ struct C { };
 
 bool nas1 = __has_nothrow_assign(I); // { dg-error "incomplete type" }
 bool nas2 = __has_nothrow_assign(C[]);
-bool nas3 = __has_nothrow_assign(I[]); // { dg-error "incomplete type" }
+bool nas3 = __has_nothrow_assign(I[]);
 bool nas4 = __has_nothrow_assign(void);
 bool nas5 = __has_nothrow_assign(const void);
 
 bool tas1 = __has_trivial_assign(I); // { dg-error "incomplete type" }
 bool tas2 = __has_trivial_assign(C[]);
-bool tas3 = __has_trivial_assign(I[]); // { dg-error "incomplete type" }
+bool tas3 = __has_trivial_assign(I[]);
 bool tas4 = __has_trivial_assign(void);
 bool tas5 = __has_trivial_assign(const void);
 
 bool nco1 = __has_nothrow_constructor(I); // { dg-error "incomplete type" }
 bool nco2 = __has_nothrow_constructor(C[]);
-bool nco3 = __has_nothrow_constructor(I[]); // { dg-error "incomplete type" }
+bool nco3 = __has_nothrow_constructor(I[]);
 bool nco4 = __has_nothrow_constructor(void);
 bool nco5 = __has_nothrow_constructor(const void);
 
 bool tco1 = __has_trivial_constructor(I); // { dg-error "incomplete type" }
 bool tco2 = __has_trivial_constructor(C[]);
-bool tco3 = __has_trivial_constructor(I[]); // { dg-error "incomplete type" }
+bool tco3 = __has_trivial_constructor(I[]);
 bool tco4 = __has_trivial_constructor(void);
 bool tco5 = __has_trivial_constructor(const void);
 
 bool ncp1 = __has_nothrow_copy(I); // { dg-error "incomplete type" }
 bool ncp2 = __has_nothrow_copy(C[]);
-bool ncp3 = __has_nothrow_copy(I[]); // { dg-error "incomplete type" }
+bool ncp3 = __has_nothrow_copy(I[]);
 bool ncp4 = __has_nothrow_copy(void);
 bool ncp5 = __has_nothrow_copy(const void);
 
 bool tcp1 = __has_trivial_copy(I); // { dg-error "incomplete type" }
 bool tcp2 = __has_trivial_copy(C[]);
-bool tcp3 = __has_trivial_copy(I[]); // { dg-error "incomplete type" }
+bool tcp3 = __has_trivial_copy(I[]);
 bool tcp4 = __has_trivial_copy(void);
 bool tcp5 = __has_trivial_copy(const void);
 
 bool vde1 = __has_virtual_destructor(I); // { dg-error "incomplete type" }
 bool vde2 = __has_virtual_destructor(C[]);
-bool vde3 = __has_virtual_destructor(I[]); // { dg-error "incomplete type" }
+bool vde3 = __has_virtual_destructor(I[]);
 bool vde4 = __has_virtual_destructor(void);
 bool vde5 = __has_virtual_destructor(const void);
 
 bool tde1 = __has_trivial_destructor(I); // { dg-error "incomplete type" }
 bool tde2 = __has_trivial_destructor(C[]);
-bool tde3 = __has_trivial_destructor(I[]); // { dg-error "incomplete type" }
+bool tde3 = __has_trivial_destructor(I[]);
 bool tde4 = __has_trivial_destructor(void);
 bool tde5 = __has_trivial_destructor(const void);
 
 bool abs1 = __is_abstract(I); // { dg-error "incomplete type" }
 bool abs2 = __is_abstract(C[]);
-bool abs3 = __is_abstract(I[]); // { dg-error "incomplete type" }
+bool abs3 = __is_abstract(I[]);
 bool abs4 = __is_abstract(void);
 bool abs5 = __is_abstract(const void);
 
 bool pod1 = __is_pod(I); // { dg-error "incomplete type" }
 bool pod2 = __is_pod(C[]);
-bool pod3 = __is_pod(I[]); // { dg-error "incomplete type" }
+bool pod3 = __is_pod(I[]);
 bool pod4 = __is_pod(void);
 bool pod5 = __is_pod(const void);
 
 bool emp1 = __is_empty(I); // { dg-error "incomplete type" }
 bool emp2 = __is_empty(C[]);
-bool emp3 = __is_empty(I[]); // { dg-error "incomplete type" }
+bool emp3 = __is_empty(I[]);
 bool emp4 = __is_empty(void);
 bool emp5 = __is_empty(const void);
 
 bool pol1 = __is_polymorphic(I); // { dg-error "incomplete type" }
 bool pol2 = __is_polymorphic(C[]);
-bool pol3 = __is_polymorphic(I[]); // { dg-error "incomplete type" }
+bool pol3 = __is_polymorphic(I[]);
 bool pol4 = __is_polymorphic(void);
 bool pol5 = __is_polymorphic(const void);
This page took 0.080186 seconds and 5 git commands to generate.