This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ Patch] Fix PR 39475


Hi,
> This is OK in principle, but this comment:
>
> + /* Checks that a type fulfills the preconditions in Table 33.  */
>
> This should explicitly reference TYPE and should quote the appropriate
> bits of the standard -- or paraphrase them -- rather than referring to
> Table 33.
>   
Agreed. The below is what I'm going to commit.

Thanks,
Paolo.

////////////
Index: testsuite/g++.dg/ext/unary_trait_incomplete.C
===================================================================
*** testsuite/g++.dg/ext/unary_trait_incomplete.C	(revision 0)
--- testsuite/g++.dg/ext/unary_trait_incomplete.C	(revision 0)
***************
*** 0 ****
--- 1,76 ----
+ // PR c++/39475
+ 
+ struct I;
+ struct C { };
+ 
+ bool nas1 = __has_nothrow_assign(I); // { dg-error "incomplete type" }
+ bool nas2 = __has_nothrow_assign(C[]);
+ 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[]);
+ 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[]);
+ 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[]);
+ 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[]);
+ 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[]);
+ 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[]);
+ 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[]);
+ 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[]);
+ 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[]);
+ 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[]);
+ 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[]);
+ bool pol4 = __is_polymorphic(void);
+ bool pol5 = __is_polymorphic(const void);
Index: cp/semantics.c
===================================================================
*** cp/semantics.c	(revision 144907)
--- cp/semantics.c	(working copy)
*************** trait_expr_value (cp_trait_kind kind, tr
*** 4902,4907 ****
--- 4902,4925 ----
      }
  }
  
+ /* Returns true if TYPE is a complete type, an array of unknown bound,
+    or (possibly cv-qualified) void, returns false otherwise.  */
+ 
+ static bool
+ check_trait_type (tree type)
+ {
+   if (COMPLETE_TYPE_P (type))
+     return true;
+ 
+   if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
+     return true;
+ 
+   if (VOID_TYPE_P (type))
+     return true;
+ 
+   return false;
+ }
+ 
  /* Process a trait expression.  */
  
  tree
*************** finish_trait_expr (cp_trait_kind kind, t
*** 4950,4963 ****
    if (type2)
      complete_type (type2);
  
!   /* The only required diagnostic.  */
!   if (kind == CPTK_IS_BASE_OF
!       && NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
!       && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
!       && !COMPLETE_TYPE_P (type2))
      {
!       error ("incomplete type %qT not allowed", type2);
!       return error_mark_node;
      }
  
    return (trait_expr_value (kind, type1, type2)
--- 4968,5012 ----
    if (type2)
      complete_type (type2);
  
!   switch (kind)
      {
!     case CPTK_HAS_NOTHROW_ASSIGN:
!     case CPTK_HAS_TRIVIAL_ASSIGN:
!     case CPTK_HAS_NOTHROW_CONSTRUCTOR:
!     case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
!     case CPTK_HAS_NOTHROW_COPY:
!     case CPTK_HAS_TRIVIAL_COPY:
!     case CPTK_HAS_TRIVIAL_DESTRUCTOR:
!     case CPTK_HAS_VIRTUAL_DESTRUCTOR:
!     case CPTK_IS_ABSTRACT:
!     case CPTK_IS_EMPTY:
!     case CPTK_IS_POD:
!     case CPTK_IS_POLYMORPHIC:
!       if (!check_trait_type (type1))
! 	{
! 	  error ("incomplete type %qT not allowed", type1);
! 	  return error_mark_node;
! 	}
!       break;
! 
!     case CPTK_IS_BASE_OF:
!       if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
! 	  && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
! 	  && !COMPLETE_TYPE_P (type2))
! 	{
! 	  error ("incomplete type %qT not allowed", type2);
! 	  return error_mark_node;
! 	}
!       break;
! 
!     case CPTK_IS_CLASS:
!     case CPTK_IS_ENUM:
!     case CPTK_IS_UNION:
!       break;
!     
!     case CPTK_IS_CONVERTIBLE_TO:
!     default:
!       gcc_unreachable ();
      }
  
    return (trait_expr_value (kind, type1, type2)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]