From: Steve Naroff Date: Thu, 4 Sep 2008 16:56:14 +0000 (+0000) Subject: Touchup CheckSingleAssignmentConstraints() and CheckCompareOperands() to check for... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=39218dfef550ad1cd7b7ece83a715996a113ffd1;p=clang Touchup CheckSingleAssignmentConstraints() and CheckCompareOperands() to check for block pointers. Added a couple FIXME's wrt PointLikeType. If the author reads this, it would be great to get some background on this class (thanks in advance). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55778 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index b3fefb265e..3eb28a86c0 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -530,6 +530,9 @@ protected: }; /// PointerLikeType - Common base class for pointers and references. +/// FIXME: Add more documentation on this classes design point. For example, +/// should BlockPointerType inherit from it? Is the concept of a PointerLikeType +/// in the C++ standard? /// class PointerLikeType : public Type { QualType PointeeType; @@ -577,6 +580,9 @@ protected: /// BlockPointerType - pointer to a block type. /// This type is to represent types syntactically represented as /// "void (^)(int)", etc. Pointee is required to always be a function type. +/// FIXME: Should BlockPointerType inherit from PointerLikeType? It could +/// simplfy some type checking code, however PointerLikeType doesn't appear +/// to be used by the type checker. /// class BlockPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; // Block is some kind of pointer type diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 37172cbf0d..02169e6db8 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1578,7 +1578,8 @@ Sema::AssignConvertType Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) { // C99 6.5.16.1p1: the left operand is a pointer and the right is // a null pointer constant. - if ((lhsType->isPointerType() || lhsType->isObjCQualifiedIdType()) + if ((lhsType->isPointerType() || lhsType->isObjCQualifiedIdType() || + lhsType->isBlockPointerType()) && rExpr->isNullPointerConstant(Context)) { ImpCastExprToType(rExpr, lhsType); return Compatible; @@ -1944,6 +1945,23 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation loc, ImpCastExprToType(lex, rType); // promote the integer to pointer return Context.IntTy; } + // Handle block pointers. + if (lType->isBlockPointerType() && rType->isIntegerType()) { + if (!RHSIsNull) + Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer, + lType.getAsString(), rType.getAsString(), + lex->getSourceRange(), rex->getSourceRange()); + ImpCastExprToType(rex, lType); // promote the integer to pointer + return Context.IntTy; + } + if (lType->isIntegerType() && rType->isBlockPointerType()) { + if (!LHSIsNull) + Diag(loc, diag::ext_typecheck_comparison_of_pointer_integer, + lType.getAsString(), rType.getAsString(), + lex->getSourceRange(), rex->getSourceRange()); + ImpCastExprToType(lex, rType); // promote the integer to pointer + return Context.IntTy; + } return InvalidOperands(loc, lex, rex); }