[cfe-commits] r107603 - in /cfe/trunk: lib/Checker/MemRegion.cpp lib/Checker/VLASizeChecker.cpp test/Analysis/outofbound.c
Jordy Rose
jediknil at belkadan.com
Sun Jul 4 17:50:15 PDT 2010
Author: jrose
Date: Sun Jul 4 19:50:15 2010
New Revision: 107603
URL: http://llvm.org/viewvc/llvm-project?rev=107603&view=rev
Log:
Track extents for VLAs.
Modified:
cfe/trunk/lib/Checker/MemRegion.cpp
cfe/trunk/lib/Checker/VLASizeChecker.cpp
cfe/trunk/test/Analysis/outofbound.c
Modified: cfe/trunk/lib/Checker/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/MemRegion.cpp?rev=107603&r1=107602&r2=107603&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/MemRegion.cpp (original)
+++ cfe/trunk/lib/Checker/MemRegion.cpp Sun Jul 4 19:50:15 2010
@@ -179,8 +179,9 @@
ASTContext& Ctx = ValMgr.getContext();
QualType T = getDesugaredValueType(Ctx);
- // FIXME: Handle variable-length arrays.
- if (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
+ if (isa<VariableArrayType>(T))
+ return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
+ if (isa<IncompleteArrayType>(T))
return UnknownVal();
CharUnits Size = Ctx.getTypeSizeInChars(T);
Modified: cfe/trunk/lib/Checker/VLASizeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/VLASizeChecker.cpp?rev=107603&r1=107602&r2=107603&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/VLASizeChecker.cpp (original)
+++ cfe/trunk/lib/Checker/VLASizeChecker.cpp Sun Jul 4 19:50:15 2010
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "GRExprEngineInternalChecks.h"
+#include "clang/AST/CharUnits.h"
#include "clang/Checker/BugReporter/BugType.h"
#include "clang/Checker/PathSensitive/CheckerVisitor.h"
#include "clang/Checker/PathSensitive/GRExprEngine.h"
@@ -42,9 +43,9 @@
const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
if (!VD)
return;
-
- const VariableArrayType *VLA
- = C.getASTContext().getAsVariableArrayType(VD->getType());
+
+ ASTContext &Ctx = C.getASTContext();
+ const VariableArrayType *VLA = Ctx.getAsVariableArrayType(VD->getType());
if (!VLA)
return;
@@ -70,9 +71,14 @@
C.EmitReport(report);
return;
}
+
+ // See if the size value is known. It can't be undefined because we would have
+ // warned about that already.
+ if (sizeV.isUnknown())
+ return;
// Check if the size is zero.
- DefinedOrUnknownSVal sizeD = cast<DefinedOrUnknownSVal>(sizeV);
+ DefinedSVal sizeD = cast<DefinedSVal>(sizeV);
const GRState *stateNotZero, *stateZero;
llvm::tie(stateNotZero, stateZero) = state->Assume(sizeD);
@@ -92,5 +98,29 @@
}
// From this point on, assume that the size is not zero.
- C.addTransition(stateNotZero);
+ state = stateNotZero;
+
+ // Convert the array length to size_t.
+ ValueManager &ValMgr = C.getValueManager();
+ SValuator &SV = ValMgr.getSValuator();
+ QualType SizeTy = Ctx.getSizeType();
+ NonLoc ArrayLength = cast<NonLoc>(SV.EvalCast(sizeD, SizeTy, SE->getType()));
+
+ // Get the element size.
+ CharUnits EleSize = Ctx.getTypeSizeInChars(VLA->getElementType());
+ SVal EleSizeVal = ValMgr.makeIntVal(EleSize.getQuantity(), SizeTy);
+
+ // Multiply the array length by the element size.
+ SVal ArraySizeVal = SV.EvalBinOpNN(state, BinaryOperator::Mul, ArrayLength,
+ cast<NonLoc>(EleSizeVal), SizeTy);
+
+ // Finally, Assume that the array's extent matches the given size.
+ const LocationContext *LC = C.getPredecessor()->getLocationContext();
+ DefinedOrUnknownSVal Extent = state->getRegion(VD, LC)->getExtent(ValMgr);
+ DefinedOrUnknownSVal ArraySize = cast<DefinedOrUnknownSVal>(ArraySizeVal);
+ DefinedOrUnknownSVal SizeIsKnown = SV.EvalEQ(state, Extent, ArraySize);
+ state = state->Assume(SizeIsKnown, true);
+
+ // Remember our assumptions!
+ C.addTransition(state);
}
Modified: cfe/trunk/test/Analysis/outofbound.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/outofbound.c?rev=107603&r1=107602&r2=107603&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/outofbound.c (original)
+++ cfe/trunk/test/Analysis/outofbound.c Sun Jul 4 19:50:15 2010
@@ -54,3 +54,11 @@
struct three_words a;
a.c[3] = 1; // expected-warning{{out-of-bound}}
}
+
+void vla(int a) {
+ if (a == 5) {
+ int x[a];
+ x[4] = 4; // no-warning
+ x[5] = 5; // expected-warning{{out-of-bound}}
+ }
+}
More information about the cfe-commits
mailing list