<div dir="ltr">Not sure if you've seen it, this broke the Windows build: <a href="http://lab.llvm.org:8011/builders/clang-x64-ninja-win7/builds/5880/steps/build%20stage%201/logs/stdio">http://lab.llvm.org:8011/builders/clang-x64-ninja-win7/builds/5880/steps/build%20stage%201/logs/stdio</a><div><br></div><div><div>FAILED: C:\PROGRA~2\MICROS~3.0\VC\bin\amd64\cl.exe   /nologo /TP -DGTEST_HAS_RTTI=0 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_GNU_SOURCE -D_HAS_EXCEPTIONS=0 -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Itools\clang\tools\extra\clang-tidy\android -ID:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\tools\extra\clang-tidy\android -ID:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include -Itools\clang\include -Iinclude -ID:\buildslave\clang-x64-ninja-win7\llvm\include /DWIN32 /D_WINDOWS   /Zc:inline /Zc:strictStrings /Oi /Zc:rvalueCast /W4 -wd4141 -wd4146 -wd4180 -wd4244 -wd4258 -wd4267 -wd4291 -wd4345 -wd4351 -wd4355 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4800 -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4324 -w14062 -we4238 /MD /O2 /Ob2   -UNDEBUG  /EHs-c- /GR- /showIncludes /Fotools\clang\tools\extra\clang-tidy\android\CMakeFiles\clangTidyAndroidModule.dir\CloexecCheck.cpp.obj /Fdtools\clang\tools\extra\clang-tidy\android\CMakeFiles\clangTidyAndroidModule.dir\ /FS -c D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\tools\extra\clang-tidy\android\CloexecCheck.cpp</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\tools\extra\clang-tidy\android\CloexecCheck.cpp(99): error C2666: 'clang::operator <<': 4 overloads have similar conversions</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclObjC.h(2612): note: could be 'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream &,const clang::ObjCImplementationDecl &)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclObjC.h(2429): note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream &,const clang::ObjCCategoryImplDecl &)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclCXX.h(3698): note: or       'const clang::PartialDiagnostic &clang::operator <<(const clang::PartialDiagnostic &,clang::AccessSpecifier)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclCXX.h(3695): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,clang::AccessSpecifier)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Attr.h(202): note: or       'const clang::PartialDiagnostic &clang::operator <<(const clang::PartialDiagnostic &,const clang::Attr *)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Attr.h(195): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,const clang::Attr *)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Sema/CodeCompleteConsumer.h(802): note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream &,const clang::CodeCompletionString &)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/CanonicalType.h(204): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,clang::CanQualType)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/TemplateBase.h(646): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,const clang::TemplateArgument &)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Decl.h(3961): note: or       'const clang::PartialDiagnostic &clang::operator <<(const clang::PartialDiagnostic &,const clang::NamedDecl *)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Decl.h(3955): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,const clang::NamedDecl *)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Decl.h(404): note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream &,const clang::NamedDecl &)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Type.h(6024): note: or       'const clang::PartialDiagnostic &clang::operator <<(const clang::PartialDiagnostic &,clang::QualType)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/Type.h(6015): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,clang::QualType)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/TemplateName.h(309): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,clang::TemplateName)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/NestedNameSpecifier.h(507): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,clang::NestedNameSpecifier *)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclarationName.h(570): note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream &,clang::DeclarationNameInfo)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclarationName.h(563): note: or       'const clang::PartialDiagnostic &clang::operator <<(const clang::PartialDiagnostic &,clang::DeclarationName)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclarationName.h(554): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,clang::DeclarationName)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/AST/DeclarationName.h(313): note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream &,clang::DeclarationName)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/PartialDiagnostic.h(408): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,const clang::PartialDiagnostic &)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/ObjCRuntime.h(361): note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream &,const clang::ObjCRuntime &)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/VersionTuple.h(165): note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream &,const clang::VersionTuple &)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1202): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,clang::DiagNullabilityKind)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1191): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,llvm::ArrayRef<clang::FixItHint>)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1185): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,const clang::FixItHint &)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1179): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,const clang::CharSourceRange &)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1172): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,llvm::ArrayRef<clang::SourceRange>)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1166): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,clang::SourceRange)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1145): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,const clang::IdentifierInfo *)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1139): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,clang::tok::TokenKind)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1133): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,unsigned int)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1117): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,int)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1110): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,const char *)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1104): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,llvm::StringRef)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/Diagnostic.h(1098): note: or       'const clang::DiagnosticBuilder &clang::operator <<(const clang::DiagnosticBuilder &,const clang::AddFlagValue)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\include\clang/Basic/DiagnosticOptions.h(58): note: or       'llvm::raw_ostream &clang::operator <<(llvm::raw_ostream &,clang::DiagnosticLevelMask)'</div><div>D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\tools\extra\clang-tidy\android\CloexecCheck.cpp(99): note: while trying to match the argument list '(const clang::DiagnosticBuilder, const char)'</div><div>ninja: build stopped: subcommand failed.</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Aug 10, 2017 at 1:18 PM, Yan Wang via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: yawanng<br>
Date: Thu Aug 10 10:18:10 2017<br>
New Revision: 310630<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=310630&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=310630&view=rev</a><br>
Log:<br>
[clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.<br>
<br>
Summary:<br>
1. Refactor the structure of the code by adding a base class for all close-on-exec checks, which implements most of the needed functions.<br>
2. memfd_create() is better to set MFD_CLOEXEC flag to avoid file descriptor leakage.<br>
<br>
Reviewers: alexfh, aaron.ballman, hokein<br>
<br>
Reviewed By: alexfh, hokein<br>
<br>
Subscribers: Eugene.Zelenko, chh, cfe-commits, srhines, mgorny, JDevlieghere, xazax.hun<br>
<br>
Tags: #clang-tools-extra<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D35372" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D35372</a><br>
<br>
Added:<br>
    clang-tools-extra/trunk/clang-<wbr>tidy/android/CloexecCheck.cpp<br>
    clang-tools-extra/trunk/clang-<wbr>tidy/android/CloexecCheck.h<br>
    clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>CloexecMemfdCreateCheck.cpp<br>
    clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>CloexecMemfdCreateCheck.h<br>
    clang-tools-extra/trunk/docs/<wbr>clang-tidy/checks/android-<wbr>cloexec-memfd-create.rst<br>
    clang-tools-extra/trunk/test/<wbr>clang-tidy/android-cloexec-<wbr>memfd-create.cpp<br>
Modified:<br>
    clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>AndroidTidyModule.cpp<br>
    clang-tools-extra/trunk/clang-<wbr>tidy/android/CMakeLists.txt<br>
    clang-tools-extra/trunk/docs/<wbr>ReleaseNotes.rst<br>
    clang-tools-extra/trunk/docs/<wbr>clang-tidy/checks/list.rst<br>
<br>
Modified: clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>AndroidTidyModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/android/AndroidTidyModule.cpp?rev=310630&r1=310629&r2=310630&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clang-tidy/android/<wbr>AndroidTidyModule.cpp?rev=<wbr>310630&r1=310629&r2=310630&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>AndroidTidyModule.cpp (original)<br>
+++ clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>AndroidTidyModule.cpp Thu Aug 10 10:18:10 2017<br>
@@ -12,6 +12,7 @@<br>
 #include "../ClangTidyModuleRegistry.h"<br>
 #include "CloexecCreatCheck.h"<br>
 #include "CloexecFopenCheck.h"<br>
+#include "CloexecMemfdCreateCheck.h"<br>
 #include "CloexecOpenCheck.h"<br>
 #include "CloexecSocketCheck.h"<br>
<br>
@@ -27,6 +28,8 @@ public:<br>
   void addCheckFactories(<wbr>ClangTidyCheckFactories &CheckFactories) override {<br>
     CheckFactories.registerCheck<<wbr>CloexecCreatCheck>("android-<wbr>cloexec-creat");<br>
     CheckFactories.registerCheck<<wbr>CloexecFopenCheck>("android-<wbr>cloexec-fopen");<br>
+    CheckFactories.registerCheck<<wbr>CloexecMemfdCreateCheck>(<br>
+        "android-cloexec-memfd-create"<wbr>);<br>
     CheckFactories.registerCheck<<wbr>CloexecOpenCheck>("android-<wbr>cloexec-open");<br>
     CheckFactories.registerCheck<<wbr>CloexecSocketCheck>("android-<wbr>cloexec-socket");<br>
   }<br>
<br>
Modified: clang-tools-extra/trunk/clang-<wbr>tidy/android/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt?rev=310630&r1=310629&r2=310630&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clang-tidy/android/<wbr>CMakeLists.txt?rev=310630&r1=<wbr>310629&r2=310630&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/clang-<wbr>tidy/android/CMakeLists.txt (original)<br>
+++ clang-tools-extra/trunk/clang-<wbr>tidy/android/CMakeLists.txt Thu Aug 10 10:18:10 2017<br>
@@ -2,8 +2,10 @@ set(LLVM_LINK_COMPONENTS support)<br>
<br>
 add_clang_library(<wbr>clangTidyAndroidModule<br>
   AndroidTidyModule.cpp<br>
+  CloexecCheck.cpp<br>
   CloexecCreatCheck.cpp<br>
   CloexecFopenCheck.cpp<br>
+  CloexecMemfdCreateCheck.cpp<br>
   CloexecOpenCheck.cpp<br>
   CloexecSocketCheck.cpp<br>
<br>
<br>
Added: clang-tools-extra/trunk/clang-<wbr>tidy/android/CloexecCheck.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.cpp?rev=310630&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clang-tidy/android/<wbr>CloexecCheck.cpp?rev=310630&<wbr>view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/clang-<wbr>tidy/android/CloexecCheck.cpp (added)<br>
+++ clang-tools-extra/trunk/clang-<wbr>tidy/android/CloexecCheck.cpp Thu Aug 10 10:18:10 2017<br>
@@ -0,0 +1,105 @@<br>
+//===--- CloexecCheck.cpp - clang-tidy--------------------<wbr>-----------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#include "CloexecCheck.h"<br>
+#include "../utils/ASTUtils.h"<br>
+#include "clang/AST/ASTContext.h"<br>
+#include "clang/ASTMatchers/<wbr>ASTMatchFinder.h"<br>
+#include "clang/Lex/Lexer.h"<br>
+<br>
+using namespace clang::ast_matchers;<br>
+<br>
+namespace clang {<br>
+namespace tidy {<br>
+namespace android {<br>
+<br>
+namespace {<br>
+<br>
+const char *const FuncDeclBindingStr = "funcDecl";<br>
+const char *const FuncBindingStr = "func";<br>
+<br>
+// Helper function to form the correct string mode for Type3.<br>
+// Build the replace text. If it's string constant, add <Mode> directly in the<br>
+// end of the string. Else, add <Mode>.<br>
+std::string buildFixMsgForStringFlag(const Expr *Arg, const SourceManager &SM,<br>
+                                     const LangOptions &LangOpts, char Mode) {<br>
+  if (Arg->getLocStart().isMacroID(<wbr>))<br>
+    return (Lexer::getSourceText(<br>
+                CharSourceRange::<wbr>getTokenRange(Arg-><wbr>getSourceRange()), SM,<br>
+                LangOpts) +<br>
+            " \"" + Twine(Mode) + "\"")<br>
+        .str();<br>
+<br>
+  StringRef SR = cast<StringLiteral>(Arg-><wbr>IgnoreParenCasts())-><wbr>getString();<br>
+  return ("\"" + SR + Twine(Mode) + "\"").str();<br>
+}<br>
+} // namespace<br>
+<br>
+void CloexecCheck::<wbr>registerMatchersImpl(<br>
+    MatchFinder *Finder, internal::Matcher<<wbr>FunctionDecl> Function) {<br>
+  // We assume all the checked APIs are C functions.<br>
+  Finder->addMatcher(<br>
+      callExpr(<br>
+          callee(functionDecl(isExternC(<wbr>), Function).bind(<wbr>FuncDeclBindingStr)))<br>
+          .bind(FuncBindingStr),<br>
+      this);<br>
+}<br>
+<br>
+void CloexecCheck::insertMacroFlag(<wbr>const MatchFinder::MatchResult &Result,<br>
+                                   StringRef MacroFlag, int ArgPos) {<br>
+  const auto *MatchedCall = Result.Nodes.getNodeAs<<wbr>CallExpr>(FuncBindingStr);<br>
+  const auto *FlagArg = MatchedCall->getArg(ArgPos);<br>
+  const auto *FD = Result.Nodes.getNodeAs<<wbr>FunctionDecl>(<wbr>FuncDeclBindingStr);<br>
+  SourceManager &SM = *Result.SourceManager;<br>
+<br>
+  if (utils::<wbr>exprHasBitFlagWithSpelling(<wbr>FlagArg->IgnoreParenCasts(), SM,<br>
+                                        Result.Context->getLangOpts(),<br>
+                                        MacroFlag))<br>
+    return;<br>
+<br>
+  SourceLocation EndLoc =<br>
+      Lexer::getLocForEndOfToken(SM.<wbr>getFileLoc(FlagArg->getLocEnd(<wbr>)), 0, SM,<br>
+                                 Result.Context->getLangOpts())<wbr>;<br>
+<br>
+  diag(EndLoc, "%0 should use %1 where possible")<br>
+      << FD << MacroFlag<br>
+      << FixItHint::CreateInsertion(<wbr>EndLoc, (Twine(" | ") + MacroFlag).str());<br>
+}<br>
+<br>
+void CloexecCheck::replaceFunc(<wbr>const MatchFinder::MatchResult &Result,<br>
+                               StringRef WarningMsg, StringRef FixMsg) {<br>
+  const auto *MatchedCall = Result.Nodes.getNodeAs<<wbr>CallExpr>(FuncBindingStr);<br>
+  diag(MatchedCall->getLocStart(<wbr>), WarningMsg)<br>
+      << FixItHint::CreateReplacement(<wbr>MatchedCall->getSourceRange(), FixMsg);<br>
+}<br>
+<br>
+void CloexecCheck::<wbr>insertStringFlag(<br>
+    const ast_matchers::MatchFinder::<wbr>MatchResult &Result, const char Mode,<br>
+    const int ArgPos) {<br>
+  const auto *MatchedCall = Result.Nodes.getNodeAs<<wbr>CallExpr>(FuncBindingStr);<br>
+  const auto *FD = Result.Nodes.getNodeAs<<wbr>FunctionDecl>(<wbr>FuncDeclBindingStr);<br>
+  const auto *ModeArg = MatchedCall->getArg(ArgPos);<br>
+<br>
+  // Check if the <Mode> may be in the mode string.<br>
+  const auto *ModeStr = dyn_cast<StringLiteral>(<wbr>ModeArg->IgnoreParenCasts());<br>
+  if (!ModeStr || (ModeStr->getString().find(<wbr>Mode) != StringRef::npos))<br>
+    return;<br>
+<br>
+  const std::string &ReplacementText = buildFixMsgForStringFlag(<br>
+      ModeArg, *Result.SourceManager, Result.Context->getLangOpts(), Mode);<br>
+<br>
+  diag(ModeArg->getLocStart(), "use %0 mode '%1' to set O_CLOEXEC")<br>
+      << FD << Mode<br>
+      << FixItHint::CreateReplacement(<wbr>ModeArg->getSourceRange(),<br>
+                                      ReplacementText);<br>
+}<br>
+<br>
+} // namespace android<br>
+} // namespace tidy<br>
+} // namespace clang<br>
<br>
Added: clang-tools-extra/trunk/clang-<wbr>tidy/android/CloexecCheck.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.h?rev=310630&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clang-tidy/android/<wbr>CloexecCheck.h?rev=310630&<wbr>view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/clang-<wbr>tidy/android/CloexecCheck.h (added)<br>
+++ clang-tools-extra/trunk/clang-<wbr>tidy/android/CloexecCheck.h Thu Aug 10 10:18:10 2017<br>
@@ -0,0 +1,95 @@<br>
+//===--- CloexecCheck.h - clang-tidy--------------------<wbr>---------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+///<br>
+/// \file<br>
+/// This file contains the declaration of the CloexecCheck class, which is the<br>
+/// base class for all of the close-on-exec checks in Android module.<br>
+///<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_<wbr>TIDY_ANDROID_CLOEXEC_H<br>
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_<wbr>TIDY_ANDROID_CLOEXEC_H<br>
+<br>
+#include "../ClangTidy.h"<br>
+<br>
+namespace clang {<br>
+namespace tidy {<br>
+namespace android {<br>
+<br>
+/// \brief The base class for all close-on-exec checks in Android module.<br>
+/// To be specific, there are some functions that need the close-on-exec flag to<br>
+/// prevent the file descriptor leakage on fork+exec and this class provides<br>
+/// utilities to identify and fix these C functions.<br>
+class CloexecCheck : public ClangTidyCheck {<br>
+public:<br>
+  CloexecCheck(StringRef Name, ClangTidyContext *Context)<br>
+      : ClangTidyCheck(Name, Context) {}<br>
+<br>
+protected:<br>
+  void<br>
+  registerMatchersImpl(ast_<wbr>matchers::MatchFinder *Finder,<br>
+                       ast_matchers::internal::<wbr>Matcher<FunctionDecl> Function);<br>
+<br>
+  /// Currently, we have three types of fixes.<br>
+  ///<br>
+  /// Type1 is to insert the necessary macro flag in the flag argument. For<br>
+  /// example, 'O_CLOEXEC' is required in function 'open()', so<br>
+  /// \code<br>
+  ///   open(file, O_RDONLY);<br>
+  /// \endcode<br>
+  /// should be<br>
+  /// \code<br>
+  ///   open(file, O_RDONLY | O_CLOEXE);<br>
+  /// \endcode<br>
+  ///<br>
+  /// \param [out] Result MatchResult from AST matcher.<br>
+  /// \param MacroFlag The macro name of the flag.<br>
+  /// \param ArgPos The 0-based position of the flag argument.<br>
+  void insertMacroFlag(const ast_matchers::MatchFinder::<wbr>MatchResult &Result,<br>
+                       StringRef MarcoFlag, int ArgPos);<br>
+<br>
+  /// Type2 is to replace the API to another function that has required the<br>
+  /// ability. For example:<br>
+  /// \code<br>
+  ///   creat(path, mode);<br>
+  /// \endcode<br>
+  /// should be<br>
+  /// \code<br>
+  ///   open(path, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, mode)<br>
+  /// \endcode<br>
+  ///<br>
+  /// \param [out] Result MatchResult from AST matcher.<br>
+  /// \param WarningMsg The warning message.<br>
+  /// \param FixMsg The fix message.<br>
+  void replaceFunc(const ast_matchers::MatchFinder::<wbr>MatchResult &Result,<br>
+                   StringRef WarningMsg, StringRef FixMsg);<br>
+<br>
+  /// Type3 is also to add a flag to the corresponding argument, but this time,<br>
+  /// the flag is some string and each char represents a mode rather than a<br>
+  /// macro. For example, 'fopen' needs char 'e' in its mode argument string, so<br>
+  /// \code<br>
+  ///   fopen(in_file, "r");<br>
+  /// \endcode<br>
+  /// should be<br>
+  /// \code<br>
+  ///   fopen(in_file, "re");<br>
+  /// \endcode<br>
+  ///<br>
+  /// \param [out] Result MatchResult from AST matcher.<br>
+  /// \param Mode The required mode char.<br>
+  /// \param ArgPos The 0-based position of the flag argument.<br>
+  void insertStringFlag(const ast_matchers::MatchFinder::<wbr>MatchResult &Result,<br>
+                        char Mode, const int ArgPos);<br>
+};<br>
+<br>
+} // namespace android<br>
+} // namespace tidy<br>
+} // namespace clang<br>
+<br>
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_<wbr>TIDY_ANDROID_CLOEXEC_H<br>
<br>
Added: clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>CloexecMemfdCreateCheck.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.cpp?rev=310630&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clang-tidy/android/<wbr>CloexecMemfdCreateCheck.cpp?<wbr>rev=310630&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>CloexecMemfdCreateCheck.cpp (added)<br>
+++ clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>CloexecMemfdCreateCheck.cpp Thu Aug 10 10:18:10 2017<br>
@@ -0,0 +1,32 @@<br>
+//===--- CloexecMemfdCreateCheck.cpp - clang-tidy--------------------<wbr>------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#include "CloexecMemfdCreateCheck.h"<br>
+<br>
+using namespace clang::ast_matchers;<br>
+<br>
+namespace clang {<br>
+namespace tidy {<br>
+namespace android {<br>
+<br>
+void CloexecMemfdCreateCheck::<wbr>registerMatchers(MatchFinder *Finder) {<br>
+  auto CharPointerType = hasType(pointerType(pointee(<wbr>isAnyCharacter())));<br>
+  registerMatchersImpl(<br>
+      Finder, functionDecl(returns(<wbr>isInteger()), hasName("memfd_create"),<br>
+                           hasParameter(0, CharPointerType),<br>
+                           hasParameter(1, hasType(isInteger()))));<br>
+}<br>
+<br>
+void CloexecMemfdCreateCheck::<wbr>check(const MatchFinder::MatchResult &Result) {<br>
+  insertMacroFlag(Result, "MFD_CLOEXEC", /*ArgPos=*/1);<br>
+}<br>
+<br>
+} // namespace android<br>
+} // namespace tidy<br>
+} // namespace clang<br>
<br>
Added: clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>CloexecMemfdCreateCheck.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.h?rev=310630&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clang-tidy/android/<wbr>CloexecMemfdCreateCheck.h?rev=<wbr>310630&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>CloexecMemfdCreateCheck.h (added)<br>
+++ clang-tools-extra/trunk/clang-<wbr>tidy/android/<wbr>CloexecMemfdCreateCheck.h Thu Aug 10 10:18:10 2017<br>
@@ -0,0 +1,35 @@<br>
+//===--- CloexecMemfdCreateCheck.h - clang-tidy-----------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_<wbr>TIDY_ANDROID_CLOEXEC_MEMFD_<wbr>CREATE_H<br>
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_<wbr>TIDY_ANDROID_CLOEXEC_MEMFD_<wbr>CREATE_H<br>
+<br>
+#include "CloexecCheck.h"<br>
+<br>
+namespace clang {<br>
+namespace tidy {<br>
+namespace android {<br>
+<br>
+/// Finds code that uses memfd_create() without using the MFD_CLOEXEC flag.<br>
+///<br>
+/// For the user-facing documentation see:<br>
+/// <a href="http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-memfd-create.html" rel="noreferrer" target="_blank">http://clang.llvm.org/extra/<wbr>clang-tidy/checks/android-<wbr>cloexec-memfd-create.html</a><br>
+class CloexecMemfdCreateCheck : public CloexecCheck {<br>
+public:<br>
+  CloexecMemfdCreateCheck(<wbr>StringRef Name, ClangTidyContext *Context)<br>
+      : CloexecCheck(Name, Context) {}<br>
+  void registerMatchers(ast_matchers:<wbr>:MatchFinder *Finder) override;<br>
+  void check(const ast_matchers::MatchFinder::<wbr>MatchResult &Result) override;<br>
+};<br>
+<br>
+} // namespace android<br>
+} // namespace tidy<br>
+} // namespace clang<br>
+<br>
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_<wbr>TIDY_ANDROID_CLOEXEC_MEMFD_<wbr>CREATE_H<br>
<br>
Modified: clang-tools-extra/trunk/docs/<wbr>ReleaseNotes.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=310630&r1=310629&r2=310630&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/docs/ReleaseNotes.rst?<wbr>rev=310630&r1=310629&r2=<wbr>310630&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/docs/<wbr>ReleaseNotes.rst (original)<br>
+++ clang-tools-extra/trunk/docs/<wbr>ReleaseNotes.rst Thu Aug 10 10:18:10 2017<br>
@@ -70,6 +70,12 @@ Improvements to clang-tidy<br>
       ``<wbr>AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``,<br>
       ``<wbr>AllowConditionalPointerCasts`` -> ``AllowPointerConditions``.<br>
<br>
+- New `android-cloexec-memfd_create<br>
+    <<a href="http://clang.llvm.org/extra/clang-tidy/checks/android-cloexec-memfd_create.html" rel="noreferrer" target="_blank">http://clang.llvm.org/extra/<wbr>clang-tidy/checks/android-<wbr>cloexec-memfd_create.html</a>>`_ check<br>
+<br>
+    Checks if the required file flag ``MFD_CLOEXEC`` is present in the argument of<br>
+      ``memfd_create()``.<br>
+<br>
 - New `bugprone-integer-division<br>
   <<a href="http://clang.llvm.org/extra/clang-tidy/checks/bugprone-integer-division.html" rel="noreferrer" target="_blank">http://clang.llvm.org/extra/<wbr>clang-tidy/checks/bugprone-<wbr>integer-division.html</a>>`_ check<br>
<br>
<br>
Added: clang-tools-extra/trunk/docs/<wbr>clang-tidy/checks/android-<wbr>cloexec-memfd-create.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/android-cloexec-memfd-create.rst?rev=310630&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/docs/clang-tidy/checks/<wbr>android-cloexec-memfd-create.<wbr>rst?rev=310630&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/docs/<wbr>clang-tidy/checks/android-<wbr>cloexec-memfd-create.rst (added)<br>
+++ clang-tools-extra/trunk/docs/<wbr>clang-tidy/checks/android-<wbr>cloexec-memfd-create.rst Thu Aug 10 10:18:10 2017<br>
@@ -0,0 +1,18 @@<br>
+.. title:: clang-tidy - android-cloexec-memfd-create<br>
+<br>
+android-cloexec-memfd-create<br>
+============================<br>
+<br>
+``memfd_create()`` should include ``MFD_CLOEXEC`` in its type argument to avoid<br>
+the file descriptor leakage. Without this flag, an opened sensitive file would<br>
+remain open across a fork+exec to a lower-privileged SELinux domain.<br>
+<br>
+Examples:<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  memfd_create(name, MFD_ALLOW_SEALING);<br>
+<br>
+  // becomes<br>
+<br>
+  memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);<br>
<br>
Modified: clang-tools-extra/trunk/docs/<wbr>clang-tidy/checks/list.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=310630&r1=310629&r2=310630&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/docs/clang-tidy/checks/<wbr>list.rst?rev=310630&r1=310629&<wbr>r2=310630&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/docs/<wbr>clang-tidy/checks/list.rst (original)<br>
+++ clang-tools-extra/trunk/docs/<wbr>clang-tidy/checks/list.rst Thu Aug 10 10:18:10 2017<br>
@@ -6,6 +6,7 @@ Clang-Tidy Checks<br>
 .. toctree::<br>
    android-cloexec-creat<br>
    android-cloexec-fopen<br>
+   android-cloexec-memfd-create<br>
    android-cloexec-open<br>
    android-cloexec-socket<br>
    boost-use-to-string<br>
<br>
Added: clang-tools-extra/trunk/test/<wbr>clang-tidy/android-cloexec-<wbr>memfd-create.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/android-cloexec-memfd-create.cpp?rev=310630&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/test/clang-tidy/android-<wbr>cloexec-memfd-create.cpp?rev=<wbr>310630&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/test/<wbr>clang-tidy/android-cloexec-<wbr>memfd-create.cpp (added)<br>
+++ clang-tools-extra/trunk/test/<wbr>clang-tidy/android-cloexec-<wbr>memfd-create.cpp Thu Aug 10 10:18:10 2017<br>
@@ -0,0 +1,63 @@<br>
+// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t<br>
+<br>
+#define MFD_ALLOW_SEALING 1<br>
+#define __O_CLOEXEC 3<br>
+#define MFD_CLOEXEC __O_CLOEXEC<br>
+#define TEMP_FAILURE_RETRY(exp) \<br>
+  ({                            \<br>
+    int _rc;                    \<br>
+    do {                        \<br>
+      _rc = (exp);              \<br>
+    } while (_rc == -1);        \<br>
+  })<br>
+#define NULL 0<br>
+<br>
+extern "C" int memfd_create(const char *name, unsigned int flags);<br>
+<br>
+void a() {<br>
+  memfd_create(NULL, MFD_ALLOW_SEALING);<br>
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should use MFD_CLOEXEC where possible [android-cloexec-memfd-create]<br>
+  // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC)<br>
+  TEMP_FAILURE_RETRY(memfd_<wbr>create(NULL, MFD_ALLOW_SEALING));<br>
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create'<br>
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_<wbr>create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC))<br>
+}<br>
+<br>
+void f() {<br>
+  memfd_create(NULL, 3);<br>
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create'<br>
+  // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC)<br>
+  TEMP_FAILURE_RETRY(memfd_<wbr>create(NULL, 3));<br>
+  // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create'<br>
+  // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_<wbr>create(NULL, 3 | MFD_CLOEXEC))<br>
+<br>
+  int flag = 3;<br>
+  memfd_create(NULL, flag);<br>
+  TEMP_FAILURE_RETRY(memfd_<wbr>create(NULL, flag));<br>
+}<br>
+<br>
+namespace i {<br>
+int memfd_create(const char *name, unsigned int flags);<br>
+<br>
+void d() {<br>
+  memfd_create(NULL, MFD_ALLOW_SEALING);<br>
+  TEMP_FAILURE_RETRY(memfd_<wbr>create(NULL, MFD_ALLOW_SEALING));<br>
+}<br>
+<br>
+} // namespace i<br>
+<br>
+void e() {<br>
+  memfd_create(NULL, MFD_CLOEXEC);<br>
+  TEMP_FAILURE_RETRY(memfd_<wbr>create(NULL, MFD_CLOEXEC));<br>
+  memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC);<br>
+  TEMP_FAILURE_RETRY(memfd_<wbr>create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC));<br>
+}<br>
+<br>
+class G {<br>
+public:<br>
+  int memfd_create(const char *name, unsigned int flags);<br>
+  void d() {<br>
+    memfd_create(NULL, MFD_ALLOW_SEALING);<br>
+    TEMP_FAILURE_RETRY(memfd_<wbr>create(NULL, MFD_ALLOW_SEALING));<br>
+  }<br>
+};<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>