[clang] ce1fb03 - [clang][analyzer] Improve bug reports of StdLibraryFunctionsChecker.
Balázs Kéri via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 12 01:25:43 PDT 2023
Author: Balázs Kéri
Date: 2023-04-12T10:24:55+02:00
New Revision: ce1fb03db8174ca63fedc6e3aebdd6fb2c4fcfdf
URL: https://github.com/llvm/llvm-project/commit/ce1fb03db8174ca63fedc6e3aebdd6fb2c4fcfdf
DIFF: https://github.com/llvm/llvm-project/commit/ce1fb03db8174ca63fedc6e3aebdd6fb2c4fcfdf.diff
LOG: [clang][analyzer] Improve bug reports of StdLibraryFunctionsChecker.
Add an additional explanation of what is wrong if a constraint is
not satisfied, in some cases.
Additionally the bug report generation is changed to use raw_ostream.
Reviewed By: Szelethus, NoQ
Differential Revision: https://reviews.llvm.org/D144003
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp
clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c
clang/test/Analysis/std-c-library-functions-arg-constraints.c
clang/test/Analysis/std-c-library-functions-arg-constraints.cpp
clang/test/Analysis/stream-note.c
clang/test/Analysis/stream-stdlibraryfunctionargs.c
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 98f5540cef709..4e3ea0934b6f1 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -102,21 +102,19 @@ class StdLibraryFunctionsChecker
/// Special argument number for specifying the return value.
static const ArgNo Ret;
- using DescString = SmallString<96>;
-
- /// Returns the string representation of an argument index.
+ /// Get a string representation of an argument index.
/// E.g.: (1) -> '1st arg', (2) - > '2nd arg'
- static SmallString<8> getArgDesc(ArgNo);
- /// Append textual description of a numeric range [RMin,RMax] to the string
+ static void printArgDesc(ArgNo, llvm::raw_ostream &Out);
+ /// Append textual description of a numeric range [RMin,RMax] to
/// \p Out.
static void appendInsideRangeDesc(llvm::APSInt RMin, llvm::APSInt RMax,
QualType ArgT, BasicValueFactory &BVF,
- DescString &Out);
- /// Append textual description of a numeric range out of [RMin,RMax] to the
- /// string \p Out.
+ llvm::raw_ostream &Out);
+ /// Append textual description of a numeric range out of [RMin,RMax] to
+ /// \p Out.
static void appendOutOfRangeDesc(llvm::APSInt RMin, llvm::APSInt RMax,
QualType ArgT, BasicValueFactory &BVF,
- DescString &Out);
+ llvm::raw_ostream &Out);
class ValueConstraint;
@@ -152,21 +150,25 @@ class StdLibraryFunctionsChecker
/// Represents that in which context do we require a description of the
/// constraint.
- enum class DescriptionKind {
- /// The constraint is violated.
+ enum DescriptionKind {
+ /// Describe a constraint that was violated.
+ /// Description should start with something like "should be".
Violation,
- /// We assume that the constraint is satisfied.
+ /// Describe a constraint that was assumed to be true.
/// This can be used when a precondition is satisfied, or when a summary
/// case is applied.
+ /// Description should start with something like "is".
Assumption
};
/// Give a description that explains the constraint to the user. Used when
/// a bug is reported or when the constraint is applied and displayed as a
- /// note.
- virtual std::string describe(DescriptionKind DK, const CallEvent &Call,
- ProgramStateRef State,
- const Summary &Summary) const {
+ /// note. The description should not mention the argument (getArgNo).
+ /// See StdLibraryFunctionsChecker::reportBug about how this function is
+ /// used (this function is used not only there).
+ virtual void describe(DescriptionKind DK, const CallEvent &Call,
+ ProgramStateRef State, const Summary &Summary,
+ llvm::raw_ostream &Out) const {
// There are some descendant classes that are not used as argument
// constraints, e.g. ComparisonConstraint. In that case we can safely
// ignore the implementation of this function.
@@ -174,6 +176,31 @@ class StdLibraryFunctionsChecker
"Description not implemented for summary case constraints");
}
+ /// Give a description that explains the actual argument value (where the
+ /// current ValueConstraint applies to) to the user. This function should be
+ /// called only when the current constraint is satisfied by the argument.
+ /// It should produce a more precise description than the constraint itself.
+ /// The actual value of the argument and the program state can be used to
+ /// make the description more precise. In the most simple case, if the
+ /// argument has a fixed known value this value can be printed into \p Out,
+ /// this is done by default.
+ /// The function should return true if a description was printed to \p Out,
+ /// otherwise false.
+ /// See StdLibraryFunctionsChecker::reportBug about how this function is
+ /// used.
+ virtual bool describeArgumentValue(const CallEvent &Call,
+ ProgramStateRef State,
+ const Summary &Summary,
+ llvm::raw_ostream &Out) const {
+ if (auto N = getArgSVal(Call, getArgNo()).getAs<NonLoc>()) {
+ if (const llvm::APSInt *Int = N->getAsInteger()) {
+ Out << *Int;
+ return true;
+ }
+ }
+ return false;
+ }
+
/// Return those arguments that should be tracked when we report a bug about
/// argument constraint violation. By default it is the argument that is
/// constrained, however, in some special cases we need to track other
@@ -254,9 +281,13 @@ class StdLibraryFunctionsChecker
const Summary &Summary,
CheckerContext &C) const override;
- std::string describe(DescriptionKind DK, const CallEvent &Call,
- ProgramStateRef State,
- const Summary &Summary) const override;
+ void describe(DescriptionKind DK, const CallEvent &Call,
+ ProgramStateRef State, const Summary &Summary,
+ llvm::raw_ostream &Out) const override;
+
+ bool describeArgumentValue(const CallEvent &Call, ProgramStateRef State,
+ const Summary &Summary,
+ llvm::raw_ostream &Out) const override;
ValueConstraintPtr negate() const override {
RangeConstraint Tmp(*this);
@@ -342,9 +373,13 @@ class StdLibraryFunctionsChecker
const Summary &Summary,
CheckerContext &C) const override;
- std::string describe(DescriptionKind DK, const CallEvent &Call,
- ProgramStateRef State,
- const Summary &Summary) const override;
+ void describe(DescriptionKind DK, const CallEvent &Call,
+ ProgramStateRef State, const Summary &Summary,
+ llvm::raw_ostream &Out) const override;
+
+ bool describeArgumentValue(const CallEvent &Call, ProgramStateRef State,
+ const Summary &Summary,
+ llvm::raw_ostream &Out) const override;
ValueConstraintPtr negate() const override {
NotNullConstraint Tmp(*this);
@@ -396,9 +431,9 @@ class StdLibraryFunctionsChecker
const Summary &Summary,
CheckerContext &C) const override;
- std::string describe(DescriptionKind DK, const CallEvent &Call,
- ProgramStateRef State,
- const Summary &Summary) const override;
+ void describe(DescriptionKind DK, const CallEvent &Call,
+ ProgramStateRef State, const Summary &Summary,
+ llvm::raw_ostream &Out) const override;
std::vector<ArgNo> getArgsToTrack() const override {
std::vector<ArgNo> Result{ArgN};
@@ -773,8 +808,20 @@ class StdLibraryFunctionsChecker
return;
assert(Call.getDecl() &&
"Function found in summary must have a declaration available");
- std::string Msg = VC->describe(ValueConstraint::DescriptionKind::Violation,
- Call, C.getState(), Summary);
+ SmallString<256> Msg;
+ llvm::raw_svector_ostream MsgOs(Msg);
+
+ MsgOs << "The ";
+ printArgDesc(VC->getArgNo(), MsgOs);
+ MsgOs << " to '" << getFunctionName(Call) << "' ";
+ bool ValuesPrinted =
+ NegatedVC->describeArgumentValue(Call, N->getState(), Summary, MsgOs);
+ if (ValuesPrinted)
+ MsgOs << " but ";
+ else
+ MsgOs << "is out of the accepted range; It ";
+ VC->describe(ValueConstraint::Violation, Call, C.getState(), Summary,
+ MsgOs);
Msg[0] = toupper(Msg[0]);
if (!BT_InvalidArg)
BT_InvalidArg = std::make_unique<BugType>(
@@ -816,55 +863,37 @@ static BasicValueFactory &getBVF(ProgramStateRef State) {
} // end of anonymous namespace
-SmallString<8>
-StdLibraryFunctionsChecker::getArgDesc(StdLibraryFunctionsChecker::ArgNo ArgN) {
- SmallString<8> Result;
- Result += std::to_string(ArgN + 1);
- Result += llvm::getOrdinalSuffix(ArgN + 1);
- Result += " argument";
- return Result;
+void StdLibraryFunctionsChecker::printArgDesc(
+ StdLibraryFunctionsChecker::ArgNo ArgN, llvm::raw_ostream &Out) {
+ Out << std::to_string(ArgN + 1);
+ Out << llvm::getOrdinalSuffix(ArgN + 1);
+ Out << " argument";
}
void StdLibraryFunctionsChecker::appendInsideRangeDesc(llvm::APSInt RMin,
llvm::APSInt RMax,
QualType ArgT,
BasicValueFactory &BVF,
- DescString &Out) {
+ llvm::raw_ostream &Out) {
if (RMin.isZero() && RMax.isZero())
- Out.append("zero");
+ Out << "zero";
else if (RMin == RMax)
- RMin.toString(Out);
+ Out << RMin;
else if (RMin == BVF.getMinValue(ArgT)) {
if (RMax == -1)
- Out.append("< 0");
- else {
- Out.append("<= ");
- RMax.toString(Out);
- }
+ Out << "< 0";
+ else
+ Out << "<= " << RMax;
} else if (RMax == BVF.getMaxValue(ArgT)) {
if (RMin.isOne())
- Out.append("> 0");
- else {
- Out.append(">= ");
- RMin.toString(Out);
- }
+ Out << "> 0";
+ else
+ Out << ">= " << RMin;
} else if (RMin.isNegative() == RMax.isNegative() &&
RMin.getLimitedValue() == RMax.getLimitedValue() - 1) {
- RMin.toString(Out);
- Out.append(" or ");
- RMax.toString(Out);
- } else if (RMin.isNegative() == RMax.isNegative() &&
- RMin.getLimitedValue() == RMax.getLimitedValue() - 2) {
- RMin.toString(Out);
- Out.append(", ");
- (RMin + 1).toString(Out, 10, RMin.isSigned());
- Out.append(" or ");
- RMax.toString(Out);
+ Out << RMin << " or " << RMax;
} else {
- Out.append("between ");
- RMin.toString(Out);
- Out.append(" and ");
- RMax.toString(Out);
+ Out << "between " << RMin << " and " << RMax;
}
}
@@ -872,37 +901,26 @@ void StdLibraryFunctionsChecker::appendOutOfRangeDesc(llvm::APSInt RMin,
llvm::APSInt RMax,
QualType ArgT,
BasicValueFactory &BVF,
- DescString &Out) {
+ llvm::raw_ostream &Out) {
if (RMin.isZero() && RMax.isZero())
- Out.append("nonzero");
+ Out << "nonzero";
else if (RMin == RMax) {
- Out.append("not equal to ");
- RMin.toString(Out);
+ Out << "not equal to " << RMin;
} else if (RMin == BVF.getMinValue(ArgT)) {
if (RMax == -1)
- Out.append(">= 0");
- else {
- Out.append("> ");
- RMax.toString(Out);
- }
+ Out << ">= 0";
+ else
+ Out << "> " << RMax;
} else if (RMax == BVF.getMaxValue(ArgT)) {
if (RMin.isOne())
- Out.append("<= 0");
- else {
- Out.append("< ");
- RMin.toString(Out);
- }
+ Out << "<= 0";
+ else
+ Out << "< " << RMin;
} else if (RMin.isNegative() == RMax.isNegative() &&
RMin.getLimitedValue() == RMax.getLimitedValue() - 1) {
- Out.append("not ");
- RMin.toString(Out);
- Out.append(" and not ");
- RMax.toString(Out);
+ Out << "not " << RMin << " and not " << RMax;
} else {
- Out.append("not between ");
- RMin.toString(Out);
- Out.append(" and ");
- RMax.toString(Out);
+ Out << "not between " << RMin << " and " << RMax;
}
}
@@ -981,42 +999,77 @@ ProgramStateRef StdLibraryFunctionsChecker::RangeConstraint::apply(
return State;
}
-std::string StdLibraryFunctionsChecker::RangeConstraint::describe(
+void StdLibraryFunctionsChecker::RangeConstraint::describe(
DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
- const Summary &Summary) const {
+ const Summary &Summary, llvm::raw_ostream &Out) const {
BasicValueFactory &BVF = getBVF(State);
QualType T = Summary.getArgType(getArgNo());
- DescString Result;
- const auto Violation = ValueConstraint::DescriptionKind::Violation;
-
- Result += "the ";
- Result += getArgDesc(ArgN);
- Result += " to '";
- Result += getFunctionName(Call);
- Result += DK == Violation ? "' should be " : "' is ";
+
+ Out << ((DK == Violation) ? "should be " : "is ");
if (!Description.empty()) {
- Result += Description;
+ Out << Description;
} else {
unsigned I = Ranges.size();
if (Kind == WithinRange) {
for (const std::pair<RangeInt, RangeInt> &R : Ranges) {
appendInsideRangeDesc(BVF.getValue(R.first, T),
- BVF.getValue(R.second, T), T, BVF, Result);
+ BVF.getValue(R.second, T), T, BVF, Out);
if (--I > 0)
- Result += " or ";
+ Out << " or ";
}
} else {
for (const std::pair<RangeInt, RangeInt> &R : Ranges) {
appendOutOfRangeDesc(BVF.getValue(R.first, T),
- BVF.getValue(R.second, T), T, BVF, Result);
+ BVF.getValue(R.second, T), T, BVF, Out);
if (--I > 0)
- Result += " and ";
+ Out << " and ";
}
}
}
+}
+
+bool StdLibraryFunctionsChecker::RangeConstraint::describeArgumentValue(
+ const CallEvent &Call, ProgramStateRef State, const Summary &Summary,
+ llvm::raw_ostream &Out) const {
+ unsigned int NRanges = 0;
+ bool HaveAllRanges = true;
+
+ ProgramStateManager &Mgr = State->getStateManager();
+ BasicValueFactory &BVF = Mgr.getSValBuilder().getBasicValueFactory();
+ ConstraintManager &CM = Mgr.getConstraintManager();
+ SVal V = getArgSVal(Call, getArgNo());
- return Result.c_str();
+ if (auto N = V.getAs<NonLoc>()) {
+ if (const llvm::APSInt *Int = N->getAsInteger()) {
+ Out << "is ";
+ Out << *Int;
+ return true;
+ }
+ QualType T = Summary.getArgType(getArgNo());
+ SmallString<128> MoreInfo;
+ llvm::raw_svector_ostream MoreInfoOs(MoreInfo);
+ auto ApplyF = [&](const llvm::APSInt &Min, const llvm::APSInt &Max) {
+ if (CM.assumeInclusiveRange(State, *N, Min, Max, true)) {
+ if (NRanges > 0)
+ MoreInfoOs << " or ";
+ appendInsideRangeDesc(Min, Max, T, BVF, MoreInfoOs);
+ ++NRanges;
+ } else {
+ HaveAllRanges = false;
+ }
+ return true;
+ };
+
+ applyOnRange(Kind, BVF, T, ApplyF);
+ assert(NRanges > 0);
+ if (!HaveAllRanges || NRanges == 1) {
+ Out << "is ";
+ Out << MoreInfo;
+ return true;
+ }
+ }
+ return false;
}
ProgramStateRef StdLibraryFunctionsChecker::ComparisonConstraint::apply(
@@ -1055,17 +1108,23 @@ ProgramStateRef StdLibraryFunctionsChecker::NotNullConstraint::apply(
return State->assume(L, CannotBeNull);
}
-std::string StdLibraryFunctionsChecker::NotNullConstraint::describe(
+void StdLibraryFunctionsChecker::NotNullConstraint::describe(
DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
- const Summary &Summary) const {
- SmallString<48> Result;
- const auto Violation = ValueConstraint::DescriptionKind::Violation;
- Result += "the ";
- Result += getArgDesc(ArgN);
- Result += " to '";
- Result += getFunctionName(Call);
- Result += DK == Violation ? "' should not be NULL" : "' is not NULL";
- return Result.c_str();
+ const Summary &Summary, llvm::raw_ostream &Out) const {
+ assert(CannotBeNull &&
+ "Describe should not be used when the value must be NULL");
+ if (DK == Violation)
+ Out << "should not be NULL";
+ else
+ Out << "is not NULL";
+}
+
+bool StdLibraryFunctionsChecker::NotNullConstraint::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");
+ Out << "is NULL";
+ return true;
}
ProgramStateRef StdLibraryFunctionsChecker::BufferSizeConstraint::apply(
@@ -1110,28 +1169,21 @@ ProgramStateRef StdLibraryFunctionsChecker::BufferSizeConstraint::apply(
llvm_unreachable("Size argument or the dynamic size is Undefined");
}
-std::string StdLibraryFunctionsChecker::BufferSizeConstraint::describe(
+void StdLibraryFunctionsChecker::BufferSizeConstraint::describe(
DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
- const Summary &Summary) const {
- SmallString<96> Result;
- const auto Violation = ValueConstraint::DescriptionKind::Violation;
- Result += "the size of the ";
- Result += getArgDesc(ArgN);
- Result += " to '";
- Result += getFunctionName(Call);
- Result += DK == Violation ? "' should be " : "' is ";
- Result += "equal to or greater than ";
+ const Summary &Summary, llvm::raw_ostream &Out) const {
+ Out << ((DK == Violation) ? "should be " : "is ");
+ Out << "a buffer with size equal to or greater than ";
if (ConcreteSize) {
- ConcreteSize->toString(Result);
+ Out << *ConcreteSize;
} else if (SizeArgN) {
- Result += "the value of the ";
- Result += getArgDesc(*SizeArgN);
+ Out << "the value of the ";
+ printArgDesc(*SizeArgN, Out);
if (SizeMultiplierArgN) {
- Result += " times the ";
- Result += getArgDesc(*SizeMultiplierArgN);
+ Out << " times the ";
+ printArgDesc(*SizeMultiplierArgN, Out);
}
}
- return Result.c_str();
}
void StdLibraryFunctionsChecker::checkPreCall(const CallEvent &Call,
@@ -1164,10 +1216,15 @@ void StdLibraryFunctionsChecker::checkPreCall(const CallEvent &Call,
assert(SuccessSt);
NewState = SuccessSt;
if (NewState != State) {
- SmallString<64> Msg;
- Msg += "Assuming ";
- Msg += Constraint->describe(ValueConstraint::DescriptionKind::Assumption,
- Call, NewState, Summary);
+ SmallString<128> Msg;
+ llvm::raw_svector_ostream Os(Msg);
+ Os << "Assuming that the ";
+ printArgDesc(Constraint->getArgNo(), Os);
+ Os << " to '";
+ Os << getFunctionName(Call);
+ Os << "' ";
+ Constraint->describe(ValueConstraint::Assumption, Call, NewState, Summary,
+ Os);
const auto ArgSVal = Call.getArgSVal(Constraint->getArgNo());
NewNode = C.addTransition(
NewState, NewNode,
@@ -3471,6 +3528,27 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
ErrnoIrrelevant, "Function returns 0")
.Case({ReturnValueCondition(WithinRange, SingleValue(1))},
ErrnoIrrelevant, "Function returns 1"));
+ addToFunctionSummaryMap(
+ "__test_case_range_1_2__4_6",
+ Signature(ArgTypes{IntTy}, RetType{IntTy}),
+ Summary(EvalCallAsPure)
+ .Case({ArgumentCondition(0U, WithinRange,
+ IntRangeVector{{IntMin, 0}, {3, 3}}),
+ ReturnValueCondition(WithinRange, SingleValue(1))},
+ ErrnoIrrelevant)
+ .Case({ArgumentCondition(0U, WithinRange,
+ IntRangeVector{{3, 3}, {7, IntMax}}),
+ ReturnValueCondition(WithinRange, SingleValue(2))},
+ ErrnoIrrelevant)
+ .Case({ArgumentCondition(0U, WithinRange,
+ IntRangeVector{{IntMin, 0}, {7, IntMax}}),
+ ReturnValueCondition(WithinRange, SingleValue(3))},
+ ErrnoIrrelevant)
+ .Case({ArgumentCondition(
+ 0U, WithinRange,
+ IntRangeVector{{IntMin, 0}, {3, 3}, {7, IntMax}}),
+ ReturnValueCondition(WithinRange, SingleValue(4))},
+ ErrnoIrrelevant));
}
SummariesInitialized = true;
diff --git a/clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp b/clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
index 2ddcf7a3136fb..f9d901fca9da1 100644
--- a/clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
+++ b/clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp
@@ -19,7 +19,7 @@ int clang_analyzer_getExtent(void *);
// Check NotNullConstraint assumption notes.
int __not_null(int *);
int test_not_null_note(int *x, int y) {
- __not_null(x); // expected-note{{Assuming the 1st argument to '__not_null' is not NULL}}
+ __not_null(x); // expected-note{{Assuming that the 1st argument to '__not_null' is not NULL}}
if (x) // expected-note{{'x' is non-null}} \
// expected-note{{Taking true branch}}
if (!y) // expected-note{{Assuming 'y' is 0}} \
@@ -33,7 +33,7 @@ int test_not_null_note(int *x, int y) {
// Check the RangeConstraint assumption notes.
int __single_val_0(int); // [0, 0]
int test_range_constraint_note(int x, int y) {
- __single_val_0(x); // expected-note{{Assuming the 1st argument to '__single_val_0' is zero}}
+ __single_val_0(x); // expected-note{{Assuming that the 1st argument to '__single_val_0' is zero}}
return y / x; // expected-warning{{Division by zero}} \
// expected-note{{Division by zero}}
}
@@ -41,7 +41,7 @@ int test_range_constraint_note(int x, int y) {
// Check the BufferSizeConstraint assumption notes.
int __buf_size_arg_constraint_concrete(const void *buf); // size of buf must be >= 10
void test_buffer_size_note(char *buf, int y) {
- __buf_size_arg_constraint_concrete(buf); // expected-note {{Assuming the size of the 1st argument to '__buf_size_arg_constraint_concrete' is equal to or greater than 10}}
+ __buf_size_arg_constraint_concrete(buf); // expected-note {{Assuming that the 1st argument to '__buf_size_arg_constraint_concrete' is a buffer with size equal to or greater than 10}}
clang_analyzer_eval(clang_analyzer_getExtent(buf) >= 10); // expected-warning{{TRUE}} \
// expected-note{{TRUE}}
diff --git a/clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp b/clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp
index 2a9b4821b8fdb..a1b956e009f40 100644
--- a/clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp
+++ b/clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp
@@ -15,7 +15,7 @@
int __not_null(int *);
void test_not_null(int *x) {
__not_null(nullptr); // \
- // expected-warning{{The 1st argument to '__not_null' should not be NULL}}
+ // expected-warning{{The 1st argument to '__not_null' is NULL but should not be NULL [}}
}
// Check the BufferSizeConstraint violation notes.
@@ -28,19 +28,19 @@ void test_buffer_size(int x) {
case 1: {
char buf[9];
__buf_size_arg_constraint_concrete(buf); // \
- // expected-warning{{The size of the 1st argument to '__buf_size_arg_constraint_concrete' should be equal to or greater than 10}}
+ // expected-warning{{The 1st argument to '__buf_size_arg_constraint_concrete' is out of the accepted range; It should be a buffer with size equal to or greater than 10 [}}
break;
}
case 2: {
char buf[3];
__buf_size_arg_constraint(buf, 4); // \
- // expected-warning{{The size of the 1st argument to '__buf_size_arg_constraint' should be equal to or greater than the value of the 2nd argument}}
+ // expected-warning{{The 1st argument to '__buf_size_arg_constraint' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument}}
break;
}
case 3: {
char buf[3];
__buf_size_arg_constraint_mul(buf, 4, 2); // \
- // expected-warning{{The size of the 1st argument to '__buf_size_arg_constraint_mul' should be equal to or greater than the value of the 2nd argument times the 3rd argument}}
+ // expected-warning{{The 1st argument to '__buf_size_arg_constraint_mul' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument times the 3rd argument}}
break;
}
}
@@ -78,34 +78,36 @@ int __range_out_minf_1(int); // [-inf, 1]
int __range_out_1_2__4_6(int); // [1, 2], [4, 6]
int __range_out_1_2__4_inf(int); // [1, 2], [4, inf]
+int __test_case_range_1_2__4_6(int);
+
void test_range_values(int x) {
switch (x) {
case 0:
- __single_val_0(1); // expected-warning{{should be zero}}
+ __single_val_0(1); // expected-warning{{is 1 but should be zero}}
break;
case 1:
- __single_val_1(2); // expected-warning{{should be 1}}
+ __single_val_1(2); // expected-warning{{is 2 but should be 1}}
break;
case 2:
- __range_1_2(3); // expected-warning{{should be 1 or 2}}
+ __range_1_2(3); // expected-warning{{is 3 but should be 1 or 2}}
break;
case 3:
- __range_m1_1(3); // expected-warning{{should be between -1 and 1}}
+ __range_m1_1(3); // expected-warning{{is 3 but should be between -1 and 1}}
break;
case 4:
- __range_m2_m1(1); // expected-warning{{should be -2 or -1}}
+ __range_m2_m1(1); // expected-warning{{is 1 but should be -2 or -1}}
break;
case 5:
- __range_m10_10(11); // expected-warning{{should be between -10 and 10}}
+ __range_m10_10(11); // expected-warning{{is 11 but should be between -10 and 10}}
break;
case 6:
- __range_m10_10(-11); // expected-warning{{should be between -10 and 10}}
+ __range_m10_10(-11); // expected-warning{{is -11 but should be between -10 and 10}}
break;
case 7:
- __range_1_2__4_6(3); // expected-warning{{should be 1 or 2 or 4, 5 or 6}}
+ __range_1_2__4_6(3); // expected-warning{{is 3 but should be 1 or 2 or between 4 and 6}}
break;
case 8:
- __range_1_2__4_inf(3); // expected-warning{{should be 1 or 2 or >= 4}}
+ __range_1_2__4_inf(3); // expected-warning{{is 3 but should be 1 or 2 or >= 4}}
break;
}
}
@@ -113,22 +115,22 @@ void test_range_values(int x) {
void test_range_values_inf(int x) {
switch (x) {
case 1:
- __range_m1_inf(-2); // expected-warning{{should be >= -1}}
+ __range_m1_inf(-2); // expected-warning{{is -2 but should be >= -1}}
break;
case 2:
- __range_0_inf(-1); // expected-warning{{should be >= 0}}
+ __range_0_inf(-1); // expected-warning{{is -1 but should be >= 0}}
break;
case 3:
- __range_1_inf(0); // expected-warning{{should be > 0}}
+ __range_1_inf(0); // expected-warning{{is 0 but should be > 0}}
break;
case 4:
- __range_minf_m1(0); // expected-warning{{should be < 0}}
+ __range_minf_m1(0); // expected-warning{{is 0 but should be < 0}}
break;
case 5:
- __range_minf_0(1); // expected-warning{{should be <= 0}}
+ __range_minf_0(1); // expected-warning{{is 1 but should be <= 0}}
break;
case 6:
- __range_minf_1(2); // expected-warning{{should be <= 1}}
+ __range_minf_1(2); // expected-warning{{is 2 but should be <= 1}}
break;
}
}
@@ -136,28 +138,28 @@ void test_range_values_inf(int x) {
void test_range_values_out(int x) {
switch (x) {
case 0:
- __single_val_out_0(0); // expected-warning{{should be nonzero}}
+ __single_val_out_0(0); // expected-warning{{is 0 but should be nonzero}}
break;
case 1:
- __single_val_out_1(1); // expected-warning{{should be not equal to 1}}
+ __single_val_out_1(1); // expected-warning{{is 1 but should be not equal to 1}}
break;
case 2:
- __range_out_1_2(2); // expected-warning{{should be not 1 and not 2}}
+ __range_out_1_2(2); // expected-warning{{is 2 but should be not 1 and not 2}}
break;
case 3:
- __range_out_m1_1(-1); // expected-warning{{should be not between -1 and 1}}
+ __range_out_m1_1(-1); // expected-warning{{is -1 but should be not between -1 and 1}}
break;
case 4:
- __range_out_m2_m1(-2); // expected-warning{{should be not -2 and not -1}}
+ __range_out_m2_m1(-2); // expected-warning{{is -2 but should be not -2 and not -1}}
break;
case 5:
- __range_out_m10_10(0); // expected-warning{{should be not between -10 and 10}}
+ __range_out_m10_10(0); // expected-warning{{is 0 but should be not between -10 and 10}}
break;
case 6:
- __range_out_1_2__4_6(1); // expected-warning{{should be not 1 and not 2 and not between 4 and 6}}
+ __range_out_1_2__4_6(1); // expected-warning{{is 1 but should be not 1 and not 2 and not between 4 and 6}}
break;
case 7:
- __range_out_1_2__4_inf(4); // expected-warning{{should be not 1 and not 2 and < 4}}
+ __range_out_1_2__4_inf(4); // expected-warning{{is 4 but should be not 1 and not 2 and < 4}}
break;
}
}
@@ -165,22 +167,71 @@ void test_range_values_out(int x) {
void test_range_values_out_inf(int x) {
switch (x) {
case 1:
- __range_out_minf_m1(-1); // expected-warning{{should be >= 0}}
+ __range_out_minf_m1(-1); // expected-warning{{is -1 but should be >= 0}}
break;
case 2:
- __range_out_minf_0(0); // expected-warning{{should be > 0}}
+ __range_out_minf_0(0); // expected-warning{{is 0 but should be > 0}}
break;
case 3:
- __range_out_minf_1(1); // expected-warning{{should be > 1}}
+ __range_out_minf_1(1); // expected-warning{{is 1 but should be > 1}}
break;
case 4:
- __range_out_m1_inf(-1); // expected-warning{{should be < -1}}
+ __range_out_m1_inf(-1); // expected-warning{{is -1 but should be < -1}}
break;
case 5:
- __range_out_0_inf(0); // expected-warning{{should be < 0}}
+ __range_out_0_inf(0); // expected-warning{{is 0 but should be < 0}}
break;
case 6:
- __range_out_1_inf(1); // expected-warning{{should be <= 0}}
+ __range_out_1_inf(1); // expected-warning{{is 1 but should be <= 0}}
break;
}
}
+
+void test_explanation(int x, int y) {
+ switch (y) {
+ case 1:
+ if (x > 0)
+ __single_val_0(x); // expected-warning{{is > 0 but should be zero [}}
+ return;
+ case 2:
+ if (x < 0)
+ __single_val_0(x); // expected-warning{{is < 0 but should be zero [}}
+ return;
+ case 3:
+ if (x < -1)
+ __single_val_0(x); // expected-warning{{is < 0 but should be zero [}}
+ return;
+ case 4:
+ if (x != 0)
+ __single_val_0(x); // expected-warning{{is out of the accepted range; It should be zero [}}
+ return;
+ case 5:
+ if (x == 3)
+ __range_1_2__4_6(x); // expected-warning{{is 3 but should be 1 or 2 or between 4 and 6 [}}
+ return;
+ case 6:
+ if (x > 6)
+ __range_1_2__4_6(x); // expected-warning{{is >= 7 but should be 1 or 2 or between 4 and 6 [}}
+ return;
+ case 7:
+ if (x < 1)
+ __range_1_2__4_6(x); // expected-warning{{is <= 0 but should be 1 or 2 or between 4 and 6 [}}
+ return;
+ case 8:
+ if (__test_case_range_1_2__4_6(x) == 1)
+ __range_1_2__4_6(x); // expected-warning{{is 3 or <= 0 but should be 1 or 2 or between 4 and 6 [}}
+ return;
+ case 9:
+ if (__test_case_range_1_2__4_6(x) == 2)
+ __range_1_2__4_6(x); // expected-warning{{is 3 or >= 7 but should be 1 or 2 or between 4 and 6 [}}
+ return;
+ case 10:
+ if (__test_case_range_1_2__4_6(x) == 3)
+ __range_1_2__4_6(x); // expected-warning{{is <= 0 or >= 7 but should be 1 or 2 or between 4 and 6 [}}
+ return;
+ case 11:
+ if (__test_case_range_1_2__4_6(x) == 4)
+ __range_1_2__4_6(x); // expected-warning{{is out of the accepted range; It should be 1 or 2 or between 4 and 6 [}}
+ return;
+ }
+}
diff --git a/clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c b/clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c
index 38b5f03e46551..b2377363dbb63 100644
--- a/clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c
+++ b/clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c
@@ -16,8 +16,8 @@ void test_buf_size_concrete(void) {
char buf[3]; // bugpath-note{{'buf' initialized here}}
int s = 4; // bugpath-note{{'s' initialized to 4}}
__buf_size_arg_constraint(buf, s); // \
- // bugpath-warning{{The size of the 1st argument to '__buf_size_arg_constraint' should be equal to or greater than the value of the 2nd argument}} \
- // bugpath-note{{The size of the 1st argument to '__buf_size_arg_constraint' should be equal to or greater than the value of the 2nd argument}}
+ // bugpath-warning{{The 1st argument to '__buf_size_arg_constraint' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument}} \
+ // bugpath-note{{The 1st argument to '__buf_size_arg_constraint' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument}}
}
int __buf_size_arg_constraint_mul(const void *, size_t, size_t);
@@ -26,6 +26,6 @@ void test_buf_size_concrete_with_multiplication(void) {
int s1 = 4; // bugpath-note{{'s1' initialized to 4}}
int s2 = sizeof(short); // bugpath-note{{'s2' initialized to}}
__buf_size_arg_constraint_mul(buf, s1, s2); // \
- // bugpath-warning{{The size of the 1st argument to '__buf_size_arg_constraint_mul' should be equal to or greater than the value of the 2nd argument times the 3rd argument}} \
- // bugpath-note{{The size of the 1st argument to '__buf_size_arg_constraint_mul' should be equal to or greater than the value of the 2nd argument times the 3rd argument}}
+ // bugpath-warning{{The 1st argument to '__buf_size_arg_constraint_mul' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument times the 3rd argument}} \
+ // bugpath-note{{The 1st argument to '__buf_size_arg_constraint_mul' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument times the 3rd argument}}
}
diff --git a/clang/test/Analysis/std-c-library-functions-arg-constraints.c b/clang/test/Analysis/std-c-library-functions-arg-constraints.c
index cff435d627530..83666f3fe91e9 100644
--- a/clang/test/Analysis/std-c-library-functions-arg-constraints.c
+++ b/clang/test/Analysis/std-c-library-functions-arg-constraints.c
@@ -30,9 +30,9 @@ int isalnum(int);
void test_alnum_concrete(int v) {
int ret = isalnum(256); // \
- // report-warning{{The 1st argument to 'isalnum' should be an unsigned char value or EOF}} \
- // bugpath-warning{{The 1st argument to 'isalnum' should be an unsigned char value or EOF}} \
- // bugpath-note{{The 1st argument to 'isalnum' should be an unsigned char value or EOF}}
+ // report-warning{{The 1st argument to 'isalnum' is 256 but should be an unsigned char value or EOF}} \
+ // bugpath-warning{{The 1st argument to 'isalnum' is 256 but should be an unsigned char value or EOF}} \
+ // bugpath-note{{The 1st argument to 'isalnum' is 256 but should be an unsigned char value or EOF}}
(void)ret;
}
@@ -55,9 +55,9 @@ void test_alnum_symbolic2(int x) {
// bugpath-note{{Taking true branch}}
int ret = isalnum(x); // \
- // report-warning{{The 1st argument to 'isalnum' should be an unsigned char value or EOF}} \
- // bugpath-warning{{The 1st argument to 'isalnum' should be an unsigned char value or EOF}} \
- // bugpath-note{{The 1st argument to 'isalnum' should be an unsigned char value or EOF}}
+ // report-warning{{The 1st argument to 'isalnum' is >= 256 but should be an unsigned char value or EOF}} \
+ // bugpath-warning{{The 1st argument to 'isalnum' is >= 256 but should be an unsigned char value or EOF}} \
+ // bugpath-note{{The 1st argument to 'isalnum' is >= 256 but should be an unsigned char value or EOF}}
(void)ret;
}
@@ -67,9 +67,9 @@ int toupper(int);
void test_toupper_concrete(int v) {
int ret = toupper(256); // \
- // report-warning{{The 1st argument to 'toupper' should be an unsigned char value or EOF}} \
- // bugpath-warning{{The 1st argument to 'toupper' should be an unsigned char value or EOF}} \
- // bugpath-note{{The 1st argument to 'toupper' should be an unsigned char value or EOF}}
+ // report-warning{{The 1st argument to 'toupper' is 256 but should be an unsigned char value or EOF}} \
+ // bugpath-warning{{The 1st argument to 'toupper' is 256 but should be an unsigned char value or EOF}} \
+ // bugpath-note{{The 1st argument to 'toupper' is 256 but should be an unsigned char value or EOF}}
(void)ret;
}
@@ -91,9 +91,9 @@ void test_toupper_symbolic2(int x) {
// bugpath-note{{Taking true branch}}
int ret = toupper(x); // \
- // report-warning{{The 1st argument to 'toupper' should be an unsigned char value or EOF}} \
- // bugpath-warning{{The 1st argument to 'toupper' should be an unsigned char value or EOF}} \
- // bugpath-note{{The 1st argument to 'toupper' should be an unsigned char value or EOF}}
+ // report-warning{{The 1st argument to 'toupper' is >= 256 but should be an unsigned char value or EOF}} \
+ // bugpath-warning{{The 1st argument to 'toupper' is >= 256 but should be an unsigned char value or EOF}} \
+ // bugpath-note{{The 1st argument to 'toupper' is >= 256 but should be an unsigned char value or EOF}}
(void)ret;
}
@@ -103,9 +103,9 @@ int tolower(int);
void test_tolower_concrete(int v) {
int ret = tolower(256); // \
- // report-warning{{The 1st argument to 'tolower' should be an unsigned char value or EOF}} \
- // bugpath-warning{{The 1st argument to 'tolower' should be an unsigned char value or EOF}} \
- // bugpath-note{{The 1st argument to 'tolower' should be an unsigned char value or EOF}}
+ // report-warning{{The 1st argument to 'tolower' is 256 but should be an unsigned char value or EOF}} \
+ // bugpath-warning{{The 1st argument to 'tolower' is 256 but should be an unsigned char value or EOF}} \
+ // bugpath-note{{The 1st argument to 'tolower' is 256 but should be an unsigned char value or EOF}}
(void)ret;
}
@@ -127,9 +127,9 @@ void test_tolower_symbolic2(int x) {
// bugpath-note{{Taking true branch}}
int ret = tolower(x); // \
- // report-warning{{The 1st argument to 'tolower' should be an unsigned char value or EOF}} \
- // bugpath-warning{{The 1st argument to 'tolower' should be an unsigned char value or EOF}} \
- // bugpath-note{{The 1st argument to 'tolower' should be an unsigned char value or EOF}}
+ // report-warning{{The 1st argument to 'tolower' is >= 256 but should be an unsigned char value or EOF}} \
+ // bugpath-warning{{The 1st argument to 'tolower' is >= 256 but should be an unsigned char value or EOF}} \
+ // bugpath-note{{The 1st argument to 'tolower' is >= 256 but should be an unsigned char value or EOF}}
(void)ret;
}
@@ -139,9 +139,9 @@ int toascii(int);
void test_toascii_concrete(int v) {
int ret = toascii(256); // \
- // report-warning{{The 1st argument to 'toascii' should be an unsigned char value or EOF}} \
- // bugpath-warning{{The 1st argument to 'toascii' should be an unsigned char value or EOF}} \
- // bugpath-note{{The 1st argument to 'toascii' should be an unsigned char value or EOF}}
+ // report-warning{{The 1st argument to 'toascii' is 256 but should be an unsigned char value or EOF}} \
+ // bugpath-warning{{The 1st argument to 'toascii' is 256 but should be an unsigned char value or EOF}} \
+ // bugpath-note{{The 1st argument to 'toascii' is 256 but should be an unsigned char value or EOF}}
(void)ret;
}
@@ -163,9 +163,9 @@ void test_toascii_symbolic2(int x) {
// bugpath-note{{Taking true branch}}
int ret = toascii(x); // \
- // report-warning{{The 1st argument to 'toascii' should be an unsigned char value or EOF}} \
- // bugpath-warning{{The 1st argument to 'toascii' should be an unsigned char value or EOF}} \
- // bugpath-note{{The 1st argument to 'toascii' should be an unsigned char value or EOF}}
+ // report-warning{{The 1st argument to 'toascii' is >= 256 but should be an unsigned char value or EOF}} \
+ // bugpath-warning{{The 1st argument to 'toascii' is >= 256 but should be an unsigned char value or EOF}} \
+ // bugpath-note{{The 1st argument to 'toascii' is >= 256 but should be an unsigned char value or EOF}}
(void)ret;
}
@@ -176,9 +176,9 @@ typedef typeof(sizeof(int)) size_t;
size_t fread(void *restrict, size_t, size_t, FILE *restrict);
void test_notnull_concrete(FILE *fp) {
fread(0, sizeof(int), 10, fp); // \
- // report-warning{{The 1st argument to 'fread' should not be NULL}} \
- // bugpath-warning{{The 1st argument to 'fread' should not be NULL}} \
- // bugpath-note{{The 1st argument to 'fread' should not be NULL}}
+ // report-warning{{The 1st argument to 'fread' is NULL but should not be NULL}} \
+ // bugpath-warning{{The 1st argument to 'fread' is NULL but should not be NULL}} \
+ // bugpath-note{{The 1st argument to 'fread' is NULL but should not be NULL}}
}
void test_notnull_symbolic(FILE *fp, int *buf) {
fread(buf, sizeof(int), 10, fp);
@@ -192,9 +192,9 @@ void test_notnull_symbolic2(FILE *fp, int *buf) {
if (!buf) // bugpath-note{{Assuming 'buf' is null}} \
// bugpath-note{{Taking true branch}}
fread(buf, sizeof(int), 10, fp); // \
- // report-warning{{The 1st argument to 'fread' should not be NULL}} \
- // bugpath-warning{{The 1st argument to 'fread' should not be NULL}} \
- // bugpath-note{{The 1st argument to 'fread' should not be NULL}}
+ // report-warning{{The 1st argument to 'fread' is NULL but should not be NULL}} \
+ // bugpath-warning{{The 1st argument to 'fread' is NULL but should not be NULL}} \
+ // bugpath-note{{The 1st argument to 'fread' is NULL but should not be NULL}}
}
void test_no_node_after_bug(FILE *fp, size_t size, size_t n, void *buf) {
if (fp) // \
@@ -202,9 +202,9 @@ void test_no_node_after_bug(FILE *fp, size_t size, size_t n, void *buf) {
// bugpath-note{{Taking false branch}}
return;
size_t ret = fread(buf, size, n, fp); // \
- // report-warning{{The 4th argument to 'fread' should not be NULL}} \
- // bugpath-warning{{The 4th argument to 'fread' should not be NULL}} \
- // bugpath-note{{The 4th argument to 'fread' should not be NULL}}
+ // report-warning{{The 4th argument to 'fread' is NULL but should not be NULL}} \
+ // bugpath-warning{{The 4th argument to 'fread' is NULL but should not be NULL}} \
+ // bugpath-note{{The 4th argument to 'fread' is NULL but should not be NULL}}
clang_analyzer_warnIfReached(); // not reachable
}
@@ -220,9 +220,9 @@ void ARR38_C_F(FILE *file) {
// The 3rd parameter should be the number of elements to read, not
// the size in bytes.
fread(wbuf, size, nitems, file); // \
- // report-warning{{The size of the 1st argument to 'fread' should be equal to or greater than the value of the 2nd argument times the 3rd argument}} \
- // bugpath-warning{{The size of the 1st argument to 'fread' should be equal to or greater than the value of the 2nd argument times the 3rd argument}} \
- // bugpath-note{{The size of the 1st argument to 'fread' should be equal to or greater than the value of the 2nd argument times the 3rd argument}}
+ // report-warning{{The 1st argument to 'fread' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument times the 3rd argument}} \
+ // bugpath-warning{{The 1st argument to 'fread' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument times the 3rd argument}} \
+ // bugpath-note{{The 1st argument to 'fread' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument times the 3rd argument}}
}
int __two_constrained_args(int, int);
@@ -255,18 +255,18 @@ void test_multiple_constraints_on_same_arg(int x) {
int __variadic(void *stream, const char *format, ...);
void test_arg_constraint_on_variadic_fun(void) {
__variadic(0, "%d%d", 1, 2); // \
- // report-warning{{The 1st argument to '__variadic' should not be NULL}} \
- // bugpath-warning{{The 1st argument to '__variadic' should not be NULL}} \
- // bugpath-note{{The 1st argument to '__variadic' should not be NULL}}
+ // report-warning{{The 1st argument to '__variadic' is NULL but should not be NULL}} \
+ // bugpath-warning{{The 1st argument to '__variadic' is NULL but should not be NULL}} \
+ // bugpath-note{{The 1st argument to '__variadic' is NULL but should not be NULL}}
}
int __buf_size_arg_constraint(const void *, size_t);
void test_buf_size_concrete(void) {
char buf[3]; // bugpath-note{{'buf' initialized here}}
__buf_size_arg_constraint(buf, 4); // \
- // report-warning{{The size of the 1st argument to '__buf_size_arg_constraint' should be equal to or greater than the value of the 2nd argument}} \
- // bugpath-warning{{The size of the 1st argument to '__buf_size_arg_constraint' should be equal to or greater than the value of the 2nd argument}} \
- // bugpath-note{{The size of the 1st argument to '__buf_size_arg_constraint' should be equal to or greater than the value of the 2nd argument}}
+ // report-warning{{The 1st argument to '__buf_size_arg_constraint' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument}} \
+ // bugpath-warning{{The 1st argument to '__buf_size_arg_constraint' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument}} \
+ // bugpath-note{{The 1st argument to '__buf_size_arg_constraint' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument}}
}
void test_buf_size_symbolic(int s) {
char buf[3];
@@ -291,9 +291,9 @@ int __buf_size_arg_constraint_mul(const void *, size_t, size_t);
void test_buf_size_concrete_with_multiplication(void) {
short buf[3]; // bugpath-note{{'buf' initialized here}}
__buf_size_arg_constraint_mul(buf, 4, sizeof(short)); // \
- // report-warning{{The size of the 1st argument to '__buf_size_arg_constraint_mul' should be equal to or greater than the value of the 2nd argument times the 3rd argument}} \
- // bugpath-warning{{The size of the 1st argument to '__buf_size_arg_constraint_mul' should be equal to or greater than the value of the 2nd argument times the 3rd argument}} \
- // bugpath-note{{The size of the 1st argument to '__buf_size_arg_constraint_mul' should be equal to or greater than the value of the 2nd argument times the 3rd argument}}
+ // report-warning{{The 1st argument to '__buf_size_arg_constraint_mul' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument times the 3rd argument}} \
+ // bugpath-warning{{The 1st argument to '__buf_size_arg_constraint_mul' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument times the 3rd argument}} \
+ // bugpath-note{{The 1st argument to '__buf_size_arg_constraint_mul' is out of the accepted range; It should be a buffer with size equal to or greater than the value of the 2nd argument times the 3rd argument}}
}
void test_buf_size_symbolic_with_multiplication(size_t s) {
short buf[3];
@@ -317,7 +317,7 @@ int __buf_size_arg_constraint_concrete(const void *);
void test_min_buf_size(void) {
char buf[9];// bugpath-note{{'buf' initialized here}}
__buf_size_arg_constraint_concrete(buf); // \
- // report-warning{{The size of the 1st argument to '__buf_size_arg_constraint_concrete' should be equal to or greater than 10}} \
- // bugpath-warning{{The size of the 1st argument to '__buf_size_arg_constraint_concrete' should be equal to or greater than 10}} \
- // bugpath-note{{The size of the 1st argument to '__buf_size_arg_constraint_concrete' should be equal to or greater than 10}}
+ // report-warning{{The 1st argument to '__buf_size_arg_constraint_concrete' is out of the accepted range; It should be a buffer with size equal to or greater than 10}} \
+ // bugpath-warning{{The 1st argument to '__buf_size_arg_constraint_concrete' is out of the accepted range; It should be a buffer with size equal to or greater than 10}} \
+ // bugpath-note{{The 1st argument to '__buf_size_arg_constraint_concrete' is out of the accepted range; It should be a buffer with size equal to or greater than 10}}
}
diff --git a/clang/test/Analysis/std-c-library-functions-arg-constraints.cpp b/clang/test/Analysis/std-c-library-functions-arg-constraints.cpp
index 86fa98bf4f10c..48060bf052737 100644
--- a/clang/test/Analysis/std-c-library-functions-arg-constraints.cpp
+++ b/clang/test/Analysis/std-c-library-functions-arg-constraints.cpp
@@ -14,5 +14,5 @@ int __defaultparam(void *, int y = 3);
void test_arg_constraint_on_fun_with_default_param() {
__defaultparam(nullptr); // \
- // expected-warning{{The 1st argument to '__defaultparam' should not be NULL}}
+ // expected-warning{{The 1st argument to '__defaultparam' is NULL but should not be NULL}}
}
diff --git a/clang/test/Analysis/stream-note.c b/clang/test/Analysis/stream-note.c
index cd711bc27711a..199d208cbde82 100644
--- a/clang/test/Analysis/stream-note.c
+++ b/clang/test/Analysis/stream-note.c
@@ -88,8 +88,8 @@ void check_track_null(void) {
fclose(F);
return;
}
- fclose(F); // stdargs-warning {{The 1st argument to 'fclose' should not be NULL}}
- // stdargs-note at -1 {{The 1st argument to 'fclose' should not be NULL}}
+ fclose(F); // stdargs-warning {{The 1st argument to 'fclose' is NULL but should not be NULL}}
+ // stdargs-note at -1 {{The 1st argument to 'fclose' is NULL but should not be NULL}}
}
void check_eof_notes_feof_after_feof(void) {
diff --git a/clang/test/Analysis/stream-stdlibraryfunctionargs.c b/clang/test/Analysis/stream-stdlibraryfunctionargs.c
index 9d1b9244f0f24..6b4a6d10a8f61 100644
--- a/clang/test/Analysis/stream-stdlibraryfunctionargs.c
+++ b/clang/test/Analysis/stream-stdlibraryfunctionargs.c
@@ -42,7 +42,7 @@ void test_freopen(void) {
void test_fread(void) {
FILE *fp = tmpfile();
- size_t ret = fread(buf, size, n, fp); // stdargs-warning{{The 4th argument to 'fread' should not be NULL}}
+ size_t ret = fread(buf, size, n, fp); // stdargs-warning{{The 4th argument to 'fread' is NULL but should not be NULL}}
clang_analyzer_eval(fp != NULL); // any-warning{{TRUE}}
clang_analyzer_eval(ret <= n); // any-warning{{TRUE}}
clang_analyzer_eval(ret == n); // any-warning{{TRUE}} any-warning{{FALSE}}
@@ -52,7 +52,7 @@ void test_fread(void) {
void test_fwrite(void) {
FILE *fp = tmpfile();
- size_t ret = fwrite(buf, size, n, fp); // stdargs-warning{{The 4th argument to 'fwrite' should not be NULL}}
+ size_t ret = fwrite(buf, size, n, fp); // stdargs-warning{{The 4th argument to 'fwrite' is NULL but should not be NULL}}
clang_analyzer_eval(fp != NULL); // any-warning{{TRUE}}
clang_analyzer_eval(ret <= n); // any-warning{{TRUE}}
clang_analyzer_eval(ret == n); // any-warning{{TRUE}} any-warning{{FALSE}}
More information about the cfe-commits
mailing list