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 |