]> granicus.if.org Git - clang/commitdiff
Switch the type-trait like APIs on the AST to only check for incomplete
authorChandler Carruth <chandlerc@gmail.com>
Sat, 30 Apr 2011 10:31:50 +0000 (10:31 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sat, 30 Apr 2011 10:31:50 +0000 (10:31 +0000)
types after looking through arrays. Arrays with an unknown bound seem to
be specifically allowed in the library type traits in C++0x, and GCC's
builtin __is_trivial returns 'true' for the type 'int[]'. Now Clang
agrees with GCC about __is_trivial here.

Also hardens these methods against dependent types by just returning false.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130605 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Type.cpp
test/SemaCXX/type-traits.cpp

index d359265090a65117ac00f62186ac048aa3da733e..ae52ff06faf7ebc3236ef84121a6b01af06a2f10 100644 (file)
@@ -869,7 +869,7 @@ bool Type::isPODType() const {
 }
 
 bool Type::isLiteralType() const {
-  if (isIncompleteType())
+  if (isDependentType())
     return false;
 
   // C++0x [basic.types]p10:
@@ -878,11 +878,16 @@ bool Type::isLiteralType() const {
   //   -- an array of literal type
   // Extension: variable arrays cannot be literal types, since they're
   // runtime-sized.
-  if (isArrayType() && !isConstantArrayType())
+  if (isVariableArrayType())
     return false;
   const Type *BaseTy = getBaseElementTypeUnsafe();
   assert(BaseTy && "NULL element type");
 
+  // Return false for incomplete types after skipping any incomplete array
+  // types; those are expressly allowed by the standard and thus our API.
+  if (BaseTy->isIncompleteType())
+    return false;
+
   // C++0x [basic.types]p10:
   //   A type is a literal type if it is:
   //    -- a scalar type; or
@@ -916,7 +921,7 @@ bool Type::isLiteralType() const {
 }
 
 bool Type::isTrivialType() const {
-  if (isIncompleteType())
+  if (isDependentType())
     return false;
 
   // C++0x [basic.types]p9:
@@ -925,6 +930,12 @@ bool Type::isTrivialType() const {
   //   types.
   const Type *BaseTy = getBaseElementTypeUnsafe();
   assert(BaseTy && "NULL element type");
+
+  // Return false for incomplete types after skipping any incomplete array
+  // types which are expressly allowed by the standard and thus our API.
+  if (BaseTy->isIncompleteType())
+    return false;
+
   if (BaseTy->isScalarType()) return true;
   if (const RecordType *RT = BaseTy->getAs<RecordType>()) {
     if (const CXXRecordDecl *ClassDecl =
@@ -944,7 +955,7 @@ bool Type::isTrivialType() const {
 }
 
 bool Type::isStandardLayoutType() const {
-  if (isIncompleteType())
+  if (isDependentType())
     return false;
 
   // C++0x [basic.types]p9:
@@ -953,6 +964,12 @@ bool Type::isStandardLayoutType() const {
   //   standard-layout types.
   const Type *BaseTy = getBaseElementTypeUnsafe();
   assert(BaseTy && "NULL element type");
+
+  // Return false for incomplete types after skipping any incomplete array
+  // types which are expressly allowed by the standard and thus our API.
+  if (BaseTy->isIncompleteType())
+    return false;
+
   if (BaseTy->isScalarType()) return true;
   if (const RecordType *RT = BaseTy->getAs<RecordType>()) {
     if (const CXXRecordDecl *ClassDecl =
@@ -974,7 +991,7 @@ bool Type::isStandardLayoutType() const {
 // isStandardLayoutType. We implement it dircetly to avoid redundant
 // conversions from a type to a CXXRecordDecl.
 bool Type::isCXX11PODType() const {
-  if (isIncompleteType())
+  if (isDependentType())
     return false;
 
   // C++11 [basic.types]p9:
@@ -982,6 +999,12 @@ bool Type::isCXX11PODType() const {
   //   versions of these types are collectively called trivial types.
   const Type *BaseTy = getBaseElementTypeUnsafe();
   assert(BaseTy && "NULL element type");
+
+  // Return false for incomplete types after skipping any incomplete array
+  // types which are expressly allowed by the standard and thus our API.
+  if (BaseTy->isIncompleteType())
+    return false;
+
   if (BaseTy->isScalarType()) return true;
   if (const RecordType *RT = BaseTy->getAs<RecordType>()) {
     if (const CXXRecordDecl *ClassDecl =
index 1dec7f923a5857dc20c5b4593f536d255ffc0a10..c45adecf66568cc1149cb368101ee1a932735318 100644 (file)
@@ -1429,12 +1429,14 @@ void is_trivial()
   { int arr[T(__is_trivial(POD))]; }
   { int arr[T(__is_trivial(Int))]; }
   { int arr[T(__is_trivial(IntAr))]; }
+  { int arr[T(__is_trivial(IntArNB))]; }
   { int arr[T(__is_trivial(Statics))]; }
   { int arr[T(__is_trivial(Empty))]; }
   { int arr[T(__is_trivial(EmptyUnion))]; }
   { int arr[T(__is_trivial(Union))]; }
   { int arr[T(__is_trivial(Derives))]; }
   { int arr[T(__is_trivial(DerivesAr))]; }
+  { int arr[T(__is_trivial(DerivesArNB))]; }
   { int arr[T(__is_trivial(DerivesEmpty))]; }
   { int arr[T(__is_trivial(HasFunc))]; }
   { int arr[T(__is_trivial(HasOp))]; }
@@ -1459,8 +1461,6 @@ void is_trivial()
   { int arr[F(__is_trivial(DerivesHasDest))]; }
   { int arr[F(__is_trivial(DerivesHasRef))]; }
   { int arr[F(__is_trivial(DerivesHasVirt))]; }
-  { int arr[F(__is_trivial(IntArNB))]; }
-  { int arr[F(__is_trivial(DerivesArNB))]; }
   { int arr[F(__is_trivial(void))]; }
   { int arr[F(__is_trivial(cvoid))]; }
 }