aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-05-26 08:53:16 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-05-26 08:53:16 +0000
commit42ec65df778ec3faa7a7fb73caa2bca2422a0e67 (patch)
treea43c5bf8d84c280e0cee0114ca900360903352ea /lib/Sema/SemaExpr.cpp
parente2250304ca0a809693a48f84b7e886f55d004df4 (diff)
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
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp60
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;
}