summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2016-01-11 10:26:29 +0000
committerAlexander Kornienko <alexfh@google.com>2016-01-11 10:26:29 +0000
commitdcbe5a9d1727fc83b9263fe8d70e534377f33d4a (patch)
tree9c1c2417594499fd0e642e056cf551e74e29d358
parentd0f89cd721df6943e36e4bbd9715317b08b7f578 (diff)
downloadbcm5719-llvm-dcbe5a9d1727fc83b9263fe8d70e534377f33d4a.tar.gz
bcm5719-llvm-dcbe5a9d1727fc83b9263fe8d70e534377f33d4a.zip
[clang-tidy] Fix a false positive in google-runtime-memset
google-runtime-memset no longer issues a warning if the fill char value is known to be an invalid fill char count. Namely, it no longer warns for these: memset(p, 0, 0); memset(p, -1, 0); In both cases, swapping the last two args would either be useless (there is no actual bug) or wrong (it would introduce a bug). Patch by Matt Armstrong! llvm-svn: 257320
-rw-r--r--clang-tools-extra/clang-tidy/google/MemsetZeroLengthCheck.cpp18
-rw-r--r--clang-tools-extra/test/clang-tidy/google-runtime-memset-zero-length.cpp10
2 files changed, 17 insertions, 11 deletions
diff --git a/clang-tools-extra/clang-tidy/google/MemsetZeroLengthCheck.cpp b/clang-tools-extra/clang-tidy/google/MemsetZeroLengthCheck.cpp
index 4c0b8e01f22..bcf4b5b3b61 100644
--- a/clang-tools-extra/clang-tidy/google/MemsetZeroLengthCheck.cpp
+++ b/clang-tools-extra/clang-tidy/google/MemsetZeroLengthCheck.cpp
@@ -51,25 +51,29 @@ static StringRef getAsString(const MatchFinder::MatchResult &Result,
void MemsetZeroLengthCheck::check(const MatchFinder::MatchResult &Result) {
const auto *Call = Result.Nodes.getNodeAs<CallExpr>("decl");
+ // Note, this is:
+ // void *memset(void *buffer, int fill_char, size_t byte_count);
+ // Arg1 is fill_char, Arg2 is byte_count.
const Expr *Arg1 = Call->getArg(1);
const Expr *Arg2 = Call->getArg(2);
- // Try to evaluate the second argument so we can also find values that are not
- // just literals.
+ // Return if `byte_count` is not zero at compile time.
llvm::APSInt Value1, Value2;
if (Arg2->isValueDependent() ||
!Arg2->EvaluateAsInt(Value2, *Result.Context) || Value2 != 0)
return;
- // If both arguments evaluate to zero emit a warning without fix suggestions.
+ // Return if `fill_char` is known to be zero or negative at compile
+ // time. In these cases, swapping the args would be a nop, or
+ // introduce a definite bug. The code is likely correct.
if (!Arg1->isValueDependent() &&
Arg1->EvaluateAsInt(Value1, *Result.Context) &&
- (Value1 == 0 || Value1.isNegative())) {
- diag(Call->getLocStart(), "memset of size zero");
+ (Value1 == 0 || Value1.isNegative()))
return;
- }
- // Emit a warning and fix-its to swap the arguments.
+ // `byte_count` is known to be zero at compile time, and `fill_char` is
+ // either not known or known to be a positive integer. Emit a warning
+ // and fix-its to swap the arguments.
auto D = diag(Call->getLocStart(),
"memset of size zero, potentially swapped arguments");
SourceRange LHSRange = Arg1->getSourceRange();
diff --git a/clang-tools-extra/test/clang-tidy/google-runtime-memset-zero-length.cpp b/clang-tools-extra/test/clang-tidy/google-runtime-memset-zero-length.cpp
index db75cb0fedd..7599c755b48 100644
--- a/clang-tools-extra/test/clang-tidy/google-runtime-memset-zero-length.cpp
+++ b/clang-tools-extra/test/clang-tidy/google-runtime-memset-zero-length.cpp
@@ -48,13 +48,15 @@ void foo(void *a, int xsize, int ysize) {
memset(a, -1, sizeof(int));
memset(a, 0xcd, 1);
+
+ // Don't warn when the fill char and the length are both known to be
+ // zero. No bug is possible.
+ memset(a, 0, v);
memset(a, v, 0);
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero
-// CHECK-FIXES: memset(a, v, 0);
+ // -1 is clearly not a length by virtue of being negative, so no warning
+ // despite v == 0.
memset(a, -1, v);
-// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero
-// CHECK-FIXES: memset(a, -1, v);
memtmpl<0, int>();
}
OpenPOWER on IntegriCloud