diff options
author | Ben Hamilton <benhamilton@google.com> | 2018-05-01 14:48:54 +0000 |
---|---|---|
committer | Ben Hamilton <benhamilton@google.com> | 2018-05-01 14:48:54 +0000 |
commit | 969d63ea8c5820d1325ad27205fc34c4f5030a54 (patch) | |
tree | 7be73f01db63180925c7ab2f17d6174318b79aa2 | |
parent | d4fb951ce35315e1a3f5d760195fe23974c5e31f (diff) | |
download | llvm-969d63ea8c5820d1325ad27205fc34c4f5030a54.zip llvm-969d63ea8c5820d1325ad27205fc34c4f5030a54.tar.gz llvm-969d63ea8c5820d1325ad27205fc34c4f5030a54.tar.bz2 |
[clang-tidy/google-runtime-int] Allow passing non-bitwidth types to printf()-style APIs
Summary:
The `google-runtime-int` check currently fires on calls like:
printf("%lu", (unsigned long)foo);
However, the style guide says:
> Where possible, avoid passing arguments of types specified by
> bitwidth typedefs to printf-based APIs.
http://google.github.io/styleguide/cppguide.html#64-bit_Portability
This diff relaxes the check to not fire on parameters to functions
with the `__format__` attribute. (I didn't specifically check
for `__printf__` since there are a few variations.)
Test Plan: New tests added. Ran tests with:
% make -j16 check-clang-tools
Reviewers: alexfh, bkramer
Reviewed By: alexfh
Subscribers: klimek, cfe-commits
Differential Revision: https://reviews.llvm.org/D46293
llvm-svn: 331268
-rw-r--r-- | clang-tools-extra/clang-tidy/google/IntegerTypesCheck.cpp | 12 | ||||
-rw-r--r-- | clang-tools-extra/test/clang-tidy/google-runtime-int.cpp | 17 |
2 files changed, 28 insertions, 1 deletions
diff --git a/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.cpp b/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.cpp index f6c917c..7f0b765 100644 --- a/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/IntegerTypesCheck.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/AttrKinds.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/TargetInfo.h" @@ -56,7 +57,16 @@ void IntegerTypesCheck::registerMatchers(MatchFinder *Finder) { // Find all TypeLocs. The relevant Style Guide rule only applies to C++. if (!getLangOpts().CPlusPlus) return; - Finder->addMatcher(typeLoc(loc(isInteger())).bind("tl"), this); + // Match any integer types, unless they are passed to a printf-based API: + // + // http://google.github.io/styleguide/cppguide.html#64-bit_Portability + // "Where possible, avoid passing arguments of types specified by + // bitwidth typedefs to printf-based APIs." + Finder->addMatcher(typeLoc(loc(isInteger()), + unless(hasAncestor(callExpr( + callee(functionDecl(hasAttr(attr::Format))))))) + .bind("tl"), + this); IdentTable = llvm::make_unique<IdentifierTable>(getLangOpts()); } diff --git a/clang-tools-extra/test/clang-tidy/google-runtime-int.cpp b/clang-tools-extra/test/clang-tidy/google-runtime-int.cpp index e51ca7d..4bb73987 100644 --- a/clang-tools-extra/test/clang-tidy/google-runtime-int.cpp +++ b/clang-tools-extra/test/clang-tidy/google-runtime-int.cpp @@ -72,3 +72,20 @@ void fff() { B a, b; a = b; } + +__attribute__((__format__ (__printf__, 1, 2))) +void myprintf(const char* s, ...); + +void doprint_no_warning() { + uint64 foo = 23; + myprintf("foo %lu %lu", (unsigned long)42, (unsigned long)foo); +} + +void myprintf_no_attribute(const char* s, ...); + +void doprint_warning() { + uint64 foo = 23; + myprintf_no_attribute("foo %lu %lu", (unsigned long)42, (unsigned long)foo); +// CHECK-MESSAGES: [[@LINE-1]]:41: warning: consider replacing 'unsigned long' +// CHECK-MESSAGES: [[@LINE-2]]:60: warning: consider replacing 'unsigned long' +} |