From: John Wiegley Date: Thu, 28 Apr 2011 02:06:46 +0000 (+0000) Subject: A few corrections to type traits that missed the last checkin X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cf5664114eb75c6a5fef2bed1c0f0d0fb19debc9;p=clang A few corrections to type traits that missed the last checkin git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130371 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 6c8471b363..e62a59831b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3335,6 +3335,10 @@ def warn_unused_call : Warning< def err_incomplete_type_used_in_type_trait_expr : Error< "incomplete type %0 used in type trait expression">; +def err_dependent_type_used_in_type_trait_expr : Error< + "dependent type %0 used in type trait expression">; +def err_dimension_expr_not_constant_integer : Error< + "dimension expression does not evaluate to a constant unsigned int">; def err_expected_ident_or_lparen : Error<"expected identifier or '('">; def err_typecheck_cond_incompatible_operands_null : Error< diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 0617abd680..55a396ec34 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2355,8 +2355,12 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T, SourceLocation KeyLoc) { // FIXME: For many of these traits, we need a complete type before we can // check these properties. - assert(!T->isDependentType() && - "Cannot evaluate traits for dependent types."); + + if (T->isDependentType()) { + Self.Diag(KeyLoc, diag::err_dependent_type_used_in_type_trait_expr) << T; + return false; + } + ASTContext &C = Self.Context; switch(UTT) { default: assert(false && "Unknown type trait or not implemented"); @@ -2653,7 +2657,16 @@ ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait UTT, QualType E = T; if (T->isIncompleteArrayType()) E = Context.getAsArrayType(T)->getElementType(); - if (!T->isVoidType() && ! LangOpts.Borland && + if (!T->isVoidType() && + (! LangOpts.Borland || + UTT == UTT_HasNothrowAssign || + UTT == UTT_HasNothrowCopy || + UTT == UTT_HasNothrowConstructor || + UTT == UTT_HasTrivialAssign || + UTT == UTT_HasTrivialCopy || + UTT == UTT_HasTrivialConstructor || + UTT == UTT_HasTrivialDestructor || + UTT == UTT_HasVirtualDestructor) && RequireCompleteType(KWLoc, E, diag::err_incomplete_type_used_in_type_trait_expr)) return ExprError(); @@ -2688,8 +2701,14 @@ ExprResult Sema::ActOnBinaryTypeTrait(BinaryTypeTrait BTT, static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT, QualType LhsT, QualType RhsT, SourceLocation KeyLoc) { - assert((!LhsT->isDependentType() || RhsT->isDependentType()) && - "Cannot evaluate traits for dependent types."); + if (LhsT->isDependentType()) { + Self.Diag(KeyLoc, diag::err_dependent_type_used_in_type_trait_expr) << LhsT; + return false; + } + else if (RhsT->isDependentType()) { + Self.Diag(KeyLoc, diag::err_dependent_type_used_in_type_trait_expr) << RhsT; + return false; + } switch(BTT) { case BTT_IsBaseOf: { @@ -2828,8 +2847,10 @@ ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT, static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT, QualType T, Expr *DimExpr, SourceLocation KeyLoc) { - assert((!T->isDependentType()) && - "Cannot evaluate traits for dependent types."); + if (T->isDependentType()) { + Self.Diag(KeyLoc, diag::err_dependent_type_used_in_type_trait_expr) << T; + return false; + } switch(ATT) { case ATT_ArrayRank: @@ -2840,16 +2861,24 @@ static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT, T = AT->getElementType(); } return Dim; - } else { - assert(! "Array type trait applied to non-array type"); } + return 0; + case ATT_ArrayExtent: { llvm::APSInt Value; uint64_t Dim; - if (DimExpr->isIntegerConstantExpr(Value, Self.Context, 0, false)) + if (DimExpr->isIntegerConstantExpr(Value, Self.Context, 0, false)) { + if (Value < llvm::APSInt(Value.getBitWidth(), Value.isUnsigned())) { + Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer) << + DimExpr->getSourceRange(); + return false; + } Dim = Value.getLimitedValue(); - else - assert(! "Dimension expression did not evaluate to a constant integer"); + } else { + Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer) << + DimExpr->getSourceRange(); + return false; + } if (T->isArrayType()) { unsigned D = 0; @@ -2863,14 +2892,12 @@ static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT, T = AT->getElementType(); } - assert(Matched && T->isArrayType() && - "__array_extent does not refer to an array dimension"); - - llvm::APInt size = Self.Context.getAsConstantArrayType(T)->getSize(); - return size.getLimitedValue(); - } else { - assert(! "Array type trait applied to non-array type"); + if (Matched && T->isArrayType()) { + if (const ConstantArrayType *CAT = Self.Context.getAsConstantArrayType(T)) + return CAT->getSize().getLimitedValue(); + } } + return 0; } } llvm_unreachable("Unknown type trait or not implemented");