aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/GRExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-04-08 03:07:17 +0000
committerTed Kremenek <kremenek@apple.com>2009-04-08 03:07:17 +0000
commit899b3de7bc32434fc406f35255cc828ba8372b3d (patch)
tree5daccbcf492df6d6147f7f170572e86de1caedd3 /lib/Analysis/GRExprEngine.cpp
parent9fd0b1f845a61e71dd8099f596532d34c519630a (diff)
New static analyzer check by Nikita Zhuk!
"The attached patch generates warnings of cases where an ObjC message is sent to a nil object and the size of return type of that message is larger than the size of void pointer. This may result in undefined return values as described in PR 2718. The patch also includes test cases." git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68585 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r--lib/Analysis/GRExprEngine.cpp48
1 files changed, 34 insertions, 14 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 487aac06c5..06d61cc4b0 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -1690,20 +1690,40 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
if (isFeasibleNull) {
// Check if the receiver was nil and the return value a struct.
- if (ME->getType()->isRecordType() &&
- BR.getParentMap().isConsumedExpr(ME)) {
- // The [0 ...] expressions will return garbage. Flag either an
- // explicit or implicit error. Because of the structure of this
- // function we currently do not bifurfacte the state graph at
- // this point.
- // FIXME: We should bifurcate and fill the returned struct with
- // garbage.
- if (NodeTy* N = Builder->generateNode(ME, StNull, Pred)) {
- N->markAsSink();
- if (isFeasibleNotNull)
- NilReceiverStructRetImplicit.insert(N);
- else
- NilReceiverStructRetExplicit.insert(N);
+ if (BR.getParentMap().isConsumedExpr(ME)) {
+ if(ME->getType()->isRecordType()) {
+ // The [0 ...] expressions will return garbage. Flag either an
+ // explicit or implicit error. Because of the structure of this
+ // function we currently do not bifurfacte the state graph at
+ // this point.
+ // FIXME: We should bifurcate and fill the returned struct with
+ // garbage.
+ if (NodeTy* N = Builder->generateNode(ME, StNull, Pred)) {
+ N->markAsSink();
+ if (isFeasibleNotNull)
+ NilReceiverStructRetImplicit.insert(N);
+ else
+ NilReceiverStructRetExplicit.insert(N);
+ }
+ }
+ else {
+ ASTContext& Ctx = getContext();
+
+ // sizeof(void *)
+ const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
+
+ // sizeof(return type)
+ const uint64_t returnTypeSize = Ctx.getTypeSize(ME->getType());
+
+ if(voidPtrSize < returnTypeSize) {
+ if (NodeTy* N = Builder->generateNode(ME, StNull, Pred)) {
+ N->markAsSink();
+ if(isFeasibleNotNull)
+ NilReceiverLargerThanVoidPtrRetImplicit.insert(N);
+ else
+ NilReceiverLargerThanVoidPtrRetExplicit.insert(N);
+ }
+ }
}
}
}