diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2008-05-18 18:08:51 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2008-05-18 18:08:51 +0000 |
commit | 8e12298192a5221e2819b0fb78b4962a035f2188 (patch) | |
tree | 009a2ba7a8ab05d0036fb735a24ec2373e889194 /clang/lib/Sema/SemaExpr.cpp | |
parent | e2846b6929a10a7eb81430aa0b3886cf0c7e022b (diff) | |
download | bcm5719-llvm-8e12298192a5221e2819b0fb78b4962a035f2188.tar.gz bcm5719-llvm-8e12298192a5221e2819b0fb78b4962a035f2188.zip |
Add proper type-checking for pointer additiion; before, we were accepting
addition with a pointer and an integer even when it didn't make sense.
llvm-svn: 51228
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6132dfddbac..e5ac14e092c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1405,15 +1405,33 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6 return CheckVectorOperands(loc, lex, rex); QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign); - + // handle the common case first (both operands are arithmetic). if (lex->getType()->isArithmeticType() && rex->getType()->isArithmeticType()) return compType; - if (lex->getType()->isPointerType() && rex->getType()->isIntegerType()) - return lex->getType(); - if (lex->getType()->isIntegerType() && rex->getType()->isPointerType()) - return rex->getType(); + // Put any potential pointer into PExp + Expr* PExp = lex, *IExp = rex; + if (IExp->getType()->isPointerType()) + std::swap(PExp, IExp); + + if (const PointerType* PTy = PExp->getType()->getAsPointerType()) { + if (IExp->getType()->isIntegerType()) { + // Check for arithmetic on pointers to incomplete types + if (!PTy->getPointeeType()->isObjectType()) { + if (PTy->getPointeeType()->isVoidType()) { + Diag(loc, diag::ext_gnu_void_ptr, + lex->getSourceRange(), rex->getSourceRange()); + } else { + Diag(loc, diag::err_typecheck_arithmetic_incomplete_type, + lex->getType().getAsString(), lex->getSourceRange()); + return QualType(); + } + } + return PExp->getType(); + } + } + return InvalidOperands(loc, lex, rex); } @@ -1681,7 +1699,10 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc) { // C99 6.5.2.4p1: We allow complex as a GCC extension. if (const PointerType *pt = resType->getAsPointerType()) { - if (!pt->getPointeeType()->isObjectType()) { // C99 6.5.2.4p2, 6.5.6p2 + if (pt->getPointeeType()->isVoidType()) { + Diag(OpLoc, diag::ext_gnu_void_ptr, op->getSourceRange()); + } else if (!pt->getPointeeType()->isObjectType()) { + // C99 6.5.2.4p2, 6.5.6p2 Diag(OpLoc, diag::err_typecheck_arithmetic_incomplete_type, resType.getAsString(), op->getSourceRange()); return QualType(); |