Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1099,7 +1099,19 @@ .getAsRegion() ->getAs() ->getSuperRegion() - ->getAs(); + ->getAs(); + // FIXME: Since 'ExprEngine::VisitCXXNewAllocator' has not yet been fully + // implemented, the custom operator new[] may return Non-ElementRegion after + // its inline call. When 'ExprEngine::VisitCXXNewAllocator' is fully + // implemented, the following 'if' statement should be deleted. + if (!Region) { + assert(NE->isArray() && + !C.getSourceManager().isInSystemHeader( + NE->getOperatorNew()->getLocStart()) && + "The operator new[] can return non-ElementRegion only when it is " + "a custom version and be inlined."); + return nullptr; + } } else { ElementCount = svalBuilder.makeIntVal(1, true); Region = (State->getSVal(NE, LCtx)).getAsRegion()->getAs(); Index: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -647,6 +647,13 @@ R->printPretty(os); } } + } else if (StoreSite->getLocation().getAs()) { + os << "Reach the max loop limit."; + os << " Assigning a conjured symbol"; + if (R->canPrintPretty()) { + os << " to "; + R->printPretty(os); + } } if (os.str().empty()) { Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp =================================================================== --- lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -690,6 +690,17 @@ return getLocationForCaller(CEE->getCalleeContext(), CEE->getLocationContext(), SMng); + } else if (Optional BE = P.getAs()) { + CFGElement BlockFront = BE->getBlock()->front(); + if (BlockFront.getKind() == CFGElement::Kind::Statement) { + return PathDiagnosticLocation( + BlockFront.getAs()->getStmt()->getLocStart(), SMng); + } else if (BlockFront.getKind() == CFGElement::Kind::NewAllocator) { + return PathDiagnosticLocation(BlockFront.getAs() + ->getAllocatorExpr() + ->getLocStart(), + SMng); + } } else { llvm_unreachable("Unexpected ProgramPoint"); } Index: test/Analysis/NewDelete-custom.cpp =================================================================== --- test/Analysis/NewDelete-custom.cpp +++ test/Analysis/NewDelete-custom.cpp @@ -1,5 +1,6 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -fblocks -verify %s // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -DLEAKS -fblocks -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete -analyzer-config c++-allocator-inlining=true -std=c++11 -fblocks -verify %s #include "Inputs/system-header-simulator-cxx.h" #ifndef LEAKS Index: test/Analysis/loop-widening.c =================================================================== --- test/Analysis/loop-widening.c +++ test/Analysis/loop-widening.c @@ -188,3 +188,15 @@ } clang_analyzer_eval(i >= 2); // expected-warning {{TRUE}} } + +int *p; +int bar(); +int flag; +int test_for_bug_25609() +{ + if (p == 0) + bar(); + for (int i = 0; i < flag; ++i) {} + *p = 25609; // no-crash expected-warning {{Dereference of null pointer (loaded from variable 'p')}} + return *p; +}