summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorJordy Rose <jediknil@belkadan.com>2010-07-05 04:42:43 +0000
committerJordy Rose <jediknil@belkadan.com>2010-07-05 04:42:43 +0000
commit0704a7fe4311ec3a097a49cfeb73b8746a5650d0 (patch)
tree6b90d5cf4ceb42cd4c380fd6d309cebbcc2021b8 /clang
parent6d60a1425101dfa0d9073fc4c33cb8d93d27fafb (diff)
downloadbcm5719-llvm-0704a7fe4311ec3a097a49cfeb73b8746a5650d0.tar.gz
bcm5719-llvm-0704a7fe4311ec3a097a49cfeb73b8746a5650d0.zip
Support sizeof for VLA expressions (sizeof(someVLA)). sizeof(int[n]) still unimplemented. A VLA region's sizeof value matches its extent.
llvm-svn: 107611
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Checker/GRExprEngine.cpp35
-rw-r--r--clang/test/Analysis/outofbound.c9
2 files changed, 41 insertions, 3 deletions
diff --git a/clang/lib/Checker/GRExprEngine.cpp b/clang/lib/Checker/GRExprEngine.cpp
index 89b123d1bbe..e5c9bb9eb5b 100644
--- a/clang/lib/Checker/GRExprEngine.cpp
+++ b/clang/lib/Checker/GRExprEngine.cpp
@@ -2696,9 +2696,38 @@ void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex,
// sizeof(void) == 1 byte.
amt = CharUnits::One();
}
- else if (!T.getTypePtr()->isConstantSizeType()) {
- // FIXME: Add support for VLAs.
- Dst.Add(Pred);
+ else if (!T->isConstantSizeType()) {
+ assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
+
+ // FIXME: Add support for VLA type arguments, not just VLA expressions.
+ // When that happens, we should probably refactor VLASizeChecker's code.
+ if (Ex->isArgumentType()) {
+ Dst.Add(Pred);
+ return;
+ }
+
+ // Get the size by getting the extent of the sub-expression.
+ // First, visit the sub-expression to find its region.
+ Expr *Arg = Ex->getArgumentExpr();
+ ExplodedNodeSet Tmp;
+ VisitLValue(Arg, Pred, Tmp);
+
+ for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
+ const GRState* state = GetState(*I);
+ const MemRegion *MR = state->getSVal(Arg).getAsRegion();
+
+ // If the subexpression can't be resolved to a region, we don't know
+ // anything about its size. Just leave the state as is and continue.
+ if (!MR) {
+ Dst.Add(*I);
+ continue;
+ }
+
+ // The result is the extent of the VLA.
+ SVal Extent = cast<SubRegion>(MR)->getExtent(ValMgr);
+ MakeNode(Dst, Ex, *I, state->BindExpr(Ex, Extent));
+ }
+
return;
}
else if (T->getAs<ObjCObjectType>()) {
diff --git a/clang/test/Analysis/outofbound.c b/clang/test/Analysis/outofbound.c
index 8ffb3e1efbf..9b487300c88 100644
--- a/clang/test/Analysis/outofbound.c
+++ b/clang/test/Analysis/outofbound.c
@@ -62,3 +62,12 @@ void vla(int a) {
x[5] = 5; // expected-warning{{out-of-bound}}
}
}
+
+void sizeof_vla(int a) {
+ if (a == 5) {
+ char x[a];
+ int y[sizeof(x)];
+ y[4] = 4; // no-warning
+ y[5] = 5; // expected-warning{{out-of-bound}}
+ }
+}
OpenPOWER on IntegriCloud