Index: tools/clang/plugins/CheckIPCVisitor.h |
diff --git a/tools/clang/plugins/CheckIPCVisitor.h b/tools/clang/plugins/CheckIPCVisitor.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8d170882fb407f48abbba536eca07e34bf39acbc |
--- /dev/null |
+++ b/tools/clang/plugins/CheckIPCVisitor.h |
@@ -0,0 +1,96 @@ |
+// Copyright (c) 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// This plugin ensures that 32/64-bit unstable types are not used in IPC. |
+// |
+// Type (or typedef) is unstable if it changes size between 32/ 64-bit |
+// platforms. However, it's impossible to accurately identify unstable |
+// typedefs, because their definitions rely on the preprocessor. For |
+// example uintptr_t is either unsigned int or unsigned long. |
+// |
+// So we're not trying to be accurate, and just blacklisting some types |
+// that are known to be unstable: |
+// 1. Types: long / unsigned long (but not typedefs to) |
+// 2. Typedefs: intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t, |
+// size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t, |
+// time_t, suseconds_t (including typedefs to) |
+// |
+// The plugin checks for blacklisted types in: |
+// 1. IPC::WriteParam() calls; additionally: |
+// a. WriteParam() can be used inside a template only if that template |
+// is IPC::ParamTraits<> specialization |
+// b. When used in a template on a dependent type WriteParam() must |
+// either explicitly specify template argument (WriteParam<T>(...)) |
+// because template arguments are checked by #2 |
+// 2. IPC::CheckedTuple<> specializations, both in CheckedTuple<> and |
+// all specializations it references (i.e. std::vector<Set<size_t>> is |
+// not allowed because size_t is blacklisted) |
+ |
+#ifndef TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_ |
+#define TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_ |
+ |
+#include "clang/AST/AST.h" |
+#include "clang/AST/ASTConsumer.h" |
+#include "clang/AST/RecursiveASTVisitor.h" |
+#include "clang/Frontend/CompilerInstance.h" |
+ |
+namespace chrome_checker { |
+ |
+class CheckIPCVisitor: private clang::RecursiveASTVisitor<CheckIPCVisitor> { |
+ public: |
+ explicit CheckIPCVisitor(clang::CompilerInstance& compiler); |
+ |
+ void Visit(clang::ASTContext& context); |
+ |
+ private: |
+ typedef clang::RecursiveASTVisitor<CheckIPCVisitor> Base; |
+ friend Base; |
+ |
+ bool shouldVisitTemplateInstantiations() const { return true; } |
+ |
+ bool TraverseDecl(clang::Decl*); |
+ bool VisitTemplateSpecializationType(clang::TemplateSpecializationType*); |
+ bool VisitCallExpr(clang::CallExpr*); |
+ |
+ /* ValidateXXX functions return false if validation failed and diagnostic |
+ was reported. They return true otherwise (not applicable / validation |
+ succeeded). |
+ */ |
+ |
+ bool ValidateWriteParam(const clang::CallExpr* call_expr) const; |
+ |
+ bool ValidateWriteParamSignature(const clang::CallExpr* call_expr) const; |
+ |
+ bool ValidateWriteParamInsideTemplate( |
+ const clang::CallExpr* call_expr, |
+ const clang::UnresolvedLookupExpr* lookup_expr) const; |
+ |
+ bool ValidateWriteParamArgument(const clang::Expr* arg_expr) const; |
+ |
+ bool ValidateWriteParamCaller(const clang::CallExpr* call_expr) const; |
+ |
+ bool ValidateCheckedTuple( |
+ const clang::TemplateSpecializationType* spec) const; |
+ |
+ bool IsInsideParamTraits() const; |
+ |
+ clang::CompilerInstance& compiler_; |
+ clang::ASTContext* context_; |
+ |
+ unsigned error_write_param_bad_type_; |
+ unsigned error_tuple_bad_type_; |
+ |
+ unsigned error_write_param_template_arg_; |
+ unsigned error_write_param_wrong_template_; |
+ unsigned error_write_param_bad_signature_; |
+ unsigned note_see_here_; |
+ |
+ const clang::Decl* current_decl_; |
+ const clang::FunctionDecl* current_fn_decl_; |
+ const clang::ClassTemplateSpecializationDecl* current_spec_decl_; |
+}; |
+ |
+} // namespace chrome_checker |
+ |
+#endif // TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_ |