I think on Linux overload resolution was selecting 'DiagnosticBuilder&operator<<(DiagnosticBuilder&DB,int)' for you, which is probably not right anyway. I didn't find any tests for this diagnostic, so I couldn't fix it, and ended up reverting the change in r310661.
On Thu, Aug 10, 2017 at 12:15 PM, Yan Wang via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Yes. Sorry for the broken. But it works well in my Linux machine. Maybe I > should revert it first. > > Thanks, > Yan Wang > > On Thu, Aug 10, 2017 at 12:07 PM, Nico Weber <tha...@chromium.org> wrote: > >> Not sure if you've seen it, this broke the Windows build: >> http://lab.llvm.org:8011/builders/clang-x64-ninja-win7/build >> s/5880/steps/build%20stage%201/logs/stdio >> >> 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\cla >> ng-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\ex >> tra\clang-tidy\android\CloexecCheck.cpp >> D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\tools\ex >> tra\clang-tidy\android\CloexecCheck.cpp(99): error C2666: >> 'clang::operator <<': 4 overloads have similar conversions >> 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 &)' >> 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 &)' >> 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)' >> 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)' >> 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 *)' >> 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 *)' >> 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 &)' >> 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)' >> 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 &)' >> 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 *)' >> 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 *)' >> 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 &)' >> 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)' >> 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)' >> 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)' >> 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 *)' >> 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)' >> 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)' >> 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)' >> 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)' >> 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 &)' >> 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 &)' >> 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 &)' >> 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)' >> 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>)' >> 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 &)' >> 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 &)' >> 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>)' >> 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)' >> 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 *)' >> 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)' >> 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)' >> 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)' >> 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 *)' >> 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)' >> 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)' >> 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)' >> D:\buildslave\clang-x64-ninja-win7\llvm\tools\clang\tools\ex >> tra\clang-tidy\android\CloexecCheck.cpp(99): note: while trying to match >> the argument list '(const clang::DiagnosticBuilder, const char)' >> ninja: build stopped: subcommand failed. >> >> On Thu, Aug 10, 2017 at 1:18 PM, Yan Wang via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> Author: yawanng >>> Date: Thu Aug 10 10:18:10 2017 >>> New Revision: 310630 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=310630&view=rev >>> Log: >>> [clang-tidy] Refactor the code and add a close-on-exec check on >>> memfd_create() in Android module. >>> >>> Summary: >>> 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. >>> 2. memfd_create() is better to set MFD_CLOEXEC flag to avoid file >>> descriptor leakage. >>> >>> Reviewers: alexfh, aaron.ballman, hokein >>> >>> Reviewed By: alexfh, hokein >>> >>> Subscribers: Eugene.Zelenko, chh, cfe-commits, srhines, mgorny, >>> JDevlieghere, xazax.hun >>> >>> Tags: #clang-tools-extra >>> >>> Differential Revision: https://reviews.llvm.org/D35372 >>> >>> Added: >>> clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.cpp >>> clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.h >>> clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreat >>> eCheck.cpp >>> clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.h >>> clang-tools-extra/trunk/docs/clang-tidy/checks/android-cloex >>> ec-memfd-create.rst >>> clang-tools-extra/trunk/test/clang-tidy/android-cloexec-memf >>> d-create.cpp >>> Modified: >>> clang-tools-extra/trunk/clang-tidy/android/AndroidTidyModule.cpp >>> clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt >>> clang-tools-extra/trunk/docs/ReleaseNotes.rst >>> clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst >>> >>> Modified: clang-tools-extra/trunk/clang-tidy/android/AndroidTidyModule >>> .cpp >>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/ >>> clang-tidy/android/AndroidTidyModule.cpp?rev=310630&r1=31062 >>> 9&r2=310630&view=diff >>> ============================================================ >>> ================== >>> --- clang-tools-extra/trunk/clang-tidy/android/AndroidTidyModule.cpp >>> (original) >>> +++ clang-tools-extra/trunk/clang-tidy/android/AndroidTidyModule.cpp >>> Thu Aug 10 10:18:10 2017 >>> @@ -12,6 +12,7 @@ >>> #include "../ClangTidyModuleRegistry.h" >>> #include "CloexecCreatCheck.h" >>> #include "CloexecFopenCheck.h" >>> +#include "CloexecMemfdCreateCheck.h" >>> #include "CloexecOpenCheck.h" >>> #include "CloexecSocketCheck.h" >>> >>> @@ -27,6 +28,8 @@ public: >>> void addCheckFactories(ClangTidyCheckFactories &CheckFactories) >>> override { >>> CheckFactories.registerCheck<CloexecCreatCheck>("android-cl >>> oexec-creat"); >>> CheckFactories.registerCheck<CloexecFopenCheck>("android-cl >>> oexec-fopen"); >>> + CheckFactories.registerCheck<CloexecMemfdCreateCheck>( >>> + "android-cloexec-memfd-create"); >>> CheckFactories.registerCheck<CloexecOpenCheck>("android-clo >>> exec-open"); >>> CheckFactories.registerCheck<CloexecSocketCheck>("android-c >>> loexec-socket"); >>> } >>> >>> Modified: clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt >>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/ >>> clang-tidy/android/CMakeLists.txt?rev=310630&r1=310629&r2=31 >>> 0630&view=diff >>> ============================================================ >>> ================== >>> --- clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt (original) >>> +++ clang-tools-extra/trunk/clang-tidy/android/CMakeLists.txt Thu Aug >>> 10 10:18:10 2017 >>> @@ -2,8 +2,10 @@ set(LLVM_LINK_COMPONENTS support) >>> >>> add_clang_library(clangTidyAndroidModule >>> AndroidTidyModule.cpp >>> + CloexecCheck.cpp >>> CloexecCreatCheck.cpp >>> CloexecFopenCheck.cpp >>> + CloexecMemfdCreateCheck.cpp >>> CloexecOpenCheck.cpp >>> CloexecSocketCheck.cpp >>> >>> >>> Added: clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.cpp >>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/ >>> clang-tidy/android/CloexecCheck.cpp?rev=310630&view=auto >>> ============================================================ >>> ================== >>> --- clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.cpp (added) >>> +++ clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.cpp Thu Aug >>> 10 10:18:10 2017 >>> @@ -0,0 +1,105 @@ >>> +//===--- CloexecCheck.cpp - clang-tidy-------------------- >>> -----------------===// >>> +// >>> +// The LLVM Compiler Infrastructure >>> +// >>> +// This file is distributed under the University of Illinois Open Source >>> +// License. See LICENSE.TXT for details. >>> +// >>> +//===------------------------------------------------------ >>> ----------------===// >>> + >>> +#include "CloexecCheck.h" >>> +#include "../utils/ASTUtils.h" >>> +#include "clang/AST/ASTContext.h" >>> +#include "clang/ASTMatchers/ASTMatchFinder.h" >>> +#include "clang/Lex/Lexer.h" >>> + >>> +using namespace clang::ast_matchers; >>> + >>> +namespace clang { >>> +namespace tidy { >>> +namespace android { >>> + >>> +namespace { >>> + >>> +const char *const FuncDeclBindingStr = "funcDecl"; >>> +const char *const FuncBindingStr = "func"; >>> + >>> +// Helper function to form the correct string mode for Type3. >>> +// Build the replace text. If it's string constant, add <Mode> directly >>> in the >>> +// end of the string. Else, add <Mode>. >>> +std::string buildFixMsgForStringFlag(const Expr *Arg, const >>> SourceManager &SM, >>> + const LangOptions &LangOpts, char >>> Mode) { >>> + if (Arg->getLocStart().isMacroID()) >>> + return (Lexer::getSourceText( >>> + CharSourceRange::getTokenRange(Arg->getSourceRange()), >>> SM, >>> + LangOpts) + >>> + " \"" + Twine(Mode) + "\"") >>> + .str(); >>> + >>> + StringRef SR = cast<StringLiteral>(Arg->Ignor >>> eParenCasts())->getString(); >>> + return ("\"" + SR + Twine(Mode) + "\"").str(); >>> +} >>> +} // namespace >>> + >>> +void CloexecCheck::registerMatchersImpl( >>> + MatchFinder *Finder, internal::Matcher<FunctionDecl> Function) { >>> + // We assume all the checked APIs are C functions. >>> + Finder->addMatcher( >>> + callExpr( >>> + callee(functionDecl(isExternC(), >>> Function).bind(FuncDeclBindingStr))) >>> + .bind(FuncBindingStr), >>> + this); >>> +} >>> + >>> +void CloexecCheck::insertMacroFlag(const MatchFinder::MatchResult >>> &Result, >>> + StringRef MacroFlag, int ArgPos) { >>> + const auto *MatchedCall = Result.Nodes.getNodeAs<CallExp >>> r>(FuncBindingStr); >>> + const auto *FlagArg = MatchedCall->getArg(ArgPos); >>> + const auto *FD = Result.Nodes.getNodeAs<Functio >>> nDecl>(FuncDeclBindingStr); >>> + SourceManager &SM = *Result.SourceManager; >>> + >>> + if (utils::exprHasBitFlagWithSpelling(FlagArg->IgnoreParenCasts(), >>> SM, >>> + Result.Context->getLangOpts(), >>> + MacroFlag)) >>> + return; >>> + >>> + SourceLocation EndLoc = >>> + Lexer::getLocForEndOfToken(SM.getFileLoc(FlagArg->getLocEnd()), >>> 0, SM, >>> + Result.Context->getLangOpts()); >>> + >>> + diag(EndLoc, "%0 should use %1 where possible") >>> + << FD << MacroFlag >>> + << FixItHint::CreateInsertion(EndLoc, (Twine(" | ") + >>> MacroFlag).str()); >>> +} >>> + >>> +void CloexecCheck::replaceFunc(const MatchFinder::MatchResult &Result, >>> + StringRef WarningMsg, StringRef FixMsg) { >>> + const auto *MatchedCall = Result.Nodes.getNodeAs<CallExp >>> r>(FuncBindingStr); >>> + diag(MatchedCall->getLocStart(), WarningMsg) >>> + << FixItHint::CreateReplacement(MatchedCall->getSourceRange(), >>> FixMsg); >>> +} >>> + >>> +void CloexecCheck::insertStringFlag( >>> + const ast_matchers::MatchFinder::MatchResult &Result, const char >>> Mode, >>> + const int ArgPos) { >>> + const auto *MatchedCall = Result.Nodes.getNodeAs<CallExp >>> r>(FuncBindingStr); >>> + const auto *FD = Result.Nodes.getNodeAs<Functio >>> nDecl>(FuncDeclBindingStr); >>> + const auto *ModeArg = MatchedCall->getArg(ArgPos); >>> + >>> + // Check if the <Mode> may be in the mode string. >>> + const auto *ModeStr = dyn_cast<StringLiteral>(ModeAr >>> g->IgnoreParenCasts()); >>> + if (!ModeStr || (ModeStr->getString().find(Mode) != StringRef::npos)) >>> + return; >>> + >>> + const std::string &ReplacementText = buildFixMsgForStringFlag( >>> + ModeArg, *Result.SourceManager, Result.Context->getLangOpts(), >>> Mode); >>> + >>> + diag(ModeArg->getLocStart(), "use %0 mode '%1' to set O_CLOEXEC") >>> + << FD << Mode >>> + << FixItHint::CreateReplacement(ModeArg->getSourceRange(), >>> + ReplacementText); >>> +} >>> + >>> +} // namespace android >>> +} // namespace tidy >>> +} // namespace clang >>> >>> Added: clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.h >>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/ >>> clang-tidy/android/CloexecCheck.h?rev=310630&view=auto >>> ============================================================ >>> ================== >>> --- clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.h (added) >>> +++ clang-tools-extra/trunk/clang-tidy/android/CloexecCheck.h Thu Aug >>> 10 10:18:10 2017 >>> @@ -0,0 +1,95 @@ >>> +//===--- CloexecCheck.h - clang-tidy-----------------------------*- >>> C++ -*-===// >>> +// >>> +// The LLVM Compiler Infrastructure >>> +// >>> +// This file is distributed under the University of Illinois Open Source >>> +// License. See LICENSE.TXT for details. >>> +// >>> +//===------------------------------------------------------ >>> ----------------===// >>> +/// >>> +/// \file >>> +/// This file contains the declaration of the CloexecCheck class, which >>> is the >>> +/// base class for all of the close-on-exec checks in Android module. >>> +/// >>> +//===------------------------------------------------------ >>> ----------------===// >>> + >>> +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H >>> +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H >>> + >>> +#include "../ClangTidy.h" >>> + >>> +namespace clang { >>> +namespace tidy { >>> +namespace android { >>> + >>> +/// \brief The base class for all close-on-exec checks in Android >>> module. >>> +/// To be specific, there are some functions that need the >>> close-on-exec flag to >>> +/// prevent the file descriptor leakage on fork+exec and this class >>> provides >>> +/// utilities to identify and fix these C functions. >>> +class CloexecCheck : public ClangTidyCheck { >>> +public: >>> + CloexecCheck(StringRef Name, ClangTidyContext *Context) >>> + : ClangTidyCheck(Name, Context) {} >>> + >>> +protected: >>> + void >>> + registerMatchersImpl(ast_matchers::MatchFinder *Finder, >>> + ast_matchers::internal::Matcher<FunctionDecl> >>> Function); >>> + >>> + /// Currently, we have three types of fixes. >>> + /// >>> + /// Type1 is to insert the necessary macro flag in the flag argument. >>> For >>> + /// example, 'O_CLOEXEC' is required in function 'open()', so >>> + /// \code >>> + /// open(file, O_RDONLY); >>> + /// \endcode >>> + /// should be >>> + /// \code >>> + /// open(file, O_RDONLY | O_CLOEXE); >>> + /// \endcode >>> + /// >>> + /// \param [out] Result MatchResult from AST matcher. >>> + /// \param MacroFlag The macro name of the flag. >>> + /// \param ArgPos The 0-based position of the flag argument. >>> + void insertMacroFlag(const ast_matchers::MatchFinder::MatchResult >>> &Result, >>> + StringRef MarcoFlag, int ArgPos); >>> + >>> + /// Type2 is to replace the API to another function that has required >>> the >>> + /// ability. For example: >>> + /// \code >>> + /// creat(path, mode); >>> + /// \endcode >>> + /// should be >>> + /// \code >>> + /// open(path, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, mode) >>> + /// \endcode >>> + /// >>> + /// \param [out] Result MatchResult from AST matcher. >>> + /// \param WarningMsg The warning message. >>> + /// \param FixMsg The fix message. >>> + void replaceFunc(const ast_matchers::MatchFinder::MatchResult >>> &Result, >>> + StringRef WarningMsg, StringRef FixMsg); >>> + >>> + /// Type3 is also to add a flag to the corresponding argument, but >>> this time, >>> + /// the flag is some string and each char represents a mode rather >>> than a >>> + /// macro. For example, 'fopen' needs char 'e' in its mode argument >>> string, so >>> + /// \code >>> + /// fopen(in_file, "r"); >>> + /// \endcode >>> + /// should be >>> + /// \code >>> + /// fopen(in_file, "re"); >>> + /// \endcode >>> + /// >>> + /// \param [out] Result MatchResult from AST matcher. >>> + /// \param Mode The required mode char. >>> + /// \param ArgPos The 0-based position of the flag argument. >>> + void insertStringFlag(const ast_matchers::MatchFinder::MatchResult >>> &Result, >>> + char Mode, const int ArgPos); >>> +}; >>> + >>> +} // namespace android >>> +} // namespace tidy >>> +} // namespace clang >>> + >>> +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_H >>> >>> Added: clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreat >>> eCheck.cpp >>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/ >>> clang-tidy/android/CloexecMemfdCreateCheck.cpp?rev=310630&view=auto >>> ============================================================ >>> ================== >>> --- clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.cpp >>> (added) >>> +++ clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.cpp >>> Thu Aug 10 10:18:10 2017 >>> @@ -0,0 +1,32 @@ >>> +//===--- CloexecMemfdCreateCheck.cpp - clang-tidy-------------------- >>> ------===// >>> +// >>> +// The LLVM Compiler Infrastructure >>> +// >>> +// This file is distributed under the University of Illinois Open Source >>> +// License. See LICENSE.TXT for details. >>> +// >>> +//===------------------------------------------------------ >>> ----------------===// >>> + >>> +#include "CloexecMemfdCreateCheck.h" >>> + >>> +using namespace clang::ast_matchers; >>> + >>> +namespace clang { >>> +namespace tidy { >>> +namespace android { >>> + >>> +void CloexecMemfdCreateCheck::registerMatchers(MatchFinder *Finder) { >>> + auto CharPointerType = hasType(pointerType(pointee(is >>> AnyCharacter()))); >>> + registerMatchersImpl( >>> + Finder, functionDecl(returns(isInteger()), >>> hasName("memfd_create"), >>> + hasParameter(0, CharPointerType), >>> + hasParameter(1, hasType(isInteger())))); >>> +} >>> + >>> +void CloexecMemfdCreateCheck::check(const MatchFinder::MatchResult >>> &Result) { >>> + insertMacroFlag(Result, "MFD_CLOEXEC", /*ArgPos=*/1); >>> +} >>> + >>> +} // namespace android >>> +} // namespace tidy >>> +} // namespace clang >>> >>> Added: clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreat >>> eCheck.h >>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/ >>> clang-tidy/android/CloexecMemfdCreateCheck.h?rev=310630&view=auto >>> ============================================================ >>> ================== >>> --- clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.h >>> (added) >>> +++ clang-tools-extra/trunk/clang-tidy/android/CloexecMemfdCreateCheck.h >>> Thu Aug 10 10:18:10 2017 >>> @@ -0,0 +1,35 @@ >>> +//===--- CloexecMemfdCreateCheck.h - clang-tidy-----------------*- C++ >>> -*-===// >>> +// >>> +// The LLVM Compiler Infrastructure >>> +// >>> +// This file is distributed under the University of Illinois Open Source >>> +// License. See LICENSE.TXT for details. >>> +// >>> +//===------------------------------------------------------ >>> ----------------===// >>> + >>> +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_MEMFD_CREA >>> TE_H >>> +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_MEMFD_CREA >>> TE_H >>> + >>> +#include "CloexecCheck.h" >>> + >>> +namespace clang { >>> +namespace tidy { >>> +namespace android { >>> + >>> +/// Finds code that uses memfd_create() without using the MFD_CLOEXEC >>> flag. >>> +/// >>> +/// For the user-facing documentation see: >>> +/// http://clang.llvm.org/extra/clang-tidy/checks/android-cloexe >>> c-memfd-create.html >>> +class CloexecMemfdCreateCheck : public CloexecCheck { >>> +public: >>> + CloexecMemfdCreateCheck(StringRef Name, ClangTidyContext *Context) >>> + : CloexecCheck(Name, Context) {} >>> + void registerMatchers(ast_matchers::MatchFinder *Finder) override; >>> + void check(const ast_matchers::MatchFinder::MatchResult &Result) >>> override; >>> +}; >>> + >>> +} // namespace android >>> +} // namespace tidy >>> +} // namespace clang >>> + >>> +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ANDROID_CLOEXEC_MEMFD_CREA >>> TE_H >>> >>> Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst >>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/ >>> docs/ReleaseNotes.rst?rev=310630&r1=310629&r2=310630&view=diff >>> ============================================================ >>> ================== >>> --- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original) >>> +++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Thu Aug 10 10:18:10 >>> 2017 >>> @@ -70,6 +70,12 @@ Improvements to clang-tidy >>> ``AllowConditionalIntegerCasts`` -> ``AllowIntegerConditions``, >>> ``AllowConditionalPointerCasts`` -> ``AllowPointerConditions``. >>> >>> +- New `android-cloexec-memfd_create >>> + <http://clang.llvm.org/extra/clang-tidy/checks/android-cloex >>> ec-memfd_create.html>`_ check >>> + >>> + Checks if the required file flag ``MFD_CLOEXEC`` is present in the >>> argument of >>> + ``memfd_create()``. >>> + >>> - New `bugprone-integer-division >>> <http://clang.llvm.org/extra/clang-tidy/checks/bugprone-int >>> eger-division.html>`_ check >>> >>> >>> Added: clang-tools-extra/trunk/docs/clang-tidy/checks/android-cloex >>> ec-memfd-create.rst >>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/ >>> docs/clang-tidy/checks/android-cloexec-memfd-create.rst?rev= >>> 310630&view=auto >>> ============================================================ >>> ================== >>> --- >>> clang-tools-extra/trunk/docs/clang-tidy/checks/android-cloexec-memfd-create.rst >>> (added) >>> +++ >>> clang-tools-extra/trunk/docs/clang-tidy/checks/android-cloexec-memfd-create.rst >>> Thu Aug 10 10:18:10 2017 >>> @@ -0,0 +1,18 @@ >>> +.. title:: clang-tidy - android-cloexec-memfd-create >>> + >>> +android-cloexec-memfd-create >>> +============================ >>> + >>> +``memfd_create()`` should include ``MFD_CLOEXEC`` in its type argument >>> to avoid >>> +the file descriptor leakage. Without this flag, an opened sensitive >>> file would >>> +remain open across a fork+exec to a lower-privileged SELinux domain. >>> + >>> +Examples: >>> + >>> +.. code-block:: c++ >>> + >>> + memfd_create(name, MFD_ALLOW_SEALING); >>> + >>> + // becomes >>> + >>> + memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC); >>> >>> Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst >>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/ >>> docs/clang-tidy/checks/list.rst?rev=310630&r1=310629&r2=310630&view=diff >>> ============================================================ >>> ================== >>> --- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original) >>> +++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Thu Aug 10 >>> 10:18:10 2017 >>> @@ -6,6 +6,7 @@ Clang-Tidy Checks >>> .. toctree:: >>> android-cloexec-creat >>> android-cloexec-fopen >>> + android-cloexec-memfd-create >>> android-cloexec-open >>> android-cloexec-socket >>> boost-use-to-string >>> >>> Added: clang-tools-extra/trunk/test/clang-tidy/android-cloexec-memf >>> d-create.cpp >>> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/ >>> test/clang-tidy/android-cloexec-memfd-create.cpp?rev=310630&view=auto >>> ============================================================ >>> ================== >>> --- clang-tools-extra/trunk/test/clang-tidy/android-cloexec-memfd-create.cpp >>> (added) >>> +++ clang-tools-extra/trunk/test/clang-tidy/android-cloexec-memfd-create.cpp >>> Thu Aug 10 10:18:10 2017 >>> @@ -0,0 +1,63 @@ >>> +// RUN: %check_clang_tidy %s android-cloexec-memfd-create %t >>> + >>> +#define MFD_ALLOW_SEALING 1 >>> +#define __O_CLOEXEC 3 >>> +#define MFD_CLOEXEC __O_CLOEXEC >>> +#define TEMP_FAILURE_RETRY(exp) \ >>> + ({ \ >>> + int _rc; \ >>> + do { \ >>> + _rc = (exp); \ >>> + } while (_rc == -1); \ >>> + }) >>> +#define NULL 0 >>> + >>> +extern "C" int memfd_create(const char *name, unsigned int flags); >>> + >>> +void a() { >>> + memfd_create(NULL, MFD_ALLOW_SEALING); >>> + // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: 'memfd_create' should >>> use MFD_CLOEXEC where possible [android-cloexec-memfd-create] >>> + // CHECK-FIXES: memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC) >>> + TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING)); >>> + // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: 'memfd_create' >>> + // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, >>> MFD_ALLOW_SEALING | MFD_CLOEXEC)) >>> +} >>> + >>> +void f() { >>> + memfd_create(NULL, 3); >>> + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'memfd_create' >>> + // CHECK-FIXES: memfd_create(NULL, 3 | MFD_CLOEXEC) >>> + TEMP_FAILURE_RETRY(memfd_create(NULL, 3)); >>> + // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: 'memfd_create' >>> + // CHECK-FIXES: TEMP_FAILURE_RETRY(memfd_create(NULL, 3 | >>> MFD_CLOEXEC)) >>> + >>> + int flag = 3; >>> + memfd_create(NULL, flag); >>> + TEMP_FAILURE_RETRY(memfd_create(NULL, flag)); >>> +} >>> + >>> +namespace i { >>> +int memfd_create(const char *name, unsigned int flags); >>> + >>> +void d() { >>> + memfd_create(NULL, MFD_ALLOW_SEALING); >>> + TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING)); >>> +} >>> + >>> +} // namespace i >>> + >>> +void e() { >>> + memfd_create(NULL, MFD_CLOEXEC); >>> + TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_CLOEXEC)); >>> + memfd_create(NULL, MFD_ALLOW_SEALING | MFD_CLOEXEC); >>> + TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING | >>> MFD_CLOEXEC)); >>> +} >>> + >>> +class G { >>> +public: >>> + int memfd_create(const char *name, unsigned int flags); >>> + void d() { >>> + memfd_create(NULL, MFD_ALLOW_SEALING); >>> + TEMP_FAILURE_RETRY(memfd_create(NULL, MFD_ALLOW_SEALING)); >>> + } >>> +}; >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> cfe-commits@lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> >> >> > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits