aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Hamilton <benhamilton@google.com>2018-05-01 14:48:54 +0000
committerBen Hamilton <benhamilton@google.com>2018-05-01 14:48:54 +0000
commit969d63ea8c5820d1325ad27205fc34c4f5030a54 (patch)
tree7be73f01db63180925c7ab2f17d6174318b79aa2
parentd4fb951ce35315e1a3f5d760195fe23974c5e31f (diff)
downloadllvm-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.cpp12
-rw-r--r--clang-tools-extra/test/clang-tidy/google-runtime-int.cpp17
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'
+}