kmarshall created this revision. The extent calculation function had a bug which caused it to ignore if the size value was defined prior to casting it. As a result, size expressions with free variables would trigger assertion failures during the cast operation.
This patch adds that missing check, and replaces the redundant call to castAs<>() with the SVar that is returned by the checked cast. Added a regression test "Malloc+NewDynamicArray" that exercises the fix. https://reviews.llvm.org/D30312 Files: lib/StaticAnalyzer/Checkers/MallocChecker.cpp test/Analysis/Malloc+NewDynamicArray.cpp Index: test/Analysis/Malloc+NewDynamicArray.cpp =================================================================== --- test/Analysis/Malloc+NewDynamicArray.cpp +++ test/Analysis/Malloc+NewDynamicArray.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -verify %s + +//----------------------------------------------------------------------- +// Check that arrays sized using expressions with free variables +// do not cause the unix.Malloc checker to crash. +// +// The function should not actually be called from anywhere, otherwise +// the compiler will optimize the length expression and replace it with +// with precomputed literals. +//----------------------------------------------------------------------- + +void AllocateExpr(int lhs, int rhs) { + new int[lhs + rhs]; +} + +// expected-no-diagnostics + Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1026,12 +1026,11 @@ ASTContext &AstContext = C.getASTContext(); CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType); - if (Optional<DefinedOrUnknownSVal> DefinedSize = - ElementCount.getAs<DefinedOrUnknownSVal>()) { + if (Optional<NonLoc> DefinedSize = ElementCount.getAs<NonLoc>()) { DefinedOrUnknownSVal Extent = Region->getExtent(svalBuilder); // size in Bytes = ElementCount*TypeSize SVal SizeInBytes = svalBuilder.evalBinOpNN( - State, BO_Mul, ElementCount.castAs<NonLoc>(), + State, BO_Mul, *DefinedSize, svalBuilder.makeArrayIndex(TypeSize.getQuantity()), svalBuilder.getArrayIndexType()); DefinedOrUnknownSVal extentMatchesSize = svalBuilder.evalEQ(
Index: test/Analysis/Malloc+NewDynamicArray.cpp =================================================================== --- test/Analysis/Malloc+NewDynamicArray.cpp +++ test/Analysis/Malloc+NewDynamicArray.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -verify %s + +//----------------------------------------------------------------------- +// Check that arrays sized using expressions with free variables +// do not cause the unix.Malloc checker to crash. +// +// The function should not actually be called from anywhere, otherwise +// the compiler will optimize the length expression and replace it with +// with precomputed literals. +//----------------------------------------------------------------------- + +void AllocateExpr(int lhs, int rhs) { + new int[lhs + rhs]; +} + +// expected-no-diagnostics + Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1026,12 +1026,11 @@ ASTContext &AstContext = C.getASTContext(); CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType); - if (Optional<DefinedOrUnknownSVal> DefinedSize = - ElementCount.getAs<DefinedOrUnknownSVal>()) { + if (Optional<NonLoc> DefinedSize = ElementCount.getAs<NonLoc>()) { DefinedOrUnknownSVal Extent = Region->getExtent(svalBuilder); // size in Bytes = ElementCount*TypeSize SVal SizeInBytes = svalBuilder.evalBinOpNN( - State, BO_Mul, ElementCount.castAs<NonLoc>(), + State, BO_Mul, *DefinedSize, svalBuilder.makeArrayIndex(TypeSize.getQuantity()), svalBuilder.getArrayIndexType()); DefinedOrUnknownSVal extentMatchesSize = svalBuilder.evalEQ(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits