-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[clang-tidy] Fix crash in bugprone-not-null-terminated-result check #160727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[clang-tidy] Fix crash in bugprone-not-null-terminated-result check #160727
Conversation
The check was crashing when trying to evaluate value-dependent expressions using EvaluateAsInt() in cases where the src parameter of memcpy is value-dependent, but the length is not. Added isValueDependent() check before EvaluateAsInt() call to prevent the crash.
@llvm/pr-subscribers-clang-tools-extra @llvm/pr-subscribers-clang-tidy Author: Endre Fülöp (gamesh411) ChangesThe check was crashing when trying to evaluate value-dependent expressions using EvaluateAsInt() in cases where the src parameter of memcpy is value-dependent, but the length is not. Added isValueDependent() check before EvaluateAsInt() call to prevent the crash. Full diff: https://github.com/llvm/llvm-project/pull/160727.diff 2 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
index d4676842a97ff..463677d2d3af6 100644
--- a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
@@ -64,15 +64,17 @@ static unsigned getLength(const Expr *E,
if (!E)
return 0;
- Expr::EvalResult Length;
E = E->IgnoreImpCasts();
if (const auto *LengthDRE = dyn_cast<DeclRefExpr>(E))
if (const auto *LengthVD = dyn_cast<VarDecl>(LengthDRE->getDecl()))
if (!isa<ParmVarDecl>(LengthVD))
if (const Expr *LengthInit = LengthVD->getInit())
- if (LengthInit->EvaluateAsInt(Length, *Result.Context))
- return Length.Val.getInt().getZExtValue();
+ if (!LengthInit->isValueDependent()) {
+ Expr::EvalResult Length;
+ if (LengthInit->EvaluateAsInt(Length, *Result.Context))
+ return Length.Val.getInt().getZExtValue();
+ }
if (const auto *LengthIL = dyn_cast<IntegerLiteral>(E))
return LengthIL->getValue().getZExtValue();
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-value-dependent-crash.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-value-dependent-crash.cpp
new file mode 100644
index 0000000000000..5f361c35e448c
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/not-null-terminated-result-value-dependent-crash.cpp
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -std=c++17 -I %S/Inputs/not-null-terminated-result
+
+// This test case reproduces the crash when the check tries to evaluate
+// a value-dependent expression using EvaluateAsInt() in
+// bugprone-not-null-terminated-result, where the src parameter of memcpy is
+// value-dependent, but the length is not.
+
+// expected-no-diagnostics
+
+#include "not-null-terminated-result-cxx.h"
+
+template<size_t N>
+class ValueDependentClass {
+public:
+ void copyData(char* Dst) {
+ const char* Src = reinterpret_cast<const char*>(this);
+ // The length parameter is arbitrary, but the crash is not reproduced if it is N.
+ memcpy(Dst, Src, 32);
+ }
+};
+
+template class ValueDependentClass<42>; // The template parameter value is arbitrary.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add release note in clang-tools-extra/ReleaseNotes.rst
.
Make entry in lexical order
if (const Expr *LengthInit = LengthVD->getInit()) | ||
if (LengthInit->EvaluateAsInt(Length, *Result.Context)) | ||
return Length.Val.getInt().getZExtValue(); | ||
if (!LengthInit->isValueDependent()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (const Expr *LengthInit = LengthVD->getInit(); LengthInit && !LengthInit->isValueDependent()) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
please add release note also
The check was crashing when trying to evaluate value-dependent expressions using EvaluateAsInt() in cases where the src parameter of memcpy is value-dependent, but the length is not. Added isValueDependent() check before EvaluateAsInt() call to prevent the crash.