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 set_context(clang::ASTContext * context)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_ 100