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(E)) if (const auto *LengthVD = dyn_cast(LengthDRE->getDecl())) if (!isa(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(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 +class ValueDependentClass { +public: + void copyData(char* Dst) { + const char* Src = reinterpret_cast(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.