[clang-tools-extra] r310630 - [clang-tidy] Refactor the code and add a close-on-exec check on memfd_create() in Android module.

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 10 14:22:47 PDT 2017


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 at 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 <thakis at 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 at 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 at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>
>>
>>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170810/447fcee6/attachment-0001.html>


More information about the cfe-commits mailing list