From: Chandler Carruth Date: Thu, 26 May 2011 08:53:16 +0000 (+0000) Subject: Extract two more methods from the unary type trait checking. These X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=42ec65df778ec3faa7a7fb73caa2bca2422a0e67;p=clang Extract two more methods from the unary type trait checking. These provide re-usable forms of the rest of the custom validation done here. Still no functionality changed here. With this it should be possible to have an expression-centric code path and a type-centric code path which don't duplicate logic. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132118 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 37ad6a8bfb..b89e2bcc80 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3072,6 +3072,42 @@ static bool CheckVecStepTraitOperandType(Sema &S, QualType T, return false; } +static bool CheckExtensionTraitOperandType(Sema &S, QualType T, + SourceLocation Loc, + SourceRange ArgRange, + UnaryExprOrTypeTrait TraitKind) { + // C99 6.5.3.4p1: + if (T->isFunctionType()) { + // alignof(function) is allowed as an extension. + if (TraitKind == UETT_SizeOf) + S.Diag(Loc, diag::ext_sizeof_function_type) << ArgRange; + return false; + } + + // Allow sizeof(void)/alignof(void) as an extension. + if (T->isVoidType()) { + S.Diag(Loc, diag::ext_sizeof_void_type) << TraitKind << ArgRange; + return false; + } + + return true; +} + +static bool CheckObjCTraitOperandConstraints(Sema &S, QualType T, + SourceLocation Loc, + SourceRange ArgRange, + UnaryExprOrTypeTrait TraitKind) { + // Reject sizeof(interface) and sizeof(interface) in 64-bit mode. + if (S.LangOpts.ObjCNonFragileABI && T->isObjCObjectType()) { + S.Diag(Loc, diag::err_sizeof_nonfragile_interface) + << T << (TraitKind == UETT_SizeOf) + << ArgRange; + return true; + } + + return false; +} + /// \brief Check the constrains on expression operands to unary type expression /// and type traits. /// @@ -3117,33 +3153,19 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType exprType, if (ExprKind == UETT_VecStep) return CheckVecStepTraitOperandType(*this, exprType, OpLoc, ExprRange); - // C99 6.5.3.4p1: - if (exprType->isFunctionType()) { - // alignof(function) is allowed as an extension. - if (ExprKind == UETT_SizeOf) - Diag(OpLoc, diag::ext_sizeof_function_type) - << ExprRange; - return false; - } - - // Allow sizeof(void)/alignof(void) as an extension. - if (exprType->isVoidType()) { - Diag(OpLoc, diag::ext_sizeof_void_type) << ExprKind << ExprRange; + // Whitelist some types as extensions + if (!CheckExtensionTraitOperandType(*this, exprType, OpLoc, ExprRange, + ExprKind)) return false; - } if (RequireCompleteType(OpLoc, exprType, PDiag(diag::err_sizeof_alignof_incomplete_type) << ExprKind << ExprRange)) return true; - // Reject sizeof(interface) and sizeof(interface) in 64-bit mode. - if (LangOpts.ObjCNonFragileABI && exprType->isObjCObjectType()) { - Diag(OpLoc, diag::err_sizeof_nonfragile_interface) - << exprType << (ExprKind == UETT_SizeOf) - << ExprRange; + if (CheckObjCTraitOperandConstraints(*this, exprType, OpLoc, ExprRange, + ExprKind)) return true; - } return false; }