blob: 336ed56f5bf3f57f5593820b93d9505bdcb60f2d [file] [log] [blame]
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001//===--- CloexecCheck.h - clang-tidy-----------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file contains the declaration of the CloexecCheck class, which is the
11/// base class for all of the close-on-exec checks in Android module.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H
16#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H
17
18#include "../ClangTidyCheck.h"
19
20namespace clang {
21namespace tidy {
22namespace android {
23
24/// The base class for all close-on-exec checks in Android module.
25/// To be specific, there are some functions that need the close-on-exec flag to
26/// prevent the file descriptor leakage on fork+exec and this class provides
27/// utilities to identify and fix these C functions.
28class CloexecCheck : public ClangTidyCheck {
29public:
30 CloexecCheck(StringRef Name, ClangTidyContext *Context)
31 : ClangTidyCheck(Name, Context) {}
32
33protected:
34 void
35 registerMatchersImpl(ast_matchers::MatchFinder *Finder,
36 ast_matchers::internal::Matcher<FunctionDecl> Function);
37
38 /// Currently, we have three types of fixes.
39 ///
40 /// Type1 is to insert the necessary macro flag in the flag argument. For
41 /// example, 'O_CLOEXEC' is required in function 'open()', so
42 /// \code
43 /// open(file, O_RDONLY);
44 /// \endcode
45 /// should be
46 /// \code
47 /// open(file, O_RDONLY | O_CLOEXE);
48 /// \endcode
49 ///
50 /// \param [out] Result MatchResult from AST matcher.
51 /// \param MacroFlag The macro name of the flag.
52 /// \param ArgPos The 0-based position of the flag argument.
53 void insertMacroFlag(const ast_matchers::MatchFinder::MatchResult &Result,
54 StringRef MacroFlag, int ArgPos);
55
56 /// Type2 is to replace the API to another function that has required the
57 /// ability. For example:
58 /// \code
59 /// creat(path, mode);
60 /// \endcode
61 /// should be
62 /// \code
63 /// open(path, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, mode)
64 /// \endcode
65 ///
66 /// \param [out] Result MatchResult from AST matcher.
67 /// \param WarningMsg The warning message.
68 /// \param FixMsg The fix message.
69 void replaceFunc(const ast_matchers::MatchFinder::MatchResult &Result,
70 StringRef WarningMsg, StringRef FixMsg);
71
72 /// Type3 is also to add a flag to the corresponding argument, but this time,
73 /// the flag is some string and each char represents a mode rather than a
74 /// macro. For example, 'fopen' needs char 'e' in its mode argument string, so
75 /// \code
76 /// fopen(in_file, "r");
77 /// \endcode
78 /// should be
79 /// \code
80 /// fopen(in_file, "re");
81 /// \endcode
82 ///
83 /// \param [out] Result MatchResult from AST matcher.
84 /// \param Mode The required mode char.
85 /// \param ArgPos The 0-based position of the flag argument.
86 void insertStringFlag(const ast_matchers::MatchFinder::MatchResult &Result,
87 const char Mode, const int ArgPos);
88
89 /// Helper function to get the spelling of a particular argument.
90 StringRef getSpellingArg(const ast_matchers::MatchFinder::MatchResult &Result,
91 int N) const;
92
93 /// Binding name of the FuncDecl of a function call.
94 static const char *FuncDeclBindingStr;
95
96 /// Binding name of the function call expression.
97 static const char *FuncBindingStr;
98};
99
100} // namespace android
101} // namespace tidy
102} // namespace clang
103
104#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H