balazske created this revision. Herald added subscribers: manas, steakhal, ASDenysPetrov, martong, gamesh411, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, baloghadamsoftware, xazax.hun, whisperity. Herald added a reviewer: Szelethus. balazske requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The checker contains check for passing a NULL stream argument. This change should make more easy to identify where the passed pointer becomes NULL. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D104640 Files: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp clang/test/Analysis/stream-note.c
Index: clang/test/Analysis/stream-note.c =================================================================== --- clang/test/Analysis/stream-note.c +++ clang/test/Analysis/stream-note.c @@ -77,3 +77,14 @@ fclose(F1); fclose(F2); } + +void check_track_null() { + FILE *F; + F = fopen("foo1.c", "r"); // expected-note {{Value assigned to 'F'}} expected-note {{Assuming pointer value is null}} + if (F != NULL) { // expected-note {{Taking false branch}} expected-note {{'F' is equal to NULL}} + fclose(F); + return; + } + fclose(F); // expected-warning {{Stream pointer might be NULL}} + // expected-note@-1 {{Stream pointer might be NULL}} +} Index: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -306,7 +306,8 @@ /// If it can only be NULL a fatal error is emitted and nullptr returned. /// Otherwise the return value is a new state where the stream is constrained /// to be non-null. - ProgramStateRef ensureStreamNonNull(SVal StreamVal, CheckerContext &C, + ProgramStateRef ensureStreamNonNull(SVal StreamVal, const Expr *StreamE, + CheckerContext &C, ProgramStateRef State) const; /// Check that the stream is the opened state. @@ -472,7 +473,8 @@ CheckerContext &C) const { // Do not allow NULL as passed stream pointer but allow a closed stream. ProgramStateRef State = C.getState(); - State = ensureStreamNonNull(getStreamArg(Desc, Call), C, State); + State = ensureStreamNonNull(getStreamArg(Desc, Call), + Call.getArgExpr(Desc->StreamArgNo), C, State); if (!State) return; @@ -549,7 +551,8 @@ CheckerContext &C) const { ProgramStateRef State = C.getState(); SVal StreamVal = getStreamArg(Desc, Call); - State = ensureStreamNonNull(StreamVal, C, State); + State = ensureStreamNonNull(StreamVal, Call.getArgExpr(Desc->StreamArgNo), C, + State); if (!State) return; State = ensureStreamOpened(StreamVal, C, State); @@ -573,7 +576,8 @@ CheckerContext &C) const { ProgramStateRef State = C.getState(); SVal StreamVal = getStreamArg(Desc, Call); - State = ensureStreamNonNull(StreamVal, C, State); + State = ensureStreamNonNull(StreamVal, Call.getArgExpr(Desc->StreamArgNo), C, + State); if (!State) return; State = ensureStreamOpened(StreamVal, C, State); @@ -671,7 +675,8 @@ CheckerContext &C) const { ProgramStateRef State = C.getState(); SVal StreamVal = getStreamArg(Desc, Call); - State = ensureStreamNonNull(StreamVal, C, State); + State = ensureStreamNonNull(StreamVal, Call.getArgExpr(Desc->StreamArgNo), C, + State); if (!State) return; State = ensureStreamOpened(StreamVal, C, State); @@ -790,7 +795,8 @@ CheckerContext &C) const { ProgramStateRef State = C.getState(); SVal StreamVal = getStreamArg(Desc, Call); - State = ensureStreamNonNull(StreamVal, C, State); + State = ensureStreamNonNull(StreamVal, Call.getArgExpr(Desc->StreamArgNo), C, + State); if (!State) return; State = ensureStreamOpened(StreamVal, C, State); @@ -814,7 +820,8 @@ } ProgramStateRef -StreamChecker::ensureStreamNonNull(SVal StreamVal, CheckerContext &C, +StreamChecker::ensureStreamNonNull(SVal StreamVal, const Expr *StreamE, + CheckerContext &C, ProgramStateRef State) const { auto Stream = StreamVal.getAs<DefinedSVal>(); if (!Stream) @@ -827,8 +834,11 @@ if (!StateNotNull && StateNull) { if (ExplodedNode *N = C.generateErrorNode(StateNull)) { - C.emitReport(std::make_unique<PathSensitiveBugReport>( - BT_FileNull, "Stream pointer might be NULL.", N)); + auto R = std::make_unique<PathSensitiveBugReport>( + BT_FileNull, "Stream pointer might be NULL.", N); + if (StreamE) + bugreporter::trackExpressionValue(N, StreamE, *R); + C.emitReport(std::move(R)); } return nullptr; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits