diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-07-16 23:38:09 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-16 23:38:09 +0000 |
commit | 89e5aaf57e20b39e35b0d068ebbc09ae736f2e1e (patch) | |
tree | 81e26f5fefbe3d2d30ce0fc2387f82ac5aed1dd1 | |
parent | b04a45720ba0cbc4bdb08aebceefa184e22f8a93 (diff) |
[analyzer] Handle new-expressions with initializers for scalars.
<rdar://problem/11818967>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160328 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineC.cpp | 21 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 13 | ||||
-rw-r--r-- | test/Analysis/new.cpp | 35 |
3 files changed, 50 insertions, 19 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp index fe9adb1e15..0254b756ee 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -571,18 +571,17 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE, svalBuilder.makeCompoundVal(T, vals))); return; } - - if (Loc::isLocType(T) || T->isIntegerType()) { - assert(IE->getNumInits() == 1); - const Expr *initEx = IE->getInit(0); - B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, - state->getSVal(initEx, LCtx))); - return; - } - assert(IE->getNumInits() == 1); - B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, UnknownVal())); - return; + // Handle scalars: int{5} and int{}. + assert(NumInitElements <= 1); + + SVal V; + if (NumInitElements == 0) + V = getSValBuilder().makeZeroVal(T); + else + V = state->getSVal(IE->getInit(0), LCtx); + + B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V)); } void ExprEngine::VisitGuardedExpr(const Expr *Ex, diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 3fa052817c..9a1264e17c 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -136,6 +136,19 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, State = State->BindExpr(CNE, LCtx, symVal); } + // If the type is not a record, we won't have a CXXConstructExpr as an + // initializer. Copy the value over. + if (const Expr *Init = CNE->getInitializer()) { + if (!isa<CXXConstructExpr>(Init)) { + QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); + (void)ObjTy; + assert(!ObjTy->isRecordType()); + SVal Location = State->getSVal(CNE, LCtx); + if (isa<Loc>(Location)) + State = State->bindLoc(cast<Loc>(Location), State->getSVal(Init, LCtx)); + } + } + Bldr.generateNode(CNE, Pred, State); } diff --git a/test/Analysis/new.cpp b/test/Analysis/new.cpp index 5dad9430c6..fb77de22f1 100644 --- a/test/Analysis/new.cpp +++ b/test/Analysis/new.cpp @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s void clang_analyzer_eval(bool); -typedef typeof(sizeof(int)) size_t; +typedef __typeof__(sizeof(int)) size_t; extern "C" void *malloc(size_t); int someGlobal; @@ -59,23 +59,42 @@ void *testCustomNewMalloc() { return y; } +void testScalarInitialization() { + int *n = new int(3); + clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}} + + new (n) int(); + clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}} + + new (n) int{3}; + clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}} + + new (n) int{}; + clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}} +} + //-------------------------------- // Incorrectly-modelled behavior //-------------------------------- -void testZeroInitialization() { +int testNoInitialization() { int *n = new int; // Should warn that *n is uninitialized. if (*n) { // no-warning + return 0; } + return 1; } -void testValueInitialization() { - int *n = new int(3); +int testNoInitializationPlacement() { + int n; + new (&n) int; - // Should be TRUE (and have no uninitialized variable warning) - clang_analyzer_eval(*n == 3); // expected-warning{{UNKNOWN}} + // Should warn that n is uninitialized. + if (n) { // no-warning + return 0; + } + return 1; } - |