Index: lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -687,8 +687,20 @@ // FIXME: We don't handle constructors or destructors for arrays properly. const MemRegion *Target = Dtor.getCXXThisVal().getAsRegion(); - if (Target && isa(Target)) - return CIP_DisallowedOnce; + if (Target && isa(Target)) { + if (const Stmt *DtorExpr = Dtor.getOriginExpr()) + if (const Stmt *ParentExpr = + CurLC->getParentMap().getParent(DtorExpr)) + if (const CXXDeleteExpr *DeleteExpr = + dyn_cast(ParentExpr)) + if (DeleteExpr->isArrayForm()) + return CIP_DisallowedOnce; + + if (const TypedValueRegion *TR = dyn_cast( + cast(Target)->getSuperRegion())) + if (TR->getValueType()->isArrayType()) + return CIP_DisallowedOnce; + } break; } Index: test/Analysis/new.cpp =================================================================== --- test/Analysis/new.cpp +++ test/Analysis/new.cpp @@ -1,4 +1,5 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -analyzer-config c++-allocator-inlining=true -DALLOCATOR_INLINING=1 -std=c++11 -verify %s #include "Inputs/system-header-simulator-cxx.h" void clang_analyzer_eval(bool); @@ -34,7 +35,12 @@ void *y = new (x) int; clang_analyzer_eval(x == y); // expected-warning{{TRUE}}; - clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}}; + clang_analyzer_eval(*x == 1); +#if ALLOCATOR_INLINING + // expected-warning@-2{{TRUE}}; +#else + // expected-warning@-4{{UNKNOWN}}; +#endif return y; } @@ -201,7 +207,10 @@ new (&n) int; // Should warn that n is uninitialized. - if (n) { // no-warning + if (n) { +#if ALLOCATOR_INLINING + // expected-warning@-2{{Branch condition evaluates to a garbage value}} +#endif return 0; } return 1; @@ -311,8 +320,7 @@ void testArrayDestr() { NoReturnDtor *p = new NoReturnDtor[2]; delete[] p; // Calls the base destructor which aborts, checked below - //TODO: clang_analyzer_eval should not be called - clang_analyzer_eval(true); // expected-warning{{TRUE}} + clang_analyzer_eval(true); } // Invalidate Region even in case of default destructor