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 check ensures that 32/64-bit unstable types are not used in IPC. |
| 6 // |
| 7 // A 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 // Additionally, templates referencing blacklisted types (e.g. vector<long>) |
| 20 // are also blacklisted. |
| 21 // |
| 22 // Blacklisted types are checked in: |
| 23 // 1. IPC::WriteParam() calls |
| 24 // 2. IPC::CheckedTuple<> specializations |
| 25 // |
| 26 |
| 27 #ifndef TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_ |
| 28 #define TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_ |
| 29 |
| 30 #include <vector> |
| 31 |
| 32 #include "clang/AST/AST.h" |
| 33 #include "clang/AST/ASTConsumer.h" |
| 34 #include "clang/AST/RecursiveASTVisitor.h" |
| 35 #include "clang/Frontend/CompilerInstance.h" |
| 36 #include "llvm/ADT/StringSet.h" |
| 37 |
| 38 namespace chrome_checker { |
| 39 |
| 40 class CheckIPCVisitor { |
| 41 public: |
| 42 explicit CheckIPCVisitor(clang::CompilerInstance& compiler); |
| 43 |
| 44 void set_context(clang::ASTContext* context) { context_ = context; } |
| 45 |
| 46 bool should_visit_template_instantiations() const { return true; } |
| 47 |
| 48 void BeginDecl(clang::Decl* decl); |
| 49 void EndDecl(); |
| 50 void VisitTemplateSpecializationType( |
| 51 clang::TemplateSpecializationType* spec); |
| 52 void VisitCallExpr(clang::CallExpr* call_expr); |
| 53 |
| 54 private: |
| 55 // ValidateXXX functions return false if validation failed and diagnostic |
| 56 // was reported. They return true otherwise (not applicable / validation |
| 57 // succeeded). |
| 58 |
| 59 bool ValidateWriteParam(const clang::CallExpr* call_expr); |
| 60 bool ValidateWriteParamSignature(const clang::CallExpr* call_expr); |
| 61 bool ValidateWriteParamArgument(const clang::Expr* arg_expr); |
| 62 bool ValidateCheckedTuple( |
| 63 const clang::TemplateSpecializationType* spec); |
| 64 |
| 65 template <typename T> |
| 66 const T* GetParentDecl() const; |
| 67 |
| 68 bool IsBlacklistedType(clang::QualType type) const; |
| 69 bool IsBlacklistedTypedef(const clang::TypedefNameDecl* tdef) const; |
| 70 |
| 71 struct CheckDetails { |
| 72 clang::QualType entry_type; |
| 73 clang::QualType exit_type; |
| 74 llvm::SmallVector<const clang::TypedefType*, 5> typedefs; |
| 75 }; |
| 76 |
| 77 bool CheckType(clang::QualType type, CheckDetails* details) const; |
| 78 bool CheckIntegerType(clang::QualType type, CheckDetails* details) const; |
| 79 bool CheckTemplateArgument(const clang::TemplateArgument& arg, |
| 80 CheckDetails* details) const; |
| 81 |
| 82 void ReportCheckError(const CheckDetails& details, |
| 83 clang::SourceLocation loc, |
| 84 unsigned error); |
| 85 |
| 86 clang::CompilerInstance& compiler_; |
| 87 clang::ASTContext* context_; |
| 88 |
| 89 unsigned error_write_param_bad_type_; |
| 90 unsigned error_tuple_bad_type_; |
| 91 unsigned error_write_param_bad_signature_; |
| 92 unsigned note_see_here_; |
| 93 |
| 94 std::vector<const clang::Decl*> decl_stack_; |
| 95 |
| 96 llvm::StringSet<> blacklisted_typedefs_; |
| 97 }; |
| 98 |
| 99 } // namespace chrome_checker |
| 100 |
| 101 #endif // TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_ |
OLD | NEW |