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 void BeginDecl(clang::Decl* decl); |
| 47 void EndDecl(); |
| 48 void VisitTemplateSpecializationType( |
| 49 clang::TemplateSpecializationType* spec); |
| 50 void VisitCallExpr(clang::CallExpr* call_expr); |
| 51 |
| 52 private: |
| 53 // ValidateXXX functions return false if validation failed and diagnostic |
| 54 // was reported. They return true otherwise (not applicable / validation |
| 55 // succeeded). |
| 56 |
| 57 bool ValidateWriteParam(const clang::CallExpr* call_expr); |
| 58 bool ValidateWriteParamSignature(const clang::CallExpr* call_expr); |
| 59 bool ValidateWriteParamArgument(const clang::Expr* arg_expr); |
| 60 bool ValidateCheckedTuple( |
| 61 const clang::TemplateSpecializationType* spec); |
| 62 |
| 63 template <typename T> |
| 64 const T* GetParentDecl() const; |
| 65 |
| 66 bool IsBlacklistedType(clang::QualType type) const; |
| 67 bool IsBlacklistedTypedef(const clang::TypedefNameDecl* tdef) const; |
| 68 |
| 69 struct CheckDetails { |
| 70 clang::QualType entry_type; |
| 71 clang::QualType exit_type; |
| 72 llvm::SmallVector<const clang::TypedefType*, 5> typedefs; |
| 73 }; |
| 74 |
| 75 bool CheckType(clang::QualType type, CheckDetails* details) const; |
| 76 bool CheckIntegerType(clang::QualType type, CheckDetails* details) const; |
| 77 bool CheckTemplateArgument(const clang::TemplateArgument& arg, |
| 78 CheckDetails* details) const; |
| 79 |
| 80 void ReportCheckError(const CheckDetails& details, |
| 81 clang::SourceLocation loc, |
| 82 unsigned error); |
| 83 |
| 84 clang::CompilerInstance& compiler_; |
| 85 clang::ASTContext* context_; |
| 86 |
| 87 unsigned error_write_param_bad_type_; |
| 88 unsigned error_tuple_bad_type_; |
| 89 unsigned error_write_param_bad_signature_; |
| 90 unsigned note_see_here_; |
| 91 |
| 92 std::vector<const clang::Decl*> decl_stack_; |
| 93 |
| 94 llvm::StringSet<> blacklisted_typedefs_; |
| 95 }; |
| 96 |
| 97 } // namespace chrome_checker |
| 98 |
| 99 #endif // TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_ |
OLD | NEW |