diff options
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 60 |
1 files changed, 41 insertions, 19 deletions
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<proto>) 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<proto>) 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; } |