https://github.com/ziqingluo-90 updated https://github.com/llvm/llvm-project/pull/131374
>From fdc265eeca36dc877f56389d8dba39b5144447e6 Mon Sep 17 00:00:00 2001 From: Ziqing Luo <ziqing_...@apple.com> Date: Fri, 14 Mar 2025 11:13:46 -0700 Subject: [PATCH 1/3] [NFC][Static Analyzer] Rename `NotNullConstraint` & `NotNullBufferConstraint` NotNullConstraint is used to check both null and non-null of a pointer. So the name, which was created originally for just checking non-nullness, becomes less suitable. The same reason applies to `NotNullBufferConstraint`. --- .../Checkers/StdLibraryFunctionsChecker.cpp | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index fef19b4547555..3542b7c8aaf30 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -367,13 +367,13 @@ class StdLibraryFunctionsChecker }; /// Check null or non-null-ness of an argument that is of pointer type. - class NotNullConstraint : public ValueConstraint { + class NullnessConstraint : public ValueConstraint { using ValueConstraint::ValueConstraint; // This variable has a role when we negate the constraint. bool CannotBeNull = true; public: - NotNullConstraint(ArgNo ArgN, bool CannotBeNull = true) + NullnessConstraint(ArgNo ArgN, bool CannotBeNull = true) : ValueConstraint(ArgN), CannotBeNull(CannotBeNull) {} ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call, @@ -389,9 +389,9 @@ class StdLibraryFunctionsChecker llvm::raw_ostream &Out) const override; ValueConstraintPtr negate() const override { - NotNullConstraint Tmp(*this); + NullnessConstraint Tmp(*this); Tmp.CannotBeNull = !this->CannotBeNull; - return std::make_shared<NotNullConstraint>(Tmp); + return std::make_shared<NullnessConstraint>(Tmp); } protected: @@ -407,9 +407,9 @@ class StdLibraryFunctionsChecker /// The argument is meant to be a buffer that has a size constraint, and it /// is allowed to have a NULL value if the size is 0. The size can depend on /// 1 or 2 additional arguments, if one of these is 0 the buffer is allowed to - /// be NULL. This is useful for functions like `fread` which have this special - /// property. - class NotNullBufferConstraint : public ValueConstraint { + /// be NULL. Otherwise, the buffer pointer must be non-null. This is useful + /// for functions like `fread` which have this special property. + class BufferNullnessConstraint : public ValueConstraint { using ValueConstraint::ValueConstraint; ArgNo SizeArg1N; std::optional<ArgNo> SizeArg2N; @@ -417,7 +417,7 @@ class StdLibraryFunctionsChecker bool CannotBeNull = true; public: - NotNullBufferConstraint(ArgNo ArgN, ArgNo SizeArg1N, + BufferNullnessConstraint(ArgNo ArgN, ArgNo SizeArg1N, std::optional<ArgNo> SizeArg2N, bool CannotBeNull = true) : ValueConstraint(ArgN), SizeArg1N(SizeArg1N), SizeArg2N(SizeArg2N), @@ -436,9 +436,9 @@ class StdLibraryFunctionsChecker llvm::raw_ostream &Out) const override; ValueConstraintPtr negate() const override { - NotNullBufferConstraint Tmp(*this); + BufferNullnessConstraint Tmp(*this); Tmp.CannotBeNull = !this->CannotBeNull; - return std::make_shared<NotNullBufferConstraint>(Tmp); + return std::make_shared<BufferNullnessConstraint>(Tmp); } protected: @@ -1151,7 +1151,7 @@ ProgramStateRef StdLibraryFunctionsChecker::ComparisonConstraint::apply( return State; } -ProgramStateRef StdLibraryFunctionsChecker::NotNullConstraint::apply( +ProgramStateRef StdLibraryFunctionsChecker::NullnessConstraint::apply( ProgramStateRef State, const CallEvent &Call, const Summary &Summary, CheckerContext &C) const { SVal V = getArgSVal(Call, getArgNo()); @@ -1165,7 +1165,7 @@ ProgramStateRef StdLibraryFunctionsChecker::NotNullConstraint::apply( return State->assume(L, CannotBeNull); } -void StdLibraryFunctionsChecker::NotNullConstraint::describe( +void StdLibraryFunctionsChecker::NullnessConstraint::describe( DescriptionKind DK, const CallEvent &Call, ProgramStateRef State, const Summary &Summary, llvm::raw_ostream &Out) const { assert(CannotBeNull && @@ -1176,7 +1176,7 @@ void StdLibraryFunctionsChecker::NotNullConstraint::describe( Out << "is not NULL"; } -bool StdLibraryFunctionsChecker::NotNullConstraint::describeArgumentValue( +bool StdLibraryFunctionsChecker::NullnessConstraint::describeArgumentValue( const CallEvent &Call, ProgramStateRef State, const Summary &Summary, llvm::raw_ostream &Out) const { assert(!CannotBeNull && "This function is used when the value is NULL"); @@ -1184,7 +1184,7 @@ bool StdLibraryFunctionsChecker::NotNullConstraint::describeArgumentValue( return true; } -ProgramStateRef StdLibraryFunctionsChecker::NotNullBufferConstraint::apply( +ProgramStateRef StdLibraryFunctionsChecker::BufferNullnessConstraint::apply( ProgramStateRef State, const CallEvent &Call, const Summary &Summary, CheckerContext &C) const { SVal V = getArgSVal(Call, getArgNo()); @@ -1213,7 +1213,7 @@ ProgramStateRef StdLibraryFunctionsChecker::NotNullBufferConstraint::apply( return State->assume(L, CannotBeNull); } -void StdLibraryFunctionsChecker::NotNullBufferConstraint::describe( +void StdLibraryFunctionsChecker::BufferNullnessConstraint::describe( DescriptionKind DK, const CallEvent &Call, ProgramStateRef State, const Summary &Summary, llvm::raw_ostream &Out) const { assert(CannotBeNull && @@ -1224,7 +1224,7 @@ void StdLibraryFunctionsChecker::NotNullBufferConstraint::describe( Out << "is not NULL"; } -bool StdLibraryFunctionsChecker::NotNullBufferConstraint::describeArgumentValue( +bool StdLibraryFunctionsChecker::BufferNullnessConstraint::describeArgumentValue( const CallEvent &Call, ProgramStateRef State, const Summary &Summary, llvm::raw_ostream &Out) const { assert(!CannotBeNull && "This function is used when the value is NULL"); @@ -1792,14 +1792,14 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( }; auto LessThanOrEq = BO_LE; auto NotNull = [&](ArgNo ArgN) { - return std::make_shared<NotNullConstraint>(ArgN); + return std::make_shared<NullnessConstraint>(ArgN); }; auto IsNull = [&](ArgNo ArgN) { - return std::make_shared<NotNullConstraint>(ArgN, false); + return std::make_shared<NullnessConstraint>(ArgN, false); }; auto NotNullBuffer = [&](ArgNo ArgN, ArgNo SizeArg1N, std::optional<ArgNo> SizeArg2N = std::nullopt) { - return std::make_shared<NotNullBufferConstraint>(ArgN, SizeArg1N, + return std::make_shared<BufferNullnessConstraint>(ArgN, SizeArg1N, SizeArg2N); }; >From 93a97284b1a3b42d46462a2e7ac993f487668921 Mon Sep 17 00:00:00 2001 From: Ziqing Luo <ziqing_...@apple.com> Date: Mon, 24 Mar 2025 16:48:19 -0700 Subject: [PATCH 2/3] Change the assertion message to indicate that some cases are not implemented instread of should not happen --- .../Checkers/StdLibraryFunctionsChecker.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index 3542b7c8aaf30..3a311f75d986f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -1169,7 +1169,7 @@ void StdLibraryFunctionsChecker::NullnessConstraint::describe( DescriptionKind DK, const CallEvent &Call, ProgramStateRef State, const Summary &Summary, llvm::raw_ostream &Out) const { assert(CannotBeNull && - "Describe should not be used when the value must be NULL"); + "'describe' is not implemented when the value must be NULL"); if (DK == Violation) Out << "should not be NULL"; else @@ -1179,7 +1179,8 @@ void StdLibraryFunctionsChecker::NullnessConstraint::describe( bool StdLibraryFunctionsChecker::NullnessConstraint::describeArgumentValue( const CallEvent &Call, ProgramStateRef State, const Summary &Summary, llvm::raw_ostream &Out) const { - assert(!CannotBeNull && "This function is used when the value is NULL"); + assert(!CannotBeNull && "'describeArgumentValue' is not implemented when the " + "value must be non-NULL"); Out << "is NULL"; return true; } @@ -1217,7 +1218,7 @@ void StdLibraryFunctionsChecker::BufferNullnessConstraint::describe( DescriptionKind DK, const CallEvent &Call, ProgramStateRef State, const Summary &Summary, llvm::raw_ostream &Out) const { assert(CannotBeNull && - "Describe should not be used when the value must be NULL"); + "'describe' is not implemented when the buffer must be NULL"); if (DK == Violation) Out << "should not be NULL"; else @@ -1227,7 +1228,8 @@ void StdLibraryFunctionsChecker::BufferNullnessConstraint::describe( bool StdLibraryFunctionsChecker::BufferNullnessConstraint::describeArgumentValue( const CallEvent &Call, ProgramStateRef State, const Summary &Summary, llvm::raw_ostream &Out) const { - assert(!CannotBeNull && "This function is used when the value is NULL"); + assert(!CannotBeNull && "'describeArgumentValue' is not implemented when the " + "buffer must be non-NULL"); Out << "is NULL"; return true; } >From b1bb00f7ce33880e16bf89d22ae8abfbc0f21c18 Mon Sep 17 00:00:00 2001 From: Ziqing Luo <ziqing_...@apple.com> Date: Mon, 24 Mar 2025 16:55:13 -0700 Subject: [PATCH 3/3] fix format --- .../Checkers/StdLibraryFunctionsChecker.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index 3a311f75d986f..b9f743c5c386b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -418,8 +418,8 @@ class StdLibraryFunctionsChecker public: BufferNullnessConstraint(ArgNo ArgN, ArgNo SizeArg1N, - std::optional<ArgNo> SizeArg2N, - bool CannotBeNull = true) + std::optional<ArgNo> SizeArg2N, + bool CannotBeNull = true) : ValueConstraint(ArgN), SizeArg1N(SizeArg1N), SizeArg2N(SizeArg2N), CannotBeNull(CannotBeNull) {} @@ -1225,9 +1225,10 @@ void StdLibraryFunctionsChecker::BufferNullnessConstraint::describe( Out << "is not NULL"; } -bool StdLibraryFunctionsChecker::BufferNullnessConstraint::describeArgumentValue( - const CallEvent &Call, ProgramStateRef State, const Summary &Summary, - llvm::raw_ostream &Out) const { +bool StdLibraryFunctionsChecker::BufferNullnessConstraint:: + describeArgumentValue(const CallEvent &Call, ProgramStateRef State, + const Summary &Summary, + llvm::raw_ostream &Out) const { assert(!CannotBeNull && "'describeArgumentValue' is not implemented when the " "buffer must be non-NULL"); Out << "is NULL"; @@ -1802,7 +1803,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( auto NotNullBuffer = [&](ArgNo ArgN, ArgNo SizeArg1N, std::optional<ArgNo> SizeArg2N = std::nullopt) { return std::make_shared<BufferNullnessConstraint>(ArgN, SizeArg1N, - SizeArg2N); + SizeArg2N); }; std::optional<QualType> FileTy = lookupTy("FILE"); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits