Author: paulhoad Date: Fri Feb 8 09:00:01 2019 New Revision: 353535 URL: http://llvm.org/viewvc/llvm-project?rev=353535&view=rev Log: [clang-tidy] Add options to bugprone-argument-comment to add missing argument comments to literals
bugprone-argument-comment only supports identifying those comments which do not match the function parameter name This revision add 3 options to adding missing argument comments to literals (granularity on type is added to control verbosity of fixit) ``` CheckOptions: - key: bugprone-argument-comment.CommentBoolLiterals value: '1' - key: bugprone-argument-comment.CommentFloatLiterals value: '1' - key: bugprone-argument-comment.CommentIntegerLiterals value: '1' - key: bugprone-argument-comment.CommentStringLiterals value: '1' - key: bugprone-argument-comment.CommentCharacterLiterals value: '1' - key: bugprone-argument-comment.CommentUserDefinedLiterals value: '1' - key: bugprone-argument-comment.CommentNullPtrs value: '1' ``` After applying these options, literal arguments will be preceded with /*ParameterName=*/ Reviewers: JonasToth, Eugene.Zelenko, alexfh, hokein, aaron.ballman Reviewed By: aaron.ballman, Eugene.Zelenko Differential Revision: https://reviews.llvm.org/D57674 Added: clang-tools-extra/trunk/test/clang-tidy/bugprone-argument-comment-literals.cpp Modified: clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.cpp clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.h clang-tools-extra/trunk/docs/ReleaseNotes.rst clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-argument-comment.rst Modified: clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.cpp?rev=353535&r1=353534&r2=353535&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.cpp Fri Feb 8 09:00:01 2019 @@ -11,6 +11,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Token.h" + #include "../utils/LexerUtils.h" using namespace clang::ast_matchers; @@ -23,17 +24,37 @@ ArgumentCommentCheck::ArgumentCommentChe ClangTidyContext *Context) : ClangTidyCheck(Name, Context), StrictMode(Options.getLocalOrGlobal("StrictMode", 0) != 0), + CommentBoolLiterals(Options.getLocalOrGlobal("CommentBoolLiterals", 0) != + 0), + CommentIntegerLiterals( + Options.getLocalOrGlobal("CommentIntegerLiterals", 0) != 0), + CommentFloatLiterals( + Options.getLocalOrGlobal("CommentFloatLiterals", 0) != 0), + CommentStringLiterals( + Options.getLocalOrGlobal("CommentStringLiterals", 0) != 0), + CommentUserDefinedLiterals( + Options.getLocalOrGlobal("CommentUserDefinedLiterals", 0) != 0), + CommentCharacterLiterals( + Options.getLocalOrGlobal("CommentCharacterLiterals", 0) != 0), + CommentNullPtrs(Options.getLocalOrGlobal("CommentNullPtrs", 0) != 0), IdentRE("^(/\\* *)([_A-Za-z][_A-Za-z0-9]*)( *= *\\*/)$") {} void ArgumentCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "StrictMode", StrictMode); + Options.store(Opts, "CommentBoolLiterals", CommentBoolLiterals); + Options.store(Opts, "CommentIntegerLiterals", CommentIntegerLiterals); + Options.store(Opts, "CommentFloatLiterals", CommentFloatLiterals); + Options.store(Opts, "CommentStringLiterals", CommentStringLiterals); + Options.store(Opts, "CommentUserDefinedLiterals", CommentUserDefinedLiterals); + Options.store(Opts, "CommentCharacterLiterals", CommentCharacterLiterals); + Options.store(Opts, "CommentNullPtrs", CommentNullPtrs); } void ArgumentCommentCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( callExpr(unless(cxxOperatorCallExpr()), - // NewCallback's arguments relate to the pointed function, don't - // check them against NewCallback's parameter names. + // NewCallback's arguments relate to the pointed function, + // don't check them against NewCallback's parameter names. // FIXME: Make this configurable. unless(hasDeclaration(functionDecl( hasAnyName("NewCallback", "NewPermanentCallback"))))) @@ -126,8 +147,8 @@ static bool isLikelyTypo(llvm::ArrayRef< const unsigned Threshold = 2; // Other parameters must be an edit distance at least Threshold more away - // from this parameter. This gives us greater confidence that this is a typo - // of this parameter and not one with a similar name. + // from this parameter. This gives us greater confidence that this is a + // typo of this parameter and not one with a similar name. unsigned OtherED = ArgNameLower.edit_distance(II->getName().lower(), /*AllowReplacements=*/true, ThisED + Threshold); @@ -180,8 +201,8 @@ static const CXXMethodDecl *findMockedMe } return nullptr; } - if (const auto *Next = dyn_cast_or_null<CXXMethodDecl>( - Method->getNextDeclInContext())) { + if (const auto *Next = + dyn_cast_or_null<CXXMethodDecl>(Method->getNextDeclInContext())) { if (looksLikeExpectMethod(Next) && areMockAndExpectMethods(Method, Next)) return Method; } @@ -206,6 +227,21 @@ static const FunctionDecl *resolveMocks( return Func; } +// Given the argument type and the options determine if we should +// be adding an argument comment. +bool ArgumentCommentCheck::shouldAddComment(const Expr *Arg) const { + if (Arg->getExprLoc().isMacroID()) + return false; + Arg = Arg->IgnoreImpCasts(); + return (CommentBoolLiterals && isa<CXXBoolLiteralExpr>(Arg)) || + (CommentIntegerLiterals && isa<IntegerLiteral>(Arg)) || + (CommentFloatLiterals && isa<FloatingLiteral>(Arg)) || + (CommentUserDefinedLiterals && isa<UserDefinedLiteral>(Arg)) || + (CommentCharacterLiterals && isa<CharacterLiteral>(Arg)) || + (CommentStringLiterals && isa<StringLiteral>(Arg)) || + (CommentNullPtrs && isa<CXXNullPtrLiteralExpr>(Arg)); +} + void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, const FunctionDecl *OriginalCallee, SourceLocation ArgBeginLoc, @@ -219,7 +255,7 @@ void ArgumentCommentCheck::checkCallArgs if (NumArgs == 0) return; - auto makeFileCharRange = [Ctx](SourceLocation Begin, SourceLocation End) { + auto MakeFileCharRange = [Ctx](SourceLocation Begin, SourceLocation End) { return Lexer::makeFileCharRange(CharSourceRange::getCharRange(Begin, End), Ctx->getSourceManager(), Ctx->getLangOpts()); @@ -242,7 +278,7 @@ void ArgumentCommentCheck::checkCallArgs } CharSourceRange BeforeArgument = - makeFileCharRange(ArgBeginLoc, Args[I]->getBeginLoc()); + MakeFileCharRange(ArgBeginLoc, Args[I]->getBeginLoc()); ArgBeginLoc = Args[I]->getEndLoc(); std::vector<std::pair<SourceLocation, StringRef>> Comments; @@ -250,7 +286,7 @@ void ArgumentCommentCheck::checkCallArgs Comments = getCommentsInRange(Ctx, BeforeArgument); } else { // Fall back to parsing back from the start of the argument. - CharSourceRange ArgsRange = makeFileCharRange( + CharSourceRange ArgsRange = MakeFileCharRange( Args[I]->getBeginLoc(), Args[NumArgs - 1]->getEndLoc()); Comments = getCommentsBeforeLoc(Ctx, ArgsRange.getBegin()); } @@ -277,8 +313,19 @@ void ArgumentCommentCheck::checkCallArgs } } } + + // If the argument comments are missing for literals add them. + if (Comments.empty() && shouldAddComment(Args[I])) { + std::string ArgComment = + (llvm::Twine("/*") + II->getName() + "=*/").str(); + DiagnosticBuilder Diag = + diag(Args[I]->getBeginLoc(), + "argument comment missing for literal argument %0") + << II + << FixItHint::CreateInsertion(Args[I]->getBeginLoc(), ArgComment); + } } -} +} // namespace bugprone void ArgumentCommentCheck::check(const MatchFinder::MatchResult &Result) { const auto *E = Result.Nodes.getNodeAs<Expr>("expr"); Modified: clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.h?rev=353535&r1=353534&r2=353535&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.h (original) +++ clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.h Fri Feb 8 09:00:01 2019 @@ -26,7 +26,8 @@ namespace bugprone { /// /// ... /// f(/*bar=*/true); -/// // warning: argument name 'bar' in comment does not match parameter name 'foo' +/// // warning: argument name 'bar' in comment does not match parameter name +/// 'foo' /// \endcode /// /// The check tries to detect typos and suggest automated fixes for them. @@ -39,12 +40,21 @@ public: void storeOptions(ClangTidyOptions::OptionMap &Opts) override; private: - const bool StrictMode; + const unsigned StrictMode : 1; + const unsigned CommentBoolLiterals : 1; + const unsigned CommentIntegerLiterals : 1; + const unsigned CommentFloatLiterals : 1; + const unsigned CommentStringLiterals : 1; + const unsigned CommentUserDefinedLiterals : 1; + const unsigned CommentCharacterLiterals : 1; + const unsigned CommentNullPtrs : 1; llvm::Regex IdentRE; void checkCallArgs(ASTContext *Ctx, const FunctionDecl *Callee, SourceLocation ArgBeginLoc, llvm::ArrayRef<const Expr *> Args); + + bool shouldAddComment(const Expr *Arg) const; }; } // namespace bugprone Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=353535&r1=353534&r2=353535&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original) +++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Fri Feb 8 09:00:01 2019 @@ -92,6 +92,12 @@ Improvements to clang-tidy Checks whether there are underscores in googletest test and test case names in test macros, which is prohibited by the Googletest FAQ. +- The :doc:`bugprone-argument-comment + <clang-tidy/checks/bugprone-argument-comment>` now supports + `CommentBoolLiterals`, `CommentIntegerLiterals`, `CommentFloatLiterals`, + `CommentUserDefiniedLiterals`, `CommentStringLiterals`, + `CommentCharacterLiterals` & `CommentNullPtrs` options. + Improvements to include-fixer ----------------------------- Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-argument-comment.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-argument-comment.rst?rev=353535&r1=353534&r2=353535&view=diff ============================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-argument-comment.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-argument-comment.rst Fri Feb 8 09:00:01 2019 @@ -27,3 +27,158 @@ Options When zero (default value), the check will ignore leading and trailing underscores and case when comparing names -- otherwise they are taken into account. + +.. option:: CommentBoolLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the boolean literal argument. + +Before: + +.. code-block:: c++ + + void foo(bool TurnKey, bool PressButton); + + foo(true, false); + +After: + +.. code-block:: c++ + + void foo(bool TurnKey, bool PressButton); + + foo(/*TurnKey=*/true, /*PressButton=*/false); + +.. option:: CommentIntegerLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the integer literal argument. + +Before: + +.. code-block:: c++ + + void foo(int MeaningOfLife); + + foo(42); + +After: + +.. code-block:: c++ + + void foo(int MeaningOfLife); + + foo(/*MeaningOfLife=*/42); + +.. option:: CommentFloatLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the float/double literal argument. + +Before: + +.. code-block:: c++ + + void foo(float Pi); + + foo(3.14159); + +After: + +.. code-block:: c++ + + void foo(float Pi); + + foo(/*Pi=*/3.14159); + +.. option:: CommentStringLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the string literal argument. + +Before: + +.. code-block:: c++ + + void foo(const char *String); + void foo(const wchar_t *WideString); + + foo("Hello World"); + foo(L"Hello World"); + +After: + +.. code-block:: c++ + + void foo(const char *String); + void foo(const wchar_t *WideString); + + foo(/*String=*/"Hello World"); + foo(/*WideString=*/L"Hello World"); + +.. option:: CommentCharacterLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the character literal argument. + +Before: + +.. code-block:: c++ + + void foo(char *Character); + + foo('A'); + +After: + +.. code-block:: c++ + + void foo(char *Character); + + foo(/*Character=*/'A'); + +.. option:: CommentUserDefinedLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the user defined literal argument. + +Before: + +.. code-block:: c++ + + void foo(double Distance); + + double operator"" _km(long double); + + foo(402.0_km); + +After: + +.. code-block:: c++ + + void foo(double Distance); + + double operator"" _km(long double); + + foo(/*Distance=*/402.0_km); + +.. option:: CommentNullPtrs + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the nullptr literal argument. + +Before: + +.. code-block:: c++ + + void foo(A* Value); + + foo(nullptr); + +After: + +.. code-block:: c++ + + void foo(A* Value); + + foo(/*Value=*/nullptr); Added: clang-tools-extra/trunk/test/clang-tidy/bugprone-argument-comment-literals.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/bugprone-argument-comment-literals.cpp?rev=353535&view=auto ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/bugprone-argument-comment-literals.cpp (added) +++ clang-tools-extra/trunk/test/clang-tidy/bugprone-argument-comment-literals.cpp Fri Feb 8 09:00:01 2019 @@ -0,0 +1,124 @@ +// RUN: %check_clang_tidy %s bugprone-argument-comment %t -- \ +// RUN: -config="{CheckOptions: [{key: CommentBoolLiterals, value: 1},{key: CommentIntegerLiterals, value: 1}, {key: CommentFloatLiterals, value: 1}, {key: CommentUserDefinedLiterals, value: 1}, {key: CommentStringLiterals, value: 1}, {key: CommentNullPtrs, value: 1}, {key: CommentCharacterLiterals, value: 1}]}" -- + +struct A { + void foo(bool abc); + void foo(bool abc, bool cde); + void foo(const char *, bool abc); + void foo(int iabc); + void foo(float fabc); + void foo(double dabc); + void foo(const char *strabc); + void fooW(const wchar_t *wstrabc); + void fooPtr(A *ptrabc); + void foo(char chabc); +}; + +#define FOO 1 + +void g(int a); +void h(double b); +void i(const char *c); + +double operator"" _km(long double); + +void test() { + A a; + + a.foo(true); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/true); + + a.foo(false); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false); + + a.foo(true, false); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-MESSAGES: [[@LINE-2]]:15: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/true, /*cde=*/false); + + a.foo(false, true); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-MESSAGES: [[@LINE-2]]:16: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true); + + a.foo(/*abc=*/false, true); + // CHECK-MESSAGES: [[@LINE-1]]:24: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true); + + a.foo(false, /*cde=*/true); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true); + + bool val1 = true; + bool val2 = false; + a.foo(val1, val2); + + a.foo("", true); + // CHECK-MESSAGES: [[@LINE-1]]:13: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo("", /*abc=*/true); + + a.foo(0); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'iabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*iabc=*/0); + + a.foo(1.0f); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'fabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*fabc=*/1.0f); + + a.foo(1.0); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'dabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*dabc=*/1.0); + + int val3 = 10; + a.foo(val3); + + float val4 = 10.0; + a.foo(val4); + + double val5 = 10.0; + a.foo(val5); + + a.foo("Hello World"); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'strabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*strabc=*/"Hello World"); + // + a.fooW(L"Hello World"); + // CHECK-MESSAGES: [[@LINE-1]]:10: warning: argument comment missing for literal argument 'wstrabc' [bugprone-argument-comment] + // CHECK-FIXES: a.fooW(/*wstrabc=*/L"Hello World"); + + a.fooPtr(nullptr); + // CHECK-MESSAGES: [[@LINE-1]]:12: warning: argument comment missing for literal argument 'ptrabc' [bugprone-argument-comment] + // CHECK-FIXES: a.fooPtr(/*ptrabc=*/nullptr); + + a.foo(402.0_km); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'dabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*dabc=*/402.0_km); + + a.foo('A'); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'chabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*chabc=*/'A'); + + g(FOO); + h(1.0f); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument 'b' [bugprone-argument-comment] + // CHECK-FIXES: h(/*b=*/1.0f); + i(__FILE__); + + // FIXME Would like the below to add argument comments. + g((1)); + // FIXME But we should not add argument comments here. + g(_Generic(0, int : 0)); +} + +void f(bool _with_underscores_); +void ignores_underscores() { + f(false); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument '_with_underscores_' [bugprone-argument-comment] + // CHECK-FIXES: f(/*_with_underscores_=*/false); + + f(true); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument + // CHECK-FIXES: f(/*_with_underscores_=*/true); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits