Index: clang-tidy/modernize/CMakeLists.txt =================================================================== --- clang-tidy/modernize/CMakeLists.txt +++ clang-tidy/modernize/CMakeLists.txt @@ -16,6 +16,7 @@ ReplaceRandomShuffleCheck.cpp ReturnBracedInitListCheck.cpp ShrinkToFitCheck.cpp + UnaryStaticAssertCheck.cpp UseAutoCheck.cpp UseBoolLiteralsCheck.cpp UseDefaultMemberInitCheck.cpp Index: clang-tidy/modernize/ModernizeTidyModule.cpp =================================================================== --- clang-tidy/modernize/ModernizeTidyModule.cpp +++ clang-tidy/modernize/ModernizeTidyModule.cpp @@ -22,6 +22,7 @@ #include "ReplaceRandomShuffleCheck.h" #include "ReturnBracedInitListCheck.h" #include "ShrinkToFitCheck.h" +#include "UnaryStaticAssertCheck.h" #include "UseAutoCheck.h" #include "UseBoolLiteralsCheck.h" #include "UseDefaultMemberInitCheck.h" @@ -61,6 +62,8 @@ CheckFactories.registerCheck( "modernize-return-braced-init-list"); CheckFactories.registerCheck("modernize-shrink-to-fit"); + CheckFactories.registerCheck( + "modernize-unary-static-assert"); CheckFactories.registerCheck("modernize-use-auto"); CheckFactories.registerCheck( "modernize-use-bool-literals"); Index: clang-tidy/modernize/UnaryStaticAssertCheck.h =================================================================== --- /dev/null +++ clang-tidy/modernize/UnaryStaticAssertCheck.h @@ -0,0 +1,36 @@ +//===--- UnaryStaticAssertCheck.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_MODERNIZE_UNARY_STATIC_ASSERT_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_UNARY_STATIC_ASSERT_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace modernize { + +/// Replaces a static_assert declaration with an empty message +/// with the unary version. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-unary-static-assert.html +class UnaryStaticAssertCheck : public ClangTidyCheck { +public: + UnaryStaticAssertCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace modernize +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_UNARY_STATIC_ASSERT_H Index: clang-tidy/modernize/UnaryStaticAssertCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/modernize/UnaryStaticAssertCheck.cpp @@ -0,0 +1,46 @@ +//===--- UnaryStaticAssertCheck.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 "UnaryStaticAssertCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace modernize { + +void UnaryStaticAssertCheck::registerMatchers(MatchFinder *Finder) { + if (!getLangOpts().CPlusPlus1z) + return; + + Finder->addMatcher(staticAssertDecl().bind("static_assert"), this); +} + +void UnaryStaticAssertCheck::check(const MatchFinder::MatchResult &Result) { + const auto *MatchedDecl = + Result.Nodes.getNodeAs("static_assert"); + const StringLiteral *AssertMessage = MatchedDecl->getMessage(); + + if (!AssertMessage || AssertMessage->getLength()) + return; + + SourceLocation Loc = MatchedDecl->getLocation(); + + auto Diag = diag(Loc, + "use unary 'static_assert' when the string literal is an empty string"); + + if (!Loc.isMacroID()) + Diag << FixItHint::CreateRemoval(AssertMessage->getSourceRange()); +} + +} // namespace modernize +} // namespace tidy +} // namespace clang Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -108,6 +108,12 @@ Finds and replaces explicit calls to the constructor in a return statement by a braced initializer list so that the return type is not needlessly repeated. +- New `modernize-unary-static-assert-check + `_ check + + The check diagnoses any ``static_assert`` declaration with an empty string literal + and provides a fix-it to replace the declaration with a single-argument ``static_assert`` declaration. + - Improved `modernize-use-emplace `_ check Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -132,6 +132,7 @@ modernize-replace-random-shuffle modernize-return-braced-init-list modernize-shrink-to-fit + modernize-unary-static-assert modernize-use-auto modernize-use-bool-literals modernize-use-default-member-init Index: docs/clang-tidy/checks/modernize-unary-static-assert.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/modernize-unary-static-assert.rst @@ -0,0 +1,25 @@ +.. title:: clang-tidy - modernize-unary-static-assert + +modernize-unary-static-assert +============================= + +The check diagnoses any ``static_assert`` declaration with an empty string literal +and provides a fix-it to replace the declaration with a single-argument ``static_assert`` declaration. + +The check is only applicable for C++17 and later code. + +The following code: + +.. code-block:: c++ + + void f_textless(int a) { + static_assert(sizeof(a) <= 10, ""); + } + +is replaced by: + +.. code-block:: c++ + + void f_textless(int a) { + static_assert(sizeof(a) <= 10); + } Index: test/clang-tidy/modernize-unary-static-assert.cpp =================================================================== --- /dev/null +++ test/clang-tidy/modernize-unary-static-assert.cpp @@ -0,0 +1,23 @@ +// RUN: %check_clang_tidy %s modernize-unary-static-assert %t -- -- -std=c++1z + +#define FOO static_assert(sizeof(a) <= 15, ""); + +void f_textless(int a) { + static_assert(sizeof(a) <= 10, ""); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use unary 'static_assert' when the string literal is an empty string [modernize-unary-static-assert] + // CHECK-FIXES: {{^}} static_assert(sizeof(a) <= 10 );{{$}} + static_assert(sizeof(a) <= 12, L""); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use unary 'static_assert' when + // CHECK-FIXES: {{^}} static_assert(sizeof(a) <= 12 );{{$}} + FOO + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use unary 'static_assert' when + // CHECK-FIXES: {{^}} FOO{{$}} +} + +void f_with_tex(int a) { + static_assert(sizeof(a) <= 10, "Sie of variable a is out of range!"); +} + +void f_unary(int a) { static_assert(sizeof(a) <= 10); } + +void f_incorrect_assert() { static_assert(""); }