MTC created this revision. MTC added reviewers: NoQ, baloghadamsoftware, szepet, dcoughlin. Herald added subscribers: cfe-commits, a.sidorin, rnkovacs, xazax.hun. Herald added a reviewer: george.karpenkov.
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`. Given the code below: void null_terminator_loop_widen(int *a) { int c; for (;;) { c = *a; a++; } } I haven't found any problems with `SymbolConjured` containing null `Stmt` for the time being. So I just use `dyn_cast_or_null<>` instead of `dyn_cast<>` in `IteratorChecker.cpp`, and didn't delve into the widen loop part. Repository: rC Clang https://reviews.llvm.org/D44606 Files: lib/StaticAnalyzer/Checkers/IteratorChecker.cpp test/Analysis/loop-widening.c Index: test/Analysis/loop-widening.c =================================================================== --- test/Analysis/loop-widening.c +++ 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,13 @@ } clang_analyzer_eval(i >= 2); // expected-warning {{TRUE}} } + +#ifdef TEST_NULL_TERM +void null_terminator_loop_widen(int *a) { + int c; + for (;;) { + c = *a; // no-crash + a++; + } +} +#endif Index: lib/StaticAnalyzer/Checkers/IteratorChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IteratorChecker.cpp +++ lib/StaticAnalyzer/Checkers/IteratorChecker.cpp @@ -604,7 +604,7 @@ if (const auto *BSE = dyn_cast<BinarySymExpr>(SE)) { return BSE->getOpcode(); } else if (const auto *SC = dyn_cast<SymbolConjured>(SE)) { - const auto *COE = dyn_cast<CXXOperatorCallExpr>(SC->getStmt()); + const auto *COE = dyn_cast_or_null<CXXOperatorCallExpr>(SC->getStmt()); if (!COE) return BO_Comma; // Extremal value, neither EQ nor NE if (COE->getOperator() == OO_EqualEqual) {
Index: test/Analysis/loop-widening.c =================================================================== --- test/Analysis/loop-widening.c +++ 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,13 @@ } clang_analyzer_eval(i >= 2); // expected-warning {{TRUE}} } + +#ifdef TEST_NULL_TERM +void null_terminator_loop_widen(int *a) { + int c; + for (;;) { + c = *a; // no-crash + a++; + } +} +#endif Index: lib/StaticAnalyzer/Checkers/IteratorChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IteratorChecker.cpp +++ lib/StaticAnalyzer/Checkers/IteratorChecker.cpp @@ -604,7 +604,7 @@ if (const auto *BSE = dyn_cast<BinarySymExpr>(SE)) { return BSE->getOpcode(); } else if (const auto *SC = dyn_cast<SymbolConjured>(SE)) { - const auto *COE = dyn_cast<CXXOperatorCallExpr>(SC->getStmt()); + const auto *COE = dyn_cast_or_null<CXXOperatorCallExpr>(SC->getStmt()); if (!COE) return BO_Comma; // Extremal value, neither EQ nor NE if (COE->getOperator() == OO_EqualEqual) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits