OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // This plugin ensures that 32/64-bit unstable types are not used in IPC. |
| 6 // |
| 7 // Type (or typedef) is unstable if it changes size between 32/ 64-bit |
| 8 // platforms. However, it's impossible to accurately identify unstable |
| 9 // typedefs, because their definitions rely on the preprocessor. For |
| 10 // example uintptr_t is either unsigned int or unsigned long. |
| 11 // |
| 12 // So we're not trying to be accurate, and just blacklisting some types |
| 13 // that are known to be unstable: |
| 14 // 1. Types: long / unsigned long (but not typedefs to) |
| 15 // 2. Typedefs: intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t, |
| 16 // size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t, |
| 17 // time_t, suseconds_t (including typedefs to) |
| 18 // |
| 19 // The plugin checks for blacklisted types in: |
| 20 // 1. IPC::WriteParam() calls; additionally: |
| 21 // a. WriteParam() can be used inside a template only if that template |
| 22 // is IPC::ParamTraits<> specialization |
| 23 // b. When used in a template on a dependent type WriteParam() must |
| 24 // either explicitly specify template argument (WriteParam<T>(...)) |
| 25 // because template arguments are checked by #2 |
| 26 // 2. IPC::CheckedTuple<> specializations, both in CheckedTuple<> and |
| 27 // all specializations it references (i.e. std::vector<Set<size_t>> is |
| 28 // not allowed because size_t is blacklisted) |
| 29 |
| 30 #ifndef TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_ |
| 31 #define TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_ |
| 32 |
| 33 #include "clang/AST/AST.h" |
| 34 #include "clang/AST/ASTConsumer.h" |
| 35 #include "clang/AST/RecursiveASTVisitor.h" |
| 36 #include "clang/Frontend/CompilerInstance.h" |
| 37 |
| 38 namespace chrome_checker { |
| 39 |
| 40 class CheckIPCVisitor: private clang::RecursiveASTVisitor<CheckIPCVisitor> { |
| 41 public: |
| 42 explicit CheckIPCVisitor(clang::CompilerInstance& compiler); |
| 43 |
| 44 void Visit(clang::ASTContext& context); |
| 45 |
| 46 private: |
| 47 typedef clang::RecursiveASTVisitor<CheckIPCVisitor> Base; |
| 48 friend Base; |
| 49 |
| 50 bool shouldVisitTemplateInstantiations() const { return true; } |
| 51 |
| 52 bool TraverseDecl(clang::Decl*); |
| 53 bool VisitTemplateSpecializationType(clang::TemplateSpecializationType*); |
| 54 bool VisitCallExpr(clang::CallExpr*); |
| 55 |
| 56 /* ValidateXXX functions return false if validation failed and diagnostic |
| 57 was reported. They return true otherwise (not applicable / validation |
| 58 succeeded). |
| 59 */ |
| 60 |
| 61 bool ValidateWriteParam(const clang::CallExpr* call_expr) const; |
| 62 |
| 63 bool ValidateWriteParamSignature(const clang::CallExpr* call_expr) const; |
| 64 |
| 65 bool ValidateWriteParamInsideTemplate( |
| 66 const clang::CallExpr* call_expr, |
| 67 const clang::UnresolvedLookupExpr* lookup_expr) const; |
| 68 |
| 69 bool ValidateWriteParamArgument(const clang::Expr* arg_expr) const; |
| 70 |
| 71 bool ValidateWriteParamCaller(const clang::CallExpr* call_expr) const; |
| 72 |
| 73 bool ValidateCheckedTuple( |
| 74 const clang::TemplateSpecializationType* spec) const; |
| 75 |
| 76 bool IsInsideParamTraits() const; |
| 77 |
| 78 clang::CompilerInstance& compiler_; |
| 79 clang::ASTContext* context_; |
| 80 |
| 81 unsigned error_write_param_bad_type_; |
| 82 unsigned error_tuple_bad_type_; |
| 83 |
| 84 unsigned error_write_param_template_arg_; |
| 85 unsigned error_write_param_wrong_template_; |
| 86 unsigned error_write_param_bad_signature_; |
| 87 unsigned note_see_here_; |
| 88 |
| 89 const clang::Decl* current_decl_; |
| 90 const clang::FunctionDecl* current_fn_decl_; |
| 91 const clang::ClassTemplateSpecializationDecl* current_spec_decl_; |
| 92 }; |
| 93 |
| 94 } // namespace chrome_checker |
| 95 |
| 96 #endif // TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_ |
OLD | NEW |