diff options
author | Jordy Rose <jediknil@belkadan.com> | 2010-07-05 04:42:43 +0000 |
---|---|---|
committer | Jordy Rose <jediknil@belkadan.com> | 2010-07-05 04:42:43 +0000 |
commit | 0704a7fe4311ec3a097a49cfeb73b8746a5650d0 (patch) | |
tree | 6b90d5cf4ceb42cd4c380fd6d309cebbcc2021b8 /clang/lib/Checker | |
parent | 6d60a1425101dfa0d9073fc4c33cb8d93d27fafb (diff) | |
download | bcm5719-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/lib/Checker')
-rw-r--r-- | clang/lib/Checker/GRExprEngine.cpp | 35 |
1 files changed, 32 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>()) { |