From 073d5f023c19f3930ef0a5f0c931e1867331d970 Mon Sep 17 00:00:00 2001 From: Henry Wong Date: Tue, 20 Mar 2018 09:27:02 +0000 Subject: [PATCH] [analyzer] Fix the crash in IteratorChecker.cpp when 'SymbolConjured' has a null Stmt. When the loop has a null terminator statement and sets 'widen-loops=true', 'invalidateRegions' will constructs the 'SymbolConjured' with null 'Stmt'. And this will lead to a crash in 'IteratorChecker.cpp'. This patch use 'dyn_cast_or_null<>' instead of 'dyn_cast<>' in IteratorChecker.cpp. Differential Revision: https://reviews.llvm.org/D44606 llvm-svn: 327962 --- .../StaticAnalyzer/Checkers/IteratorChecker.cpp | 2 +- clang/test/Analysis/loop-widening.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp index 11f42229f53d..29d48ef1c57d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp @@ -604,7 +604,7 @@ BinaryOperator::Opcode getOpcode(const SymExpr *SE) { if (const auto *BSE = dyn_cast(SE)) { return BSE->getOpcode(); } else if (const auto *SC = dyn_cast(SE)) { - const auto *COE = dyn_cast(SC->getStmt()); + const auto *COE = dyn_cast_or_null(SC->getStmt()); if (!COE) return BO_Comma; // Extremal value, neither EQ nor NE if (COE->getOperator() == OO_EqualEqual) { diff --git a/clang/test/Analysis/loop-widening.c b/clang/test/Analysis/loop-widening.c index de17951d180f..3378893b3257 100644 --- a/clang/test/Analysis/loop-widening.c +++ b/clang/test/Analysis/loop-widening.c @@ -1,4 +1,5 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s +// RUN: %clang_analyze_cc1 -DTEST_NULL_TERM -analyzer-checker=core,unix.Malloc,debug.ExprInspection,alpha.cplusplus.IteratorRange -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s void clang_analyzer_eval(int); void clang_analyzer_warnIfReached(); @@ -188,3 +189,16 @@ void nested_loop_inner_widen() { } clang_analyzer_eval(i >= 2); // expected-warning {{TRUE}} } + +#ifdef TEST_NULL_TERM +void null_terminator_loop_widen(int *a) { + int c; + // Loop widening will call 'invalidateRegions()' and 'invalidateRegions()' + // will construct the SymbolConjured with null Stmt because of the null + // terminator statement. Accessing the null Stmt will cause a crash. + for (;;) { + c = *a; // no-crash + a++; + } +} +#endif