1 //===--- 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 20 namespace clang { 21 namespace tidy { 22 namespace 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. 28 class CloexecCheck : public ClangTidyCheck { 29 public: CloexecCheck(StringRef Name,ClangTidyContext * Context)30 CloexecCheck(StringRef Name, ClangTidyContext *Context) 31 : ClangTidyCheck(Name, Context) {} 32 33 protected: 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 105