diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-12-09 00:44:16 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-12-09 00:44:16 +0000 |
commit | 159d2487e6b49f0aa64c44aef96bc9d643929931 (patch) | |
tree | 3f55f8f2e46c53255325dd42115a7bb6fbacb956 /lib/Analysis/GRExprEngineInternalChecks.cpp | |
parent | ca9bab0dcbaa980bd9e7131f43b3d3b055946983 (diff) |
[static analyzer] Extend VLA size checking to look for undefined sizes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60734 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngineInternalChecks.cpp')
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp index 8b484ab10c..d32318ca7d 100644 --- a/lib/Analysis/GRExprEngineInternalChecks.cpp +++ b/lib/Analysis/GRExprEngineInternalChecks.cpp @@ -40,6 +40,7 @@ ExplodedNode<GRState>* GetNode(GRExprEngine::undef_arg_iterator I) { namespace { class VISIBILITY_HIDDEN BuiltinBug : public BugTypeCacheLocation { +protected: const char* name; const char* desc; public: @@ -332,26 +333,45 @@ public: } }; -class VISIBILITY_HIDDEN ZeroSizeVLA : public BuiltinBug { +class VISIBILITY_HIDDEN BadSizeVLA : public BuiltinBug { public: - ZeroSizeVLA() : BuiltinBug("Zero-sized VLA", + BadSizeVLA() : BuiltinBug("Zero-sized VLA", "VLAs with zero-size are undefined.") {} virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) { for (GRExprEngine::ErrorNodes::iterator - I = Eng.ExplicitZeroSizedVLA.begin(), - E = Eng.ExplicitZeroSizedVLA.end(); I!=E; ++I) { - - // Generate a report for this bug. - PostStmt PS = cast<PostStmt>((*I)->getLocation()); + I = Eng.ExplicitBadSizedVLA.begin(), + E = Eng.ExplicitBadSizedVLA.end(); I!=E; ++I) { + + // Determine whether this was a 'zero-sized' VLA or a VLA with an + // undefined size. + GRExprEngine::NodeTy* N = *I; + PostStmt PS = cast<PostStmt>(N->getLocation()); DeclStmt *DS = cast<DeclStmt>(PS.getStmt()); VarDecl* VD = cast<VarDecl>(*DS->decl_begin()); QualType T = Eng.getContext().getCanonicalType(VD->getType()); VariableArrayType* VT = cast<VariableArrayType>(T); + Expr* SizeExpr = VT->getSizeExpr(); - RangedBugReport report(*this, *I); - report.addRange(VT->getSizeExpr()->getSourceRange()); + std::string buf; + llvm::raw_string_ostream os(buf); + os << "The expression used to specify the number of elements in the VLA '" + << VD->getNameAsString() << "' evaluates to "; + + SVal X = Eng.getStateManager().GetSVal(N->getState(), SizeExpr); + if (X.isUndef()) { + name = "Undefined size for VLA"; + os << "an undefined or garbage value."; + } + else { + name = "Zero-sized VLA"; + os << " to 0. VLAs with no elements have undefined behavior."; + } + + desc = os.str().c_str(); + RangedBugReport report(*this, N); + report.addRange(SizeExpr->getSourceRange()); // Emit the warning. BR.EmitWarning(report); @@ -430,6 +450,6 @@ void GRExprEngine::RegisterInternalChecks() { Register(new BadMsgExprArg()); Register(new BadReceiver()); Register(new OutOfBoundMemoryAccess()); - Register(new ZeroSizeVLA()); + Register(new BadSizeVLA()); AddCheck(new CheckAttrNonNull(), Stmt::CallExprClass); } |