This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGda0660691f74: [clang][analyzer] No new nodes when bug is detected in… (authored by balazske).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D137722/new/ https://reviews.llvm.org/D137722 Files: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/test/Analysis/std-c-library-functions-arg-constraints.c Index: clang/test/Analysis/std-c-library-functions-arg-constraints.c =================================================================== --- clang/test/Analysis/std-c-library-functions-arg-constraints.c +++ clang/test/Analysis/std-c-library-functions-arg-constraints.c @@ -20,6 +20,7 @@ // RUN: -verify=bugpath void clang_analyzer_eval(int); +void clang_analyzer_warnIfReached(); int glob; @@ -215,6 +216,20 @@ // bugpath-note{{}} \ // bugpath-note{{Function argument constraint is not satisfied}} } +void test_no_node_after_bug(FILE *fp, size_t size, size_t n, void *buf) { + if (fp) // \ + // bugpath-note{{Assuming 'fp' is null}} \ + // bugpath-note{{Taking false branch}} + return; + size_t ret = fread(buf, size, n, fp); // \ + // report-warning{{Function argument constraint is not satisfied}} \ + // report-note{{}} \ + // bugpath-warning{{Function argument constraint is not satisfied}} \ + // bugpath-note{{}} \ + // bugpath-note{{Function argument constraint is not satisfied}} + clang_analyzer_warnIfReached(); // not reachable +} + typedef __WCHAR_TYPE__ wchar_t; // This is one test case for the ARR38-C SEI-CERT rule. void ARR38_C_F(FILE *file) { Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -951,7 +951,7 @@ Constraint->negate()->apply(NewState, Call, Summary, C); // The argument constraint is not satisfied. if (FailureSt && !SuccessSt) { - if (ExplodedNode *N = C.generateErrorNode(NewState)) + if (ExplodedNode *N = C.generateErrorNode(NewState, NewNode)) reportBug(Call, N, Constraint.get(), Summary, C); break; } Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -211,6 +211,22 @@ (Tag ? Tag : Location.getTag())); } + /// Generate a transition to a node that will be used to report + /// an error. This node will be a sink. That is, it will stop exploration of + /// the given path. + /// + /// @param State The state of the generated node. + /// @param Pred The transition will be generated from the specified Pred node + /// to the newly generated node. + /// @param Tag The tag to uniquely identify the creation site. If null, + /// the default tag for the checker will be used. + ExplodedNode *generateErrorNode(ProgramStateRef State, + ExplodedNode *Pred, + const ProgramPointTag *Tag = nullptr) { + return generateSink(State, Pred, + (Tag ? Tag : Location.getTag())); + } + /// Generate a transition to a node that will be used to report /// an error. This node will not be a sink. That is, exploration will /// continue along this path.
Index: clang/test/Analysis/std-c-library-functions-arg-constraints.c =================================================================== --- clang/test/Analysis/std-c-library-functions-arg-constraints.c +++ clang/test/Analysis/std-c-library-functions-arg-constraints.c @@ -20,6 +20,7 @@ // RUN: -verify=bugpath void clang_analyzer_eval(int); +void clang_analyzer_warnIfReached(); int glob; @@ -215,6 +216,20 @@ // bugpath-note{{}} \ // bugpath-note{{Function argument constraint is not satisfied}} } +void test_no_node_after_bug(FILE *fp, size_t size, size_t n, void *buf) { + if (fp) // \ + // bugpath-note{{Assuming 'fp' is null}} \ + // bugpath-note{{Taking false branch}} + return; + size_t ret = fread(buf, size, n, fp); // \ + // report-warning{{Function argument constraint is not satisfied}} \ + // report-note{{}} \ + // bugpath-warning{{Function argument constraint is not satisfied}} \ + // bugpath-note{{}} \ + // bugpath-note{{Function argument constraint is not satisfied}} + clang_analyzer_warnIfReached(); // not reachable +} + typedef __WCHAR_TYPE__ wchar_t; // This is one test case for the ARR38-C SEI-CERT rule. void ARR38_C_F(FILE *file) { Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -951,7 +951,7 @@ Constraint->negate()->apply(NewState, Call, Summary, C); // The argument constraint is not satisfied. if (FailureSt && !SuccessSt) { - if (ExplodedNode *N = C.generateErrorNode(NewState)) + if (ExplodedNode *N = C.generateErrorNode(NewState, NewNode)) reportBug(Call, N, Constraint.get(), Summary, C); break; } Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -211,6 +211,22 @@ (Tag ? Tag : Location.getTag())); } + /// Generate a transition to a node that will be used to report + /// an error. This node will be a sink. That is, it will stop exploration of + /// the given path. + /// + /// @param State The state of the generated node. + /// @param Pred The transition will be generated from the specified Pred node + /// to the newly generated node. + /// @param Tag The tag to uniquely identify the creation site. If null, + /// the default tag for the checker will be used. + ExplodedNode *generateErrorNode(ProgramStateRef State, + ExplodedNode *Pred, + const ProgramPointTag *Tag = nullptr) { + return generateSink(State, Pred, + (Tag ? Tag : Location.getTag())); + } + /// Generate a transition to a node that will be used to report /// an error. This node will not be a sink. That is, exploration will /// continue along this path.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits