[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)
PiotrZSL wrote: @nicovank Overall looks fine from functionality point of view. Problem A) Getting bunch of ``` task: wait_for= cb=[as_completed.._on_completion() at /usr/lib/python3.12/asyncio/tasks.py:618]> Task was destroyed but it is pending! ``` When CTR+C a script. More graceful shutdown would be welcome. Problem B) Previously script printed clang-tidy command line, now just progress + filename, for me it's fine but some users could find this as an degradation, as previously you could simply copy command line output and just run it manually. My advice: - By default print like in original script (command line), but add --progress switch that will change it to current behavior. - Add release notes entry about updates in script that impact end user. https://github.com/llvm/llvm-project/pull/89490 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Optimize realpath in readability-identifier-naming (PR #92659)
PiotrZSL wrote: No need for release notes as this realpath stuff were added in this release anyway. So this is just a fix for degradation. https://github.com/llvm/llvm-project/pull/92659 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Correcting issues in `readability-implicit-bool-conversion` on C23 (PR #92241)
=?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson Message-ID: In-Reply-To: https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/92241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Fix handling of members in readability-redundant-member-init (PR #93217)
https://github.com/PiotrZSL created https://github.com/llvm/llvm-project/pull/93217 Compare class type instead of just assuming that called constructor belong to same class. Fixes #91605 >From 6402bdd7555b8804ca4a2c392695fa81e8a87c4e Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Wed, 22 May 2024 20:56:00 + Subject: [PATCH] [clang-tidy] Fix handling of members in readability-redundant-member-init Compare class type instead of just assuming that called constructor belong to same class. Fixes #91605 --- .../readability/RedundantMemberInitCheck.cpp | 26 +-- clang-tools-extra/docs/ReleaseNotes.rst | 5 .../readability/redundant-member-init.cpp | 16 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp index 015347ee9294c..601ff44cdd10a 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantMemberInitCheck.cpp @@ -41,25 +41,35 @@ void RedundantMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap ) { void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) { auto ConstructorMatcher = - cxxConstructExpr(argumentCountIs(0), - hasDeclaration(cxxConstructorDecl(ofClass(cxxRecordDecl( - unless(isTriviallyDefaultConstructible())) + cxxConstructExpr( + argumentCountIs(0), + hasDeclaration(cxxConstructorDecl( + ofClass(cxxRecordDecl(unless(isTriviallyDefaultConstructible())) + .bind("class") .bind("construct"); + auto HasUnionAsParent = hasParent(recordDecl(isUnion())); + + auto HasTypeEqualToConstructorClass = hasType(qualType( + hasCanonicalType(qualType(hasDeclaration(equalsBoundNode("class")); + Finder->addMatcher( cxxConstructorDecl( unless(isDelegatingConstructor()), ofClass(unless(isUnion())), forEachConstructorInitializer( - cxxCtorInitializer(withInitializer(ConstructorMatcher), - unless(forField(fieldDecl( - anyOf(hasType(isConstQualified()), - hasParent(recordDecl(isUnion( + cxxCtorInitializer( + withInitializer(ConstructorMatcher), + anyOf(isBaseInitializer(), +forField(fieldDecl(unless(hasType(isConstQualified())), + unless(HasUnionAsParent), + HasTypeEqualToConstructorClass .bind("init"))) .bind("constructor"), this); Finder->addMatcher(fieldDecl(hasInClassInitializer(ConstructorMatcher), - unless(hasParent(recordDecl(isUnion() + HasTypeEqualToConstructorClass, + unless(HasUnionAsParent)) .bind("field"), this); } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 741abc0a199a7..8f3602ea5da39 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -387,6 +387,11 @@ Changes in existing checks ` check to properly emit warnings for static data member with an in-class initializer. +- Improved :doc:`readability-redundant-member-init + ` check to avoid + false-positives when type of the member does not match type of the + initializer. + - Improved :doc:`readability-static-accessed-through-instance ` check to support calls to overloaded operators as base expression and provide fixes to diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp index 17b2714abca07..6f18a6043be93 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-member-init.cpp @@ -302,3 +302,19 @@ struct D7 { D7 d7i; D7 d7s; + +struct SS { + SS() = default; + SS(S s) : s(s) {} + + S s; +}; + +struct D8 { + SS ss = S(); +}; + +struct D9 { + D9() : ss(S()) {} + SS ss; +}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][NFCI] Simplify bugprone-sizeof-expression (PR #93024)
=?utf-8?q?Don=C3=A1t?= Nagy , =?utf-8?q?Don=C3=A1t?= Nagy Message-ID: In-Reply-To: https://github.com/PiotrZSL approved this pull request. LGTM (if tests pass) https://github.com/llvm/llvm-project/pull/93024 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/86448 >From 8ed57a657d9b87bfaaa5c4394fc3fcaf670ba94c Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sun, 24 Mar 2024 18:39:54 + Subject: [PATCH 1/6] [clang-tidy] Added bugprone-exception-rethrow check Identifies problematic exception rethrowing, especially with caught exception variables or empty throw statements outside catch blocks. Closes #71292 --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../bugprone/ExceptionRethrowCheck.cpp| 50 ++ .../bugprone/ExceptionRethrowCheck.h | 37 ++ clang-tools-extra/docs/ReleaseNotes.rst | 6 ++ .../checks/bugprone/exception-rethrow.rst | 68 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/exception-rethrow.cpp | 60 8 files changed, 226 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 1b92d2e60cc17..7466d3f2e4fc2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -26,6 +26,7 @@ #include "EasilySwappableParametersCheck.h" #include "EmptyCatchCheck.h" #include "ExceptionEscapeCheck.h" +#include "ExceptionRethrowCheck.h" #include "FoldInitTypeCheck.h" #include "ForwardDeclarationNamespaceCheck.h" #include "ForwardingReferenceOverloadCheck.h" @@ -127,6 +128,8 @@ class BugproneModule : public ClangTidyModule { CheckFactories.registerCheck("bugprone-empty-catch"); CheckFactories.registerCheck( "bugprone-exception-escape"); +CheckFactories.registerCheck( +"bugprone-exception-rethrow"); CheckFactories.registerCheck("bugprone-fold-init-type"); CheckFactories.registerCheck( "bugprone-forward-declaration-namespace"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 2d303191f8865..345ae420398e6 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangTidyBugproneModule EasilySwappableParametersCheck.cpp EmptyCatchCheck.cpp ExceptionEscapeCheck.cpp + ExceptionRethrowCheck.cpp FoldInitTypeCheck.cpp ForwardDeclarationNamespaceCheck.cpp ForwardingReferenceOverloadCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp new file mode 100644 index 0..4855ccc2724a9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -0,0 +1,50 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } +} // namespace + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + anyOf(unless(has(expr())), + has(declRefExpr(to(varDecl(isExceptionVariable()), + optionally(hasAncestor(cxxCatchStmt().bind("catch" + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult ) { + const auto *MatchedThrow = Result.Nodes.getNodeAs("throw"); + + if (const Expr *ThrownObject = MatchedThrow->getSubExpr()) { +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); +return; + } + + const bool HasCatchAnsestor = + Result.Nodes.getNodeAs("catch") != nullptr; + if (!HasCatchAnsestor) { +diag(MatchedThrow->getThrowLoc(), + "empty 'throw' outside a catch block without an exception can trigger " + "'std::terminate'"); + } +} + +}
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
@@ -0,0 +1,103 @@ +// RUN: %check_clang_tidy %s bugprone-exception-rethrow %t -- -- -fexceptions + +struct exception {}; + +namespace std { PiotrZSL wrote: that's a job for separate change, as std::move is duplicated in multiple test files. https://github.com/llvm/llvm-project/pull/86448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/86448 >From c99ba980b0b242fced57fb323c5069d856c68810 Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sun, 31 Mar 2024 12:16:53 + Subject: [PATCH 1/6] fix --- clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h | 1 + clang-tools-extra/clang-tidy/abseil/CMakeLists.txt | 6 ++ .../clang-tidy/abseil/StringFindStrContainsCheck.cpp | 7 +-- .../abseil/UpgradeDurationConversionsCheck.cpp | 2 +- clang-tools-extra/clang-tidy/altera/CMakeLists.txt | 6 ++ clang-tools-extra/clang-tidy/android/CMakeLists.txt | 6 ++ clang-tools-extra/clang-tidy/boost/CMakeLists.txt| 6 ++ clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt | 6 ++ .../clang-tidy/bugprone/IncDecInConditionsCheck.cpp | 3 +++ .../clang-tidy/bugprone/InfiniteLoopCheck.cpp| 8 .../bugprone/MultipleNewInOneExpressionCheck.cpp | 2 +- .../clang-tidy/bugprone/StringConstructorCheck.cpp | 4 ++-- .../bugprone/UnhandledExceptionAtNewCheck.cpp| 3 +++ clang-tools-extra/clang-tidy/cert/CMakeLists.txt | 6 ++ .../clang-tidy/concurrency/CMakeLists.txt| 6 ++ .../clang-tidy/cppcoreguidelines/CMakeLists.txt | 6 ++ .../VirtualClassDestructorCheck.cpp | 2 ++ clang-tools-extra/clang-tidy/darwin/CMakeLists.txt | 6 ++ clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt | 6 ++ clang-tools-extra/clang-tidy/google/CMakeLists.txt | 6 ++ clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt| 6 ++ .../clang-tidy/linuxkernel/CMakeLists.txt| 5 + clang-tools-extra/clang-tidy/llvm/CMakeLists.txt | 6 ++ clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt | 6 ++ .../clang-tidy/llvmlibc/NamespaceConstants.h | 1 + clang-tools-extra/clang-tidy/misc/CMakeLists.txt | 5 + .../clang-tidy/modernize/AvoidCArraysCheck.cpp | 4 ++-- .../clang-tidy/modernize/CMakeLists.txt | 6 ++ .../clang-tidy/modernize/LoopConvertCheck.cpp| 4 ++-- .../clang-tidy/modernize/UseEqualsDefaultCheck.cpp | 2 +- .../clang-tidy/modernize/UseEqualsDeleteCheck.cpp| 10 +- .../modernize/UseTransparentFunctorsCheck.cpp| 6 +++--- clang-tools-extra/clang-tidy/mpi/CMakeLists.txt | 6 ++ clang-tools-extra/clang-tidy/objc/CMakeLists.txt | 6 ++ clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp | 6 +++--- clang-tools-extra/clang-tidy/openmp/CMakeLists.txt | 6 ++ .../clang-tidy/performance/CMakeLists.txt| 6 ++ .../performance/UnnecessaryCopyInitialization.cpp| 2 +- .../clang-tidy/portability/CMakeLists.txt| 6 ++ .../clang-tidy/readability/CMakeLists.txt| 7 +++ .../readability/ConvertMemberFunctionsToStatic.cpp | 3 +++ .../readability/FunctionCognitiveComplexityCheck.cpp | 12 ++-- .../readability/MakeMemberFunctionConstCheck.cpp | 6 +- .../readability/RedundantDeclarationCheck.cpp| 3 +++ .../readability/RedundantSmartptrGetCheck.cpp| 4 ++-- .../ReferenceToConstructedTemporaryCheck.cpp | 2 +- 46 files changed, 197 insertions(+), 37 deletions(-) diff --git a/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h b/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h index 1eef86ddc00b9..7a636ef8ebb95 100644 --- a/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h +++ b/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h @@ -6,6 +6,7 @@ // //===--===// +#pragma once #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include diff --git a/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt b/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt index 489d732abaa8d..8eca56ead7f8e 100644 --- a/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt @@ -44,3 +44,9 @@ clang_target_link_libraries(clangTidyAbseilModule clangTooling clangTransformer ) + + set_target_properties(obj.clangTidyAbseilModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp index 28b2f81fdc8c8..0c036e31426aa 100644 --- a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp @@ -30,9 +30,12 @@ using ::clang::transformer::makeRule; using ::clang::transformer::node; using ::clang::transformer::RewriteRuleWith; +namespace { + AST_MATCHER(Type, isCharType) { return Node.isCharType(); } +} -static const char DefaultStringLikeClasses[] =
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/86448 >From 1b5c351acca7375c577111a4c55506146ef108ef Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sun, 24 Mar 2024 18:39:54 + Subject: [PATCH 01/10] [clang-tidy] Added bugprone-exception-rethrow check Identifies problematic exception rethrowing, especially with caught exception variables or empty throw statements outside catch blocks. Closes #71292 --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../bugprone/ExceptionRethrowCheck.cpp| 50 ++ .../bugprone/ExceptionRethrowCheck.h | 37 ++ clang-tools-extra/docs/ReleaseNotes.rst | 6 ++ .../checks/bugprone/exception-rethrow.rst | 68 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/exception-rethrow.cpp | 60 8 files changed, 226 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 1b92d2e60cc17..7466d3f2e4fc2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -26,6 +26,7 @@ #include "EasilySwappableParametersCheck.h" #include "EmptyCatchCheck.h" #include "ExceptionEscapeCheck.h" +#include "ExceptionRethrowCheck.h" #include "FoldInitTypeCheck.h" #include "ForwardDeclarationNamespaceCheck.h" #include "ForwardingReferenceOverloadCheck.h" @@ -127,6 +128,8 @@ class BugproneModule : public ClangTidyModule { CheckFactories.registerCheck("bugprone-empty-catch"); CheckFactories.registerCheck( "bugprone-exception-escape"); +CheckFactories.registerCheck( +"bugprone-exception-rethrow"); CheckFactories.registerCheck("bugprone-fold-init-type"); CheckFactories.registerCheck( "bugprone-forward-declaration-namespace"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 2d303191f8865..345ae420398e6 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangTidyBugproneModule EasilySwappableParametersCheck.cpp EmptyCatchCheck.cpp ExceptionEscapeCheck.cpp + ExceptionRethrowCheck.cpp FoldInitTypeCheck.cpp ForwardDeclarationNamespaceCheck.cpp ForwardingReferenceOverloadCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp new file mode 100644 index 0..4855ccc2724a9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -0,0 +1,50 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } +} // namespace + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + anyOf(unless(has(expr())), + has(declRefExpr(to(varDecl(isExceptionVariable()), + optionally(hasAncestor(cxxCatchStmt().bind("catch" + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult ) { + const auto *MatchedThrow = Result.Nodes.getNodeAs("throw"); + + if (const Expr *ThrownObject = MatchedThrow->getSubExpr()) { +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); +return; + } + + const bool HasCatchAnsestor = + Result.Nodes.getNodeAs("catch") != nullptr; + if (!HasCatchAnsestor) { +diag(MatchedThrow->getThrowLoc(), + "empty 'throw' outside a catch block without an exception can trigger " + "'std::terminate'"); + } +} +
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/86448 >From 1b5c351acca7375c577111a4c55506146ef108ef Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sun, 24 Mar 2024 18:39:54 + Subject: [PATCH 1/9] [clang-tidy] Added bugprone-exception-rethrow check Identifies problematic exception rethrowing, especially with caught exception variables or empty throw statements outside catch blocks. Closes #71292 --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../bugprone/ExceptionRethrowCheck.cpp| 50 ++ .../bugprone/ExceptionRethrowCheck.h | 37 ++ clang-tools-extra/docs/ReleaseNotes.rst | 6 ++ .../checks/bugprone/exception-rethrow.rst | 68 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/exception-rethrow.cpp | 60 8 files changed, 226 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 1b92d2e60cc17..7466d3f2e4fc2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -26,6 +26,7 @@ #include "EasilySwappableParametersCheck.h" #include "EmptyCatchCheck.h" #include "ExceptionEscapeCheck.h" +#include "ExceptionRethrowCheck.h" #include "FoldInitTypeCheck.h" #include "ForwardDeclarationNamespaceCheck.h" #include "ForwardingReferenceOverloadCheck.h" @@ -127,6 +128,8 @@ class BugproneModule : public ClangTidyModule { CheckFactories.registerCheck("bugprone-empty-catch"); CheckFactories.registerCheck( "bugprone-exception-escape"); +CheckFactories.registerCheck( +"bugprone-exception-rethrow"); CheckFactories.registerCheck("bugprone-fold-init-type"); CheckFactories.registerCheck( "bugprone-forward-declaration-namespace"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 2d303191f8865..345ae420398e6 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangTidyBugproneModule EasilySwappableParametersCheck.cpp EmptyCatchCheck.cpp ExceptionEscapeCheck.cpp + ExceptionRethrowCheck.cpp FoldInitTypeCheck.cpp ForwardDeclarationNamespaceCheck.cpp ForwardingReferenceOverloadCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp new file mode 100644 index 0..4855ccc2724a9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -0,0 +1,50 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } +} // namespace + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + anyOf(unless(has(expr())), + has(declRefExpr(to(varDecl(isExceptionVariable()), + optionally(hasAncestor(cxxCatchStmt().bind("catch" + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult ) { + const auto *MatchedThrow = Result.Nodes.getNodeAs("throw"); + + if (const Expr *ThrownObject = MatchedThrow->getSubExpr()) { +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); +return; + } + + const bool HasCatchAnsestor = + Result.Nodes.getNodeAs("catch") != nullptr; + if (!HasCatchAnsestor) { +diag(MatchedThrow->getThrowLoc(), + "empty 'throw' outside a catch block without an exception can trigger " + "'std::terminate'"); + } +} + +}
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/86448 >From 1b5c351acca7375c577111a4c55506146ef108ef Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sun, 24 Mar 2024 18:39:54 + Subject: [PATCH 1/8] [clang-tidy] Added bugprone-exception-rethrow check Identifies problematic exception rethrowing, especially with caught exception variables or empty throw statements outside catch blocks. Closes #71292 --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../bugprone/ExceptionRethrowCheck.cpp| 50 ++ .../bugprone/ExceptionRethrowCheck.h | 37 ++ clang-tools-extra/docs/ReleaseNotes.rst | 6 ++ .../checks/bugprone/exception-rethrow.rst | 68 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/exception-rethrow.cpp | 60 8 files changed, 226 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 1b92d2e60cc17..7466d3f2e4fc2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -26,6 +26,7 @@ #include "EasilySwappableParametersCheck.h" #include "EmptyCatchCheck.h" #include "ExceptionEscapeCheck.h" +#include "ExceptionRethrowCheck.h" #include "FoldInitTypeCheck.h" #include "ForwardDeclarationNamespaceCheck.h" #include "ForwardingReferenceOverloadCheck.h" @@ -127,6 +128,8 @@ class BugproneModule : public ClangTidyModule { CheckFactories.registerCheck("bugprone-empty-catch"); CheckFactories.registerCheck( "bugprone-exception-escape"); +CheckFactories.registerCheck( +"bugprone-exception-rethrow"); CheckFactories.registerCheck("bugprone-fold-init-type"); CheckFactories.registerCheck( "bugprone-forward-declaration-namespace"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 2d303191f8865..345ae420398e6 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangTidyBugproneModule EasilySwappableParametersCheck.cpp EmptyCatchCheck.cpp ExceptionEscapeCheck.cpp + ExceptionRethrowCheck.cpp FoldInitTypeCheck.cpp ForwardDeclarationNamespaceCheck.cpp ForwardingReferenceOverloadCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp new file mode 100644 index 0..4855ccc2724a9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -0,0 +1,50 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } +} // namespace + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + anyOf(unless(has(expr())), + has(declRefExpr(to(varDecl(isExceptionVariable()), + optionally(hasAncestor(cxxCatchStmt().bind("catch" + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult ) { + const auto *MatchedThrow = Result.Nodes.getNodeAs("throw"); + + if (const Expr *ThrownObject = MatchedThrow->getSubExpr()) { +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); +return; + } + + const bool HasCatchAnsestor = + Result.Nodes.getNodeAs("catch") != nullptr; + if (!HasCatchAnsestor) { +diag(MatchedThrow->getThrowLoc(), + "empty 'throw' outside a catch block without an exception can trigger " + "'std::terminate'"); + } +} + +}
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/86448 >From 1b5c351acca7375c577111a4c55506146ef108ef Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sun, 24 Mar 2024 18:39:54 + Subject: [PATCH 1/7] [clang-tidy] Added bugprone-exception-rethrow check Identifies problematic exception rethrowing, especially with caught exception variables or empty throw statements outside catch blocks. Closes #71292 --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../bugprone/ExceptionRethrowCheck.cpp| 50 ++ .../bugprone/ExceptionRethrowCheck.h | 37 ++ clang-tools-extra/docs/ReleaseNotes.rst | 6 ++ .../checks/bugprone/exception-rethrow.rst | 68 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/exception-rethrow.cpp | 60 8 files changed, 226 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 1b92d2e60cc17..7466d3f2e4fc2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -26,6 +26,7 @@ #include "EasilySwappableParametersCheck.h" #include "EmptyCatchCheck.h" #include "ExceptionEscapeCheck.h" +#include "ExceptionRethrowCheck.h" #include "FoldInitTypeCheck.h" #include "ForwardDeclarationNamespaceCheck.h" #include "ForwardingReferenceOverloadCheck.h" @@ -127,6 +128,8 @@ class BugproneModule : public ClangTidyModule { CheckFactories.registerCheck("bugprone-empty-catch"); CheckFactories.registerCheck( "bugprone-exception-escape"); +CheckFactories.registerCheck( +"bugprone-exception-rethrow"); CheckFactories.registerCheck("bugprone-fold-init-type"); CheckFactories.registerCheck( "bugprone-forward-declaration-namespace"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 2d303191f8865..345ae420398e6 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangTidyBugproneModule EasilySwappableParametersCheck.cpp EmptyCatchCheck.cpp ExceptionEscapeCheck.cpp + ExceptionRethrowCheck.cpp FoldInitTypeCheck.cpp ForwardDeclarationNamespaceCheck.cpp ForwardingReferenceOverloadCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp new file mode 100644 index 0..4855ccc2724a9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -0,0 +1,50 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } +} // namespace + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + anyOf(unless(has(expr())), + has(declRefExpr(to(varDecl(isExceptionVariable()), + optionally(hasAncestor(cxxCatchStmt().bind("catch" + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult ) { + const auto *MatchedThrow = Result.Nodes.getNodeAs("throw"); + + if (const Expr *ThrownObject = MatchedThrow->getSubExpr()) { +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); +return; + } + + const bool HasCatchAnsestor = + Result.Nodes.getNodeAs("catch") != nullptr; + if (!HasCatchAnsestor) { +diag(MatchedThrow->getThrowLoc(), + "empty 'throw' outside a catch block without an exception can trigger " + "'std::terminate'"); + } +} + +}
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/86448 >From 1b5c351acca7375c577111a4c55506146ef108ef Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sun, 24 Mar 2024 18:39:54 + Subject: [PATCH 1/5] [clang-tidy] Added bugprone-exception-rethrow check Identifies problematic exception rethrowing, especially with caught exception variables or empty throw statements outside catch blocks. Closes #71292 --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../bugprone/ExceptionRethrowCheck.cpp| 50 ++ .../bugprone/ExceptionRethrowCheck.h | 37 ++ clang-tools-extra/docs/ReleaseNotes.rst | 6 ++ .../checks/bugprone/exception-rethrow.rst | 68 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/exception-rethrow.cpp | 60 8 files changed, 226 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 1b92d2e60cc17..7466d3f2e4fc2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -26,6 +26,7 @@ #include "EasilySwappableParametersCheck.h" #include "EmptyCatchCheck.h" #include "ExceptionEscapeCheck.h" +#include "ExceptionRethrowCheck.h" #include "FoldInitTypeCheck.h" #include "ForwardDeclarationNamespaceCheck.h" #include "ForwardingReferenceOverloadCheck.h" @@ -127,6 +128,8 @@ class BugproneModule : public ClangTidyModule { CheckFactories.registerCheck("bugprone-empty-catch"); CheckFactories.registerCheck( "bugprone-exception-escape"); +CheckFactories.registerCheck( +"bugprone-exception-rethrow"); CheckFactories.registerCheck("bugprone-fold-init-type"); CheckFactories.registerCheck( "bugprone-forward-declaration-namespace"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 2d303191f8865..345ae420398e6 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangTidyBugproneModule EasilySwappableParametersCheck.cpp EmptyCatchCheck.cpp ExceptionEscapeCheck.cpp + ExceptionRethrowCheck.cpp FoldInitTypeCheck.cpp ForwardDeclarationNamespaceCheck.cpp ForwardingReferenceOverloadCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp new file mode 100644 index 0..4855ccc2724a9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -0,0 +1,50 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } +} // namespace + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + anyOf(unless(has(expr())), + has(declRefExpr(to(varDecl(isExceptionVariable()), + optionally(hasAncestor(cxxCatchStmt().bind("catch" + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult ) { + const auto *MatchedThrow = Result.Nodes.getNodeAs("throw"); + + if (const Expr *ThrownObject = MatchedThrow->getSubExpr()) { +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); +return; + } + + const bool HasCatchAnsestor = + Result.Nodes.getNodeAs("catch") != nullptr; + if (!HasCatchAnsestor) { +diag(MatchedThrow->getThrowLoc(), + "empty 'throw' outside a catch block without an exception can trigger " + "'std::terminate'"); + } +} + +}
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/86448 >From 1b5c351acca7375c577111a4c55506146ef108ef Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sun, 24 Mar 2024 18:39:54 + Subject: [PATCH 1/6] [clang-tidy] Added bugprone-exception-rethrow check Identifies problematic exception rethrowing, especially with caught exception variables or empty throw statements outside catch blocks. Closes #71292 --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../bugprone/ExceptionRethrowCheck.cpp| 50 ++ .../bugprone/ExceptionRethrowCheck.h | 37 ++ clang-tools-extra/docs/ReleaseNotes.rst | 6 ++ .../checks/bugprone/exception-rethrow.rst | 68 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/exception-rethrow.cpp | 60 8 files changed, 226 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 1b92d2e60cc17..7466d3f2e4fc2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -26,6 +26,7 @@ #include "EasilySwappableParametersCheck.h" #include "EmptyCatchCheck.h" #include "ExceptionEscapeCheck.h" +#include "ExceptionRethrowCheck.h" #include "FoldInitTypeCheck.h" #include "ForwardDeclarationNamespaceCheck.h" #include "ForwardingReferenceOverloadCheck.h" @@ -127,6 +128,8 @@ class BugproneModule : public ClangTidyModule { CheckFactories.registerCheck("bugprone-empty-catch"); CheckFactories.registerCheck( "bugprone-exception-escape"); +CheckFactories.registerCheck( +"bugprone-exception-rethrow"); CheckFactories.registerCheck("bugprone-fold-init-type"); CheckFactories.registerCheck( "bugprone-forward-declaration-namespace"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 2d303191f8865..345ae420398e6 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangTidyBugproneModule EasilySwappableParametersCheck.cpp EmptyCatchCheck.cpp ExceptionEscapeCheck.cpp + ExceptionRethrowCheck.cpp FoldInitTypeCheck.cpp ForwardDeclarationNamespaceCheck.cpp ForwardingReferenceOverloadCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp new file mode 100644 index 0..4855ccc2724a9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -0,0 +1,50 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } +} // namespace + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + anyOf(unless(has(expr())), + has(declRefExpr(to(varDecl(isExceptionVariable()), + optionally(hasAncestor(cxxCatchStmt().bind("catch" + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult ) { + const auto *MatchedThrow = Result.Nodes.getNodeAs("throw"); + + if (const Expr *ThrownObject = MatchedThrow->getSubExpr()) { +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); +return; + } + + const bool HasCatchAnsestor = + Result.Nodes.getNodeAs("catch") != nullptr; + if (!HasCatchAnsestor) { +diag(MatchedThrow->getThrowLoc(), + "empty 'throw' outside a catch block without an exception can trigger " + "'std::terminate'"); + } +} + +}
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
@@ -0,0 +1,78 @@ +//===--- UseInternalLinkageCheck.cpp - clang-tidy--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseInternalLinkageCheck.h" +#include "../utils/FileExtensionsUtils.h" +#include "clang/AST/Decl.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/STLExtras.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::misc { + +namespace { + +AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); } + +AST_MATCHER_P(Decl, isInMainFile, FileExtensionsSet, HeaderFileExtensions) { + return llvm::all_of(Node.redecls(), [&](const Decl *D) { +SourceManager = Finder->getASTContext().getSourceManager(); +const SourceLocation L = D->getLocation(); +return SM.isInMainFile(L) && + !utils::isSpellingLocInHeaderFile(L, SM, HeaderFileExtensions); + }); PiotrZSL wrote: "because decl-1 is not in main file" but thats still source file and thats a point. Take into account 2 use cases: 1. user want to run check on a header files, in such case header file will be a main file, and check wont work. 2. user want to run check on unity cpp, where there is single .cpp file generated by cmake that include other cpp files and those files include header files. In both cases user should be able to do that. You already got "allOf(isFirstDecl(), isInMainFile(HeaderFileExtensions)," and thats fine. so check should work only if first declaration is in source file (no additional header) or when declaration and definition is in header file, in such case adding static/anonymous namespace is also expected (but only if user explicitly want to run check on headers - by messing up with compile commands json for example). https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Rename out-of-line function definitions (PR #91954)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/91954 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Correcting issues in `readability-implicit-bool-conversion` on C23 (PR #92241)
=?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson Message-ID: In-Reply-To: @@ -267,6 +275,10 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) { auto BoolXor = binaryOperator(hasOperatorName("^"), hasLHS(ImplicitCastFromBool), hasRHS(ImplicitCastFromBool)); + auto ComparisonInCall = + allOf(hasParent(callExpr()), +has(binaryOperator(hasAnyOperatorName("==", "!="; PiotrZSL wrote: has -> hasSourceExpression, and probably castExpr would be needed instead of allOf https://github.com/llvm/llvm-project/pull/92241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Correcting issues in `readability-implicit-bool-conversion` on C23 (PR #92241)
=?utf-8?q?Bj=C3=B6rn?= Svensson , =?utf-8?q?Bj=C3=B6rn?= Svensson , =?utf-8?q?Bj=C3=B6rn?= Svensson Message-ID: In-Reply-To: https://github.com/PiotrZSL approved this pull request. LGTM, just nits https://github.com/llvm/llvm-project/pull/92241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Correcting issues in `readability-implicit-bool-conversion` on C23 (PR #92241)
=?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson , =?utf-8?q?Björn?= Svensson Message-ID: In-Reply-To: https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/92241 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Optimize realpath in readability-identifier-naming (PR #92659)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/92659 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Optimize realpath in readability-identifier-naming (PR #92659)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/92659 >From a2ae273d083f451f44a41bd928c42a5bbdd946ae Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Tue, 21 May 2024 17:36:08 + Subject: [PATCH] [clang-tidy] Optimize readability-identifier-naming - Reduce disk IO usage by adding cache to an realpath introduced by #81985 --- .../clang-tidy/readability/IdentifierNamingCheck.cpp | 12 ++-- .../clang-tidy/readability/IdentifierNamingCheck.h | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index c3208392df156..828f13805a698 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -1414,13 +1414,21 @@ IdentifierNamingCheck::getDiagInfo(const NamingCheckId , }}; } +StringRef IdentifierNamingCheck::getRealFileName(StringRef FileName) const { + auto Iter = RealFileNameCache.try_emplace(FileName); + SmallString<256U> = Iter.first->getValue(); + if (!Iter.second) +return RealFileName; + llvm::sys::fs::real_path(FileName, RealFileName); + return RealFileName; +} + const IdentifierNamingCheck::FileStyle & IdentifierNamingCheck::getStyleForFile(StringRef FileName) const { if (!GetConfigPerFile) return *MainFileStyle; - SmallString<128> RealFileName; - llvm::sys::fs::real_path(FileName, RealFileName); + StringRef RealFileName = getRealFileName(FileName); StringRef Parent = llvm::sys::path::parent_path(RealFileName); auto Iter = NamingStylesCache.find(Parent); if (Iter != NamingStylesCache.end()) diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h index 27c8e4bc768c4..646ec0eac8dd1 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h @@ -205,6 +205,7 @@ class IdentifierNamingCheck final : public RenamerClangTidyCheck { const NamingCheckFailure ) const override; const FileStyle (StringRef FileName) const; + StringRef getRealFileName(StringRef FileName) const; /// Find the style kind of a field in an anonymous record. StyleKind findStyleKindForAnonField( @@ -222,6 +223,7 @@ class IdentifierNamingCheck final : public RenamerClangTidyCheck { /// Stores the style options as a vector, indexed by the specified \ref /// StyleKind, for a given directory. mutable llvm::StringMap NamingStylesCache; + mutable llvm::StringMap> RealFileNameCache; FileStyle *MainFileStyle; ClangTidyContext *Context; const bool GetConfigPerFile; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Optimize realpath in readability-identifier-naming (PR #92659)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/92659 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Optimize realpath in readability-identifier-naming (PR #92659)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/92659 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Optimize realpath in readability-identifier-naming (PR #92659)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/92659 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Optimize realpath in readability-identifier-naming (PR #92659)
https://github.com/PiotrZSL created https://github.com/llvm/llvm-project/pull/92659 - Reduce disk IO usage by adding cache to an realpath introduced by #81985 - Refactor HungarianNotation::getDeclTypeName to remove some string copies and use more safe string API. >From 45bce19a4852ab95c882948ea85ba8d87a4eeef2 Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Sat, 18 May 2024 16:56:31 + Subject: [PATCH] [clang-tidy] Optimize readability-identifier-naming - Reduce disk IO usage by adding cache to an realpath introduced by #81985 - Refactor HungarianNotation::getDeclTypeName to remove some string copies and use more safe string API. --- .../readability/IdentifierNamingCheck.cpp | 68 ++- .../readability/IdentifierNamingCheck.h | 2 + 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index c3208392df156..b2ab6e283c079 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -305,27 +305,20 @@ std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName( auto = VD->getASTContext().getSourceManager(); const char *Begin = SM.getCharacterData(VD->getBeginLoc()); const char *End = SM.getCharacterData(VD->getEndLoc()); - intptr_t StrLen = End - Begin; + if (End < Begin) +return {}; // FIXME: Sometimes the value that returns from ValDecl->getEndLoc() // is wrong(out of location of Decl). This causes `StrLen` will be assigned // an unexpected large value. Current workaround to find the terminated // character instead of the `getEndLoc()` function. - const char *EOL = strchr(Begin, '\n'); - if (!EOL) -EOL = Begin + strlen(Begin); - - const char *PosList[] = {strchr(Begin, '='), strchr(Begin, ';'), - strchr(Begin, ','), strchr(Begin, ')'), EOL}; - for (const auto : PosList) { -if (Pos > Begin) - EOL = std::min(EOL, Pos); - } + llvm::StringRef NameRef(Begin, End - Begin); + auto Pos = NameRef.find_first_of("\n\r=;,)"); + if (Pos != llvm::StringRef::npos) +NameRef = NameRef.substr(0, Pos); - StrLen = EOL - Begin; - std::string TypeName; - if (StrLen > 0) { -std::string Type(Begin, StrLen); + if (!NameRef.empty()) { +std::string Type(NameRef.begin(), NameRef.end()); static constexpr StringRef Keywords[] = { // Constexpr specifiers @@ -339,66 +332,67 @@ std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName( // Remove keywords for (StringRef Kw : Keywords) { - for (size_t Pos = 0; - (Pos = Type.find(Kw.data(), Pos)) != std::string::npos;) { + for (size_t Pos = 0; (Pos = Type.find(Kw, Pos)) != std::string::npos;) { Type.replace(Pos, Kw.size(), ""); } } -TypeName = Type.erase(0, Type.find_first_not_of(' ')); // Remove template parameters const size_t Pos = Type.find('<'); if (Pos != std::string::npos) { - TypeName = Type.erase(Pos, Type.size() - Pos); + Type.erase(Pos); } // Replace spaces with single space. for (size_t Pos = 0; (Pos = Type.find(" ", Pos)) != std::string::npos; - Pos += strlen(" ")) { - Type.replace(Pos, strlen(" "), " "); + Pos += 2U) { + Type.replace(Pos, 2U, " "); } // Replace " &" with "&". for (size_t Pos = 0; (Pos = Type.find(" &", Pos)) != std::string::npos; - Pos += strlen("&")) { - Type.replace(Pos, strlen(" &"), "&"); + Pos += 2U) { + Type.replace(Pos, 2U, "&"); } // Replace " *" with "* ". for (size_t Pos = 0; (Pos = Type.find(" *", Pos)) != std::string::npos; - Pos += strlen("*")) { - Type.replace(Pos, strlen(" *"), "* "); + Pos += 1U) { + Type.replace(Pos, 2U, "* "); } +Type.erase(0, Type.find_first_not_of(' ')); + // Remove redundant tailing. static constexpr StringRef TailsOfMultiWordType[] = { " int", " char", " double", " long", " short"}; bool RedundantRemoved = false; for (auto Kw : TailsOfMultiWordType) { - size_t Pos = Type.rfind(Kw.data()); + size_t Pos = Type.rfind(Kw); if (Pos != std::string::npos) { const size_t PtrCount = getAsteriskCount(Type, ND); -Type = Type.substr(0, Pos + Kw.size() + PtrCount); +Type.erase(Pos + Kw.size() + PtrCount); RedundantRemoved = true; break; } } -TypeName = Type.erase(0, Type.find_first_not_of(' ')); +Type.erase(0, Type.find_first_not_of(' ')); if (!RedundantRemoved) { std::size_t FoundSpace = Type.find(' '); if (FoundSpace != std::string::npos) Type = Type.substr(0, FoundSpace); } -TypeName = Type.erase(0, Type.find_first_not_of(' ')); +Type.erase(0,
[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)
PiotrZSL wrote: @nicovank I think that code is fine, will re-check it today. We could always think about something else later. https://github.com/llvm/llvm-project/pull/89490 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add AllowImplicitlyDeletedCopyOrMove option to cppcoreguidelines-special-member-functions (PR #71683)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/71683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Fix crash in modernize-use-constraints (PR #92019)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/92019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add AllowImplicitlyDeletedCopyOrMove option to cppcoreguidelines-special-member-functions (PR #71683)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/71683 >From 40d7a61e98fdd64d295aa720671f47b522c261a3 Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Wed, 8 Nov 2023 13:31:28 + Subject: [PATCH] [clang-tidy] Add AllowImplicitlyDeletedCopyOrMove option to cppcoreguidelines-special-member-functions Improved cppcoreguidelines-special-member-functions check with a new option AllowImplicitlyDeletedCopyOrMove, which removes the requirement for explicit copy or move special member functions when they are already implicitly deleted. --- .../SpecialMemberFunctionsCheck.cpp | 70 ++- .../SpecialMemberFunctionsCheck.h | 7 +- clang-tools-extra/docs/ReleaseNotes.rst | 6 ++ .../special-member-functions.rst | 28 ++-- .../special-member-functions-relaxed.cpp | 26 ++- 5 files changed, 107 insertions(+), 30 deletions(-) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp index d2117c67a76d0..ed76ac665049d 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp @@ -25,7 +25,9 @@ SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck( "AllowMissingMoveFunctions", false)), AllowSoleDefaultDtor(Options.get("AllowSoleDefaultDtor", false)), AllowMissingMoveFunctionsWhenCopyIsDeleted( - Options.get("AllowMissingMoveFunctionsWhenCopyIsDeleted", false)) {} + Options.get("AllowMissingMoveFunctionsWhenCopyIsDeleted", false)), + AllowImplicitlyDeletedCopyOrMove( + Options.get("AllowImplicitlyDeletedCopyOrMove", false)) {} void SpecialMemberFunctionsCheck::storeOptions( ClangTidyOptions::OptionMap ) { @@ -33,17 +35,34 @@ void SpecialMemberFunctionsCheck::storeOptions( Options.store(Opts, "AllowSoleDefaultDtor", AllowSoleDefaultDtor); Options.store(Opts, "AllowMissingMoveFunctionsWhenCopyIsDeleted", AllowMissingMoveFunctionsWhenCopyIsDeleted); + Options.store(Opts, "AllowImplicitlyDeletedCopyOrMove", +AllowImplicitlyDeletedCopyOrMove); +} + +std::optional +SpecialMemberFunctionsCheck::getCheckTraversalKind() const { + return AllowImplicitlyDeletedCopyOrMove ? TK_AsIs + : TK_IgnoreUnlessSpelledInSource; } void SpecialMemberFunctionsCheck::registerMatchers(MatchFinder *Finder) { + auto IsNotImplicitOrDeleted = anyOf(unless(isImplicit()), isDeleted()); + Finder->addMatcher( cxxRecordDecl( - eachOf(has(cxxDestructorDecl().bind("dtor")), - has(cxxConstructorDecl(isCopyConstructor()).bind("copy-ctor")), - has(cxxMethodDecl(isCopyAssignmentOperator()) + unless(isImplicit()), + eachOf(has(cxxDestructorDecl(unless(isImplicit())).bind("dtor")), + has(cxxConstructorDecl(isCopyConstructor(), +IsNotImplicitOrDeleted) + .bind("copy-ctor")), + has(cxxMethodDecl(isCopyAssignmentOperator(), + IsNotImplicitOrDeleted) .bind("copy-assign")), - has(cxxConstructorDecl(isMoveConstructor()).bind("move-ctor")), - has(cxxMethodDecl(isMoveAssignmentOperator()) + has(cxxConstructorDecl(isMoveConstructor(), +IsNotImplicitOrDeleted) + .bind("move-ctor")), + has(cxxMethodDecl(isMoveAssignmentOperator(), + IsNotImplicitOrDeleted) .bind("move-assign" .bind("class-def"), this); @@ -127,7 +146,8 @@ void SpecialMemberFunctionsCheck::check( for (const auto : Matchers) if (const auto *MethodDecl = Result.Nodes.getNodeAs(KV.first)) { - StoreMember({KV.second, MethodDecl->isDeleted()}); + StoreMember( + {KV.second, MethodDecl->isDeleted(), MethodDecl->isImplicit()}); } } @@ -144,7 +164,13 @@ void SpecialMemberFunctionsCheck::checkForMissingMembers( auto HasMember = [&](SpecialMemberFunctionKind Kind) { return llvm::any_of(DefinedMembers, [Kind](const auto ) { - return Data.FunctionKind == Kind; + return Data.FunctionKind == Kind && !Data.IsImplicit; +}); + }; + + auto HasImplicitDeletedMember = [&](SpecialMemberFunctionKind Kind) { +return llvm::any_of(DefinedMembers, [Kind](const auto ) { + return Data.FunctionKind == Kind && Data.IsImplicit && Data.IsDeleted; }); }; @@ -154,9 +180,17 @@ void SpecialMemberFunctionsCheck::checkForMissingMembers( }); }; - auto RequireMember = [&](SpecialMemberFunctionKind
[clang-tools-extra] [clang-tidy] Fix crash in modernize-use-constraints (PR #92019)
https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/92019 >From 5f0302b0d1c34d13b566aa6f992568005a47fac0 Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Mon, 13 May 2024 19:47:44 + Subject: [PATCH 1/2] [clang-tidy] Fix crash in modernize-use-constraints Improved modernize-use-constraints check by fixing a crash that occurred in some scenarios and excluded system headers from analysis. Problem were with DependentNameTypeLoc having null type location as getQualifierLoc().getTypeLoc(). Fixes #91872 --- .../modernize/UseConstraintsCheck.cpp | 4 +++ clang-tools-extra/docs/ReleaseNotes.rst | 4 +++ .../checks/modernize/use-constraints.rst | 4 +++ .../checkers/modernize/use-constraints.cpp| 32 +++ 4 files changed, 44 insertions(+) diff --git a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp index 6d7d1d6b87c60..d9fab64050adb 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp @@ -41,6 +41,8 @@ AST_MATCHER(FunctionDecl, hasOtherDeclarations) { void UseConstraintsCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( functionTemplateDecl( + // Skip external libraries included as system headers + unless(isExpansionInSystemHeader()), has(functionDecl(unless(hasOtherDeclarations()), isDefinition(), hasReturnTypeLoc(typeLoc().bind("return"))) .bind("function"))) @@ -57,6 +59,8 @@ matchEnableIfSpecializationImplTypename(TypeLoc TheType) { return std::nullopt; } TheType = Dep.getQualifierLoc().getTypeLoc(); +if (TheType.isNull()) + return std::nullopt; } if (const auto SpecializationLoc = diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index fc976ce3a33d5..91b24f654112f 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -306,6 +306,10 @@ Changes in existing checks don't remove parentheses used in ``sizeof`` calls when they have array index accesses as arguments. +- Improved :doc:`modernize-use-constraints + ` check by fixing a crash that + occurred in some scenarios and excluded system headers from analysis. + - Improved :doc:`modernize-use-nullptr ` check to include support for C23, which also has introduced the ``nullptr`` keyword. diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst index be62dd5823d55..a8b31b80e580b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst @@ -68,3 +68,7 @@ The tool will replace the above code with, // The tool will not emit a diagnostic or attempt to replace the code. template = 0> struct my_class {}; + +.. note:: + + System headers are not analyzed by this check. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp index 3ec44be8a1c8c..3bcd5cd74024e 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp @@ -724,3 +724,35 @@ void not_last_param() { } } // namespace enable_if_trailing_type_parameter + + +// Issue fixes: + +namespace PR91872 { + +enum expression_template_option { value1, value2 }; + +template struct number_category { + static const int value = 0; +}; + +constexpr int number_kind_complex = 1; + +template +struct number { + using type = T; +}; + +template struct component_type { + using type = T; +}; + +template +inline typename std::enable_if< +number_category::value == number_kind_complex, +component_type>>::type::type +abs(const number ) { + return {}; +} + +} >From fd5fa3e94ade53bfa78850879f3dfa287697277b Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Tue, 14 May 2024 19:18:06 +0200 Subject: [PATCH 2/2] Update clang-tools-extra/docs/ReleaseNotes.rst Co-authored-by: Congcong Cai --- clang-tools-extra/docs/ReleaseNotes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 91b24f654112f..e30b7bc3cd22d 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -308,7 +308,7 @@ Changes in existing checks - Improved :doc:`modernize-use-constraints ` check by fixing a crash that - occurred in some scenarios and excluded system headers from analysis. + occurred in some scenarios and excluding system headers from analysis. - Improved
[clang-tools-extra] [clang-tidy] Ignore implicit casts with errors in bugprone-implicit-widening-of-multiplication-result (PR #92025)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/92025 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Ignore implicit casts with errors in bugprone-implicit-widening-of-multiplication-result (PR #92025)
PiotrZSL wrote: Not adding release notes & tests, as this is issue happen only when asserts are enabled and input is invalid. Fix created only to improve diagnostic for end user (errors instead of crash) in this particular case. https://github.com/llvm/llvm-project/pull/92025 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Ignore implicit casts with errors in bugprone-implicit-widening-of-multiplication-result (PR #92025)
https://github.com/PiotrZSL created https://github.com/llvm/llvm-project/pull/92025 When expression got errors (missing typedef) and clang-tidy is compiled with asserts enabled, then we crash in this check on assert because type with errors is visible as an dependent one. This is issue caused by invalid input. But as there is not point to crash in such case and generate additional confusion, such expressions with errors will be now ignored. Fixes #89515, #55293 >From 59b71daa3a19d6fd7c8d5f7722afc10a20d9903c Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Mon, 13 May 2024 20:25:35 + Subject: [PATCH] [clang-tidy] Ignore implicit casts with errors in bugprone-implicit-widening-of-multiplication-result When expression got errors (missing typedef) and clang-tidy is compiled with asserts enabled, then we crash in this check on assert because type with errors is visible as an dependent one. This is issue caused by invalid input. But as there is not point to crash in such case and generate additional confusion, such expressions with errors will be now ignored. Fixes #89515, #55293 --- .../ImplicitWideningOfMultiplicationResultCheck.cpp | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/ImplicitWideningOfMultiplicationResultCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ImplicitWideningOfMultiplicationResultCheck.cpp index 6f22f02f30183..f99beac668ce7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ImplicitWideningOfMultiplicationResultCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ImplicitWideningOfMultiplicationResultCheck.cpp @@ -9,20 +9,20 @@ #include "ImplicitWideningOfMultiplicationResultCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" #include "clang/Lex/Lexer.h" #include using namespace clang::ast_matchers; -namespace clang { +namespace clang::tidy::bugprone { + namespace { AST_MATCHER(ImplicitCastExpr, isPartOfExplicitCast) { return Node.isPartOfExplicitCast(); } +AST_MATCHER(Expr, containsErrors) { return Node.containsErrors(); } } // namespace -} // namespace clang - -namespace clang::tidy::bugprone { static const Expr *getLHSOfMulBinOp(const Expr *E) { assert(E == E->IgnoreParens() && "Already skipped all parens!"); @@ -250,7 +250,8 @@ void ImplicitWideningOfMultiplicationResultCheck::handlePointerOffsetting( void ImplicitWideningOfMultiplicationResultCheck::registerMatchers( MatchFinder *Finder) { - Finder->addMatcher(implicitCastExpr(unless(anyOf(isInTemplateInstantiation(), + Finder->addMatcher(implicitCastExpr(unless(anyOf(containsErrors(), + isInTemplateInstantiation(), isPartOfExplicitCast())), hasCastKind(CK_IntegralCast)) .bind("x"), ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Fix crash in modernize-use-constraints (PR #92019)
PiotrZSL wrote: @ccotter Can you take a look, somehow I cannot select you as reviewer. https://github.com/llvm/llvm-project/pull/92019 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Fix crash in modernize-use-constraints (PR #92019)
https://github.com/PiotrZSL created https://github.com/llvm/llvm-project/pull/92019 Improved modernize-use-constraints check by fixing a crash that occurred in some scenarios and excluded system headers from analysis. Problem were with DependentNameTypeLoc having null type location as getQualifierLoc().getTypeLoc(). Fixes #91872 >From 5f0302b0d1c34d13b566aa6f992568005a47fac0 Mon Sep 17 00:00:00 2001 From: Piotr Zegar Date: Mon, 13 May 2024 19:47:44 + Subject: [PATCH] [clang-tidy] Fix crash in modernize-use-constraints Improved modernize-use-constraints check by fixing a crash that occurred in some scenarios and excluded system headers from analysis. Problem were with DependentNameTypeLoc having null type location as getQualifierLoc().getTypeLoc(). Fixes #91872 --- .../modernize/UseConstraintsCheck.cpp | 4 +++ clang-tools-extra/docs/ReleaseNotes.rst | 4 +++ .../checks/modernize/use-constraints.rst | 4 +++ .../checkers/modernize/use-constraints.cpp| 32 +++ 4 files changed, 44 insertions(+) diff --git a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp index 6d7d1d6b87c60..d9fab64050adb 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp @@ -41,6 +41,8 @@ AST_MATCHER(FunctionDecl, hasOtherDeclarations) { void UseConstraintsCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( functionTemplateDecl( + // Skip external libraries included as system headers + unless(isExpansionInSystemHeader()), has(functionDecl(unless(hasOtherDeclarations()), isDefinition(), hasReturnTypeLoc(typeLoc().bind("return"))) .bind("function"))) @@ -57,6 +59,8 @@ matchEnableIfSpecializationImplTypename(TypeLoc TheType) { return std::nullopt; } TheType = Dep.getQualifierLoc().getTypeLoc(); +if (TheType.isNull()) + return std::nullopt; } if (const auto SpecializationLoc = diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index fc976ce3a33d5..91b24f654112f 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -306,6 +306,10 @@ Changes in existing checks don't remove parentheses used in ``sizeof`` calls when they have array index accesses as arguments. +- Improved :doc:`modernize-use-constraints + ` check by fixing a crash that + occurred in some scenarios and excluded system headers from analysis. + - Improved :doc:`modernize-use-nullptr ` check to include support for C23, which also has introduced the ``nullptr`` keyword. diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst index be62dd5823d55..a8b31b80e580b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-constraints.rst @@ -68,3 +68,7 @@ The tool will replace the above code with, // The tool will not emit a diagnostic or attempt to replace the code. template = 0> struct my_class {}; + +.. note:: + + System headers are not analyzed by this check. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp index 3ec44be8a1c8c..3bcd5cd74024e 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-constraints.cpp @@ -724,3 +724,35 @@ void not_last_param() { } } // namespace enable_if_trailing_type_parameter + + +// Issue fixes: + +namespace PR91872 { + +enum expression_template_option { value1, value2 }; + +template struct number_category { + static const int value = 0; +}; + +constexpr int number_kind_complex = 1; + +template +struct number { + using type = T; +}; + +template struct component_type { + using type = T; +}; + +template +inline typename std::enable_if< +number_category::value == number_kind_complex, +component_type>>::type::type +abs(const number ) { + return {}; +} + +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add AllowImplicitlyDeletedCopyOrMove option to cppcoreguidelines-special-member-functions (PR #71683)
PiotrZSL wrote: Bump. https://github.com/llvm/llvm-project/pull/71683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add modernize-use-std-format check (PR #90397)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/90397 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Ignore unevaluated context in bugprone-optional-value-conversion (PR #90410)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/90410 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
@@ -0,0 +1,78 @@ +//===--- UseInternalLinkageCheck.cpp - clang-tidy--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseInternalLinkageCheck.h" +#include "../utils/FileExtensionsUtils.h" +#include "clang/AST/Decl.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/STLExtras.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::misc { + +namespace { + +AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); } + +AST_MATCHER_P(Decl, isInMainFile, FileExtensionsSet, HeaderFileExtensions) { + return llvm::all_of(Node.redecls(), [&](const Decl *D) { +SourceManager = Finder->getASTContext().getSourceManager(); +const SourceLocation L = D->getLocation(); +return SM.isInMainFile(L) && + !utils::isSpellingLocInHeaderFile(L, SM, HeaderFileExtensions); + }); PiotrZSL wrote: should be: ``` #source files or main file if its not a header. return utils::isSpellingLocInFile(L, SM, SourceFileExtensions) || (SM.isInMainFile(L) && !utils::isSpellingLocInFile(L, SM, HeaderFileExtensions)); ``` isSpellingLocInHeaderFile should be renamed into isSpellingLocInFile, that "Header" is not needed in those functions. https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
@@ -0,0 +1,78 @@ +//===--- UseInternalLinkageCheck.cpp - clang-tidy--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseInternalLinkageCheck.h" +#include "../utils/FileExtensionsUtils.h" +#include "clang/AST/Decl.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/STLExtras.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::misc { + +namespace { + +AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); } + +AST_MATCHER_P(Decl, isInMainFile, FileExtensionsSet, HeaderFileExtensions) { + return llvm::all_of(Node.redecls(), [&](const Decl *D) { +SourceManager = Finder->getASTContext().getSourceManager(); +const SourceLocation L = D->getLocation(); +return SM.isInMainFile(L) && + !utils::isSpellingLocInHeaderFile(L, SM, HeaderFileExtensions); + }); +} + +AST_POLYMORPHIC_MATCHER(isExternStorageClass, +AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, +VarDecl)) { + return Node.getStorageClass() == SC_Extern; +} + +} // namespace + +void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) { + auto Common = allOf(isFirstDecl(), isInMainFile(HeaderFileExtensions), PiotrZSL wrote: isFirstDecl wont work if someone do: ``` void foo() { } #include "foo.h" ``` but thats, fine, just would be good if documentation mention that it checks first declaration https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
https://github.com/PiotrZSL commented: Few nits. Missing: - more proper handling for unity files (.cpp included from .cpp) - nits - auto-fixes (any) - in worst case you can provide just fixes with static, but attaching them to notes. https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] new check misc-use-internal-linkage (PR #90830)
PiotrZSL wrote: > > * The auto-fix should be configurable to choose `static` or anonymous > > namespace. > > Should I implement auto-fix for this check? Maybe some functions / variables > will be marked incorrectly and cause link error because the coder just forget > to include the header file but this check mark it as internal linkage. WDYT? > @carlosgalvezp @PiotrZSL @EugeneZelenko @SimplyDanny YES. I used such check on a project that I work for. In short it found over an 1000 issues, manually fixing them was not an option. I had an quick fix with adding `static`, and that worked fine, in some places code didn't compile so had to fix those by my self, but that was fine. Add an option for "static / anonymous namespace", and generate fixes/hints accordingly. You can use optional values, or enums and by default suggest one or other, and in such state you may not need to provide fixes. In other config state just provide fixes, even if that would mean wrapping every function in separate anonymous namespace or adding static. There allways can be other check or some clang-format option to merge multiple namespaces. Do not reorder functions, and one can use other. Also static is safer as it's does not change scope, with namespace user may run into issues, but still fixes are needed. You can always mention in documentation that fixes are not perfect and manual intervention may be required. Even if check will do 80% of job, thats already huge help. https://github.com/llvm/llvm-project/pull/90830 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] support expect no diagnosis test (PR #91293)
https://github.com/PiotrZSL approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/91293 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
@@ -115,6 +115,8 @@ Improvements to clang-tidy - Fixed `--verify-config` option not properly parsing checks when using the literal operator in the `.clang-tidy` config. +- Added argument `--exclude-header-filter` to exclude headers from analysis via a RegEx. PiotrZSL wrote: Mention that config option ExcludeHeaderFilterRegex is also added. ```suggestion - Added argument `--exclude-header-filter` and config option `ExcludeHeaderFilterRegex` to exclude headers from analysis via a RegEx. ``` https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL approved this pull request. LGTM, just 2 nits. https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
@@ -292,6 +296,14 @@ def main(): "-config option after reading specified config file. " "Use either -config-file or -config, not both.", ) +parser.add_argument( +"-exclude-header-filter", +default=None, +help="regular expression matching the names of the " PiotrZSL wrote: regular -> Regular ```suggestion help="Regular expression matching the names of the " ``` https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Rename out-of-line function definitions (PR #91954)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91954 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Rename out-of-line function definitions (PR #91954)
https://github.com/PiotrZSL approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/91954 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Rename out-of-line function definitions (PR #91954)
@@ -123,6 +123,9 @@ static const NamedDecl *getFailureForNamedDecl(const NamedDecl *ND) { if (const auto *Method = dyn_cast(ND)) { if (const CXXMethodDecl *Overridden = getOverrideMethod(Method)) Canonical = cast(Overridden->getCanonicalDecl()); +else if (const FunctionTemplateDecl *Primary = Method->getPrimaryTemplate()) + Canonical = + cast(Primary->getTemplatedDecl()->getCanonicalDecl()); PiotrZSL wrote: It's fine, but would be really nice to check if result of getTemplatedDecl isn't nullptr (just in case). https://github.com/llvm/llvm-project/pull/91954 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] fix crash due to assumed callee in min-max-use-initializer-list (PR #91992)
https://github.com/PiotrZSL approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/91992 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy][NFC] replace comparison of begin and end iterators with range empty (PR #91994)
https://github.com/PiotrZSL approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/91994 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `bugprone-virtual-arithmetic` check (PR #91951)
PiotrZSL wrote: bugprone-pointer-arithmetic-polymorphic-object or bugprone-pointer-arithmetic-on-polymorphic-object could be fine. limiting check to polymorphic objects it's fine, someone can always enable an cppguidelines check to cover all cases. Also check-alias should be added to cert. https://github.com/llvm/llvm-project/pull/91951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `bugprone-virtual-arithmetic` check (PR #91951)
@@ -0,0 +1,49 @@ +//===--- VirtualArithmeticCheck.cpp - clang-tidy---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "VirtualArithmeticCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +void VirtualArithmeticCheck::registerMatchers(MatchFinder *Finder) { + const auto PointerExprWithVirtualMethod = + expr(hasType(pointerType(pointee(hasDeclaration( + cxxRecordDecl(hasMethod(isVirtualAsWritten( + .bind("pointer"); + + const auto ArraySubscript = + arraySubscriptExpr(hasBase(PointerExprWithVirtualMethod)); + + const auto BinaryOperators = + binaryOperator(hasAnyOperatorName("+", "-", "+=", "-="), + hasEitherOperand(PointerExprWithVirtualMethod)); + + const auto UnaryOperators = + unaryOperator(hasAnyOperatorName("++", "--"), +hasUnaryOperand(PointerExprWithVirtualMethod)); + + Finder->addMatcher( + expr(anyOf(ArraySubscript, BinaryOperators, UnaryOperators)), this); +} + +void VirtualArithmeticCheck::check(const MatchFinder::MatchResult ) { + const auto *PointerExpr = Result.Nodes.getNodeAs("pointer"); + const CXXRecordDecl *PointeeType = + PointerExpr->getType()->getPointeeType()->getAsCXXRecordDecl(); + + diag(PointerExpr->getBeginLoc(), + "pointer arithmetic on class '%0' that declares a virtual function, " PiotrZSL wrote: `on polymorphic class` ... also "if the pointee is a different class" is not so clear. Problem is that this issue may happen regardless if this is an polymorphic object or not... https://github.com/llvm/llvm-project/pull/91951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `bugprone-virtual-arithmetic` check (PR #91951)
@@ -0,0 +1,59 @@ +// RUN: %check_clang_tidy %s bugprone-virtual-arithmetic %t + +class Base { +public: + virtual ~Base() {} +}; + +class Derived : public Base {}; + +void operators() { + Base *b = new Derived[10]; + + b += 1; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on class 'Base' that declares a virtual function, undefined behavior if the pointee is a different class [bugprone-virtual-arithmetic] + + b = b + 1; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer arithmetic on class 'Base' that declares a virtual function, undefined behavior if the pointee is a different class [bugprone-virtual-arithmetic] + + b++; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on class 'Base' that declares a virtual function, undefined behavior if the pointee is a different class [bugprone-virtual-arithmetic] + + b[1]; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on class 'Base' that declares a virtual function, undefined behavior if the pointee is a different class [bugprone-virtual-arithmetic] + + delete[] static_cast(b); +} + +void subclassWarnings() { + Base *b = new Base[10]; + + // False positive that's impossible to distinguish without + // path-sensitive analysis, but the code is bug-prone regardless. + b += 1; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on class 'Base' that declares a virtual function + + delete[] b; + + // Common false positive is a class that overrides all parent functions. + Derived *d = new Derived[10]; + + d += 1; + // no-warning + + delete[] d; +} + +template +void templateWarning(T *t) { + // FIXME: Show the location of the template instantiation in diagnostic. + t += 1; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on class 'Base' that declares a virtual function +} + +void functionArgument(Base *b) { + b += 1; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on class 'Base' that declares a virtual function + + templateWarning(b); +} PiotrZSL wrote: Add test for bugfree scenario: ``` void test() { Object table[10]; Object* ptr = table[5]; } ``` https://github.com/llvm/llvm-project/pull/91951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `bugprone-virtual-arithmetic` check (PR #91951)
@@ -0,0 +1,49 @@ +//===--- VirtualArithmeticCheck.cpp - clang-tidy---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "VirtualArithmeticCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +void VirtualArithmeticCheck::registerMatchers(MatchFinder *Finder) { + const auto PointerExprWithVirtualMethod = + expr(hasType(pointerType(pointee(hasDeclaration( + cxxRecordDecl(hasMethod(isVirtualAsWritten( + .bind("pointer"); PiotrZSL wrote: may not work for classes that derive from virtual one. You should create new AST matcher an use here: "[isPolymorphic](https://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html#a6989371936079ccd01556c99637e9de0) ()" https://github.com/llvm/llvm-project/pull/91951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `bugprone-virtual-arithmetic` check (PR #91951)
@@ -0,0 +1,50 @@ +.. title:: clang-tidy - bugprone-virtual-arithmetic + +bugprone-virtual-arithmetic +=== + +Warn if pointer arithmetic is performed on a class that declares a +virtual function. + +Pointer arithmetic on polymorphic objects where the pointer's static type is +different from its dynamic type is undefined behavior. PiotrZSL wrote: this apply not only to polymorphic objects. Would be good to write why (maybe something about pointer to virtual table). https://github.com/llvm/llvm-project/pull/91951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `bugprone-virtual-arithmetic` check (PR #91951)
@@ -0,0 +1,59 @@ +// RUN: %check_clang_tidy %s bugprone-virtual-arithmetic %t + +class Base { +public: + virtual ~Base() {} +}; + +class Derived : public Base {}; + +void operators() { + Base *b = new Derived[10]; + + b += 1; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on class 'Base' that declares a virtual function, undefined behavior if the pointee is a different class [bugprone-virtual-arithmetic] + + b = b + 1; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer arithmetic on class 'Base' that declares a virtual function, undefined behavior if the pointee is a different class [bugprone-virtual-arithmetic] + + b++; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pointer arithmetic on class 'Base' that declares a virtual function, undefined behavior if the pointee is a different class [bugprone-virtual-arithmetic] PiotrZSL wrote: add tests for ++b; https://github.com/llvm/llvm-project/pull/91951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `bugprone-virtual-arithmetic` check (PR #91951)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `bugprone-virtual-arithmetic` check (PR #91951)
https://github.com/PiotrZSL commented: Few nits. My main concern is an check name, had to open PR to find out what it does. maybe should be more a "bugprone-arithmetic-on-polymorphic-pointer" or something like that. https://github.com/llvm/llvm-project/pull/91951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] `readability-simplify-boolean-expr` avoid to warn expression expand from macro when ``IgnoreMacro`` option is enabled. (PR #91757)
@@ -513,17 +513,25 @@ class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor { return true; } - static bool isUnaryLNot(const Expr *E) { -return isa(E) && + static bool isExpectedUnaryLNot(SimplifyBooleanExprCheck *Check, + const Expr *E) { +return !Check->canBeBypassed(E) && isa(E) && cast(E)->getOpcode() == UO_LNot; } + static bool isExpectedBinaryOp(SimplifyBooleanExprCheck *Check, + const Expr *E) { +const auto *BinaryOp = dyn_cast(E); +return !Check->canBeBypassed(E) && BinaryOp && BinaryOp->isLogicalOp() && + BinaryOp->getType()->isBooleanType(); + } PiotrZSL wrote: just remove static, and then you will have access to Check class member. https://github.com/llvm/llvm-project/pull/91757 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] `readability-simplify-boolean-expr` avoid to warn expression expand from macro when ``IgnoreMacro`` option is enabled. (PR #91757)
https://github.com/PiotrZSL approved this pull request. Just nits. https://github.com/llvm/llvm-project/pull/91757 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] `readability-simplify-boolean-expr` avoid to warn expression expand from macro when ``IgnoreMacro`` option is enabled. (PR #91757)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91757 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] `readability-simplify-boolean-expr` avoid to warn expression expand from macro when ``IgnoreMacro`` option is enabled. (PR #91757)
@@ -357,6 +357,9 @@ Changes in existing checks support calls to overloaded operators as base expression and provide fixes to expressions with side-effects. +- Improved :doc:`readability-simplify-boolean-expr` PiotrZSL wrote: split into 2 lines https://github.com/llvm/llvm-project/pull/91757 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
@@ -311,7 +311,12 @@ ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer( : Context(Ctx), ExternalDiagEngine(ExternalDiagEngine), RemoveIncompatibleErrors(RemoveIncompatibleErrors), GetFixesFromNotes(GetFixesFromNotes), - EnableNolintBlocks(EnableNolintBlocks) {} + EnableNolintBlocks(EnableNolintBlocks) { + + if (Context.getOptions().ExcludeHeaderFilterRegex) +ExcludeHeaderFilter = std::make_unique( +*Context.getOptions().ExcludeHeaderFilterRegex); PiotrZSL wrote: i thing this doesn't work, i mean that ExcludeHeaderFilterRegex is always set because init value is set to '' and is used as default value for option, therfor ExcludeHeaderFilterRegex will never be nullptr. try adding check here to verify also that string is not empty. https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL approved this pull request. Overall from functional point of view looks fine. https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
@@ -562,9 +567,10 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location, } StringRef FileName(File->getName()); - LastErrorRelatesToUserCode = LastErrorRelatesToUserCode || - Sources.isInMainFile(Location) || - getHeaderFilter()->match(FileName); + LastErrorRelatesToUserCode = + LastErrorRelatesToUserCode || Sources.isInMainFile(Location) || + (getHeaderFilter()->match(FileName) && + (ExcludeHeaderFilter ? !ExcludeHeaderFilter->match(FileName) : true)); PiotrZSL wrote: `ExcludeHeaderFilter ? !ExcludeHeaderFilter->match(FileName) : true` -> `!(ExcludeHeaderFilter && ExcludeHeaderFilter->match(FileName))` https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL commented: Missing test for ExcludeHeaderFilterRegex in .clang-tidy config file. Would be nice to check if --dump-config work correctly with empty/not empty ExcludeHeaderFilterRegex Except those 2 looks fine. https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [NFC][clang-tidy] remove magic-numbers-todo.cpp (PR #91577)
https://github.com/PiotrZSL approved this pull request. https://github.com/llvm/llvm-project/pull/91577 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] check `std::string_view` and custom string-like classes in `readability-string-compare` (PR #88636)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/88636 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Ignore unevaluated context in bugprone-optional-value-conversion (PR #90410)
PiotrZSL wrote: @5chmidti I did some testing with this. And in example that you provided there is no issue. This is because if optional will be uninitialized, then this code won't compile regardless if .value() or operator * is used. Compiler will simply complain that expression is not constexpr. When used normally, you will get undefined behavior or exception. https://github.com/llvm/llvm-project/pull/90410 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Handle expr with side-effects in readability-static-accessed-through-instance (PR #90736)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/90736 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Handle implicit casts in hicpp-signed-bitwise for IgnorePositiveIntegerLiterals (PR #90621)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/90621 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
@@ -578,6 +579,13 @@ llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() { return HeaderFilter.get(); } +llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() { + if (!ExcludeHeaderFilter) +ExcludeHeaderFilter = std::make_unique( +*Context.getOptions().ExcludeHeaderFilterRegex); PiotrZSL wrote: My idea were simply to keep this optional uninitialized in such case, instead of initializing it with empty string, and then simply do not call match for such regexp https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
PiotrZSL wrote: Also python wrappers may require updating to pass those settings to clang-tidy https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
@@ -564,7 +564,8 @@ void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location, StringRef FileName(File->getName()); LastErrorRelatesToUserCode = LastErrorRelatesToUserCode || Sources.isInMainFile(Location) || - getHeaderFilter()->match(FileName); + (getHeaderFilter()->match(FileName) && +!getExcludeHeaderFilter()->match(FileName)); PiotrZSL wrote: would be nice to omit checking ExcludeHeaderFilter if it's not set. https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
@@ -578,6 +579,13 @@ llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() { return HeaderFilter.get(); } +llvm::Regex *ClangTidyDiagnosticConsumer::getExcludeHeaderFilter() { + if (!ExcludeHeaderFilter) +ExcludeHeaderFilter = std::make_unique( +*Context.getOptions().ExcludeHeaderFilterRegex); PiotrZSL wrote: what if ExcludeHeaderFilterRegex is not set ? This look like legacy bug, same as in getHeaderFilter https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL requested changes to this pull request. Release notes & clang-tidy documentation need to be updated. https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Add option to exclude headers from clang-tidy analysis (PR #91400)
https://github.com/PiotrZSL edited https://github.com/llvm/llvm-project/pull/91400 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)
https://github.com/PiotrZSL closed https://github.com/llvm/llvm-project/pull/88735 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
https://github.com/PiotrZSL requested changes to this pull request. Fix pointed out nits https://github.com/llvm/llvm-project/pull/91124 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,174 @@ +// RUN: %check_clang_tidy -std=c++11 %s modernize-use-uniform-initializer %t + +int cinit_0 = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_0 {0}; + +int cinit_1=0; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_1{0}; + +int callinit_0(0); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_0{0}; + +int callinit_1 ( 0 ); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_1 {0}; + +int callinit_2 ( ((3 + 1 + 4) + 1 + 5) ); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_2 {((3 + 1 + 4) + 1 + 5)}; + +int callinit_3((9-2)+(6+5)); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_3{(9-2)+(6+5)}; + +int callinit_4 ((3 * 5 + (8 - 9) )); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_4 {(3 * 5 + (8 - 9) )}; + +int callinit_5((7 + (-9))); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_5{(7 + (-9))}; + +int mixed_0 = {0}; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_0 {0}; + +int mixed_1={0}; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_1{0}; + +int noinit; + +int correct_0{0}; + +int correct_1 {0}; + +struct CInitList_0 { +CInitList_0() : x(0) {} +// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_0() : x{0} {} + +int x; +}; + +struct CInitList_1 { +CInitList_1():x(0) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_1():x{0} {} + +int x; +}; + +struct CInitList_2 { +CInitList_2() : x ( 0 ) {} +// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_2() : x {0} {} + +int x; +}; + +struct Correct_0 { +Correct_0() : x{0} {} + +int x; +}; + +struct Correct_1 { +Correct_1():x{0} {} + +int x; +}; + +struct InClassInitializers { +int cinit_0 = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_0 {0}; + +int cinit_1=0; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_1{0}; + +int mixed_0 = {0}; +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_0 {0}; + +int mixed_1={0}; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_1{0}; + +int noinit; + +int correct_0 {0}; + +int correct_1{0}; +}; + +// Defaulted function arguments cannot use the uniform initializer +void f(int x = 0) {} + +struct A { +A() = default; +A(int) {} +A(int, int) {} +}; + +A a_0; +A a_1{}; +A a_2(); // This is not a variable declaration it is actually a function definition (most vexing parse) +A a_3{21}; +A a_4{ 21 }; +A a_5(42); +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_5{42}; +A a_6 ( 42 ); +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_6 {42}; +A a_7{0, 1}; +A a_8{ 0, 1 }; +A a_9(0, 1); +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_9{0, 1}; +A a_10( 1, 0 ); +//
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -84,6 +84,29 @@ SourceLocation findNextTerminator(SourceLocation Start, const SourceManager , return findNextAnyTokenKind(Start, SM, LangOpts, tok::comma, tok::semi); } +SourceLocation findNextTokenKind(SourceLocation Start, const SourceManager , + const LangOptions , + tok::TokenKind TK) { + while (true) { +std::optional CurrentToken = +Lexer::findNextToken(Start, SM, LangOpts); + +if (!CurrentToken) + return {}; + +Token PotentialMatch = *CurrentToken; +if (PotentialMatch.is(TK)) + return PotentialMatch.getLocation(); + +// If we reach the end of the file, and eof is not the target token, we stop +// the loop, otherwise we will get infinite loop (findNextToken will return +// eof on eof). +if (PotentialMatch.is(tok::eof)) + return {}; +Start = PotentialMatch.getLastLoc(); + } PiotrZSL wrote: instead of re-implementing this you could just call findNextTokenSkippingComments in loop https://github.com/llvm/llvm-project/pull/91124 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,34 @@ +.. title:: clang-tidy - modernize-use-uniform-initializer + +modernize-use-uniform-initializer += + +Finds usage of C-Style initialization that can be rewritten with +C++-11 uniform initializers. + +Example +--- + +.. code-block:: c++ + + int foo = 21; + int bar(42); + + struct Baz { +Baz() : x(3) {} + +int x; + }; PiotrZSL wrote: add example with in-class initialization https://github.com/llvm/llvm-project/pull/91124 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager , + const LangOptions ) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); PiotrZSL wrote: you could try to check where previous token ends. https://github.com/llvm/llvm-project/pull/91124 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager , + const LangOptions ) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); + +return llvm::isSpace(CharBeforeParenExpr[0]); + }(); + + const SourceLocation OpenParenLoc = utils::lexer::findPreviousTokenKind( + NeedOffsetForOpenParen ? InitExpr->getBeginLoc().getLocWithOffset(-1) + : InitExpr->getBeginLoc(), + SM, LangOpts, tok::l_paren); + const SourceLocation CloseParenLoc = utils::lexer::findNextTokenKind( + InitExpr->getEndLoc(), SM, LangOpts, tok::r_paren); + + return {OpenParenLoc, CloseParenLoc}; +} + +const BuiltinType *getBuiltinType(const Expr *Expr) { + assert(Expr); + return Expr->getType().getCanonicalType().getTypePtr()->getAs(); +} + +bool castRequiresStaticCast(const ImplicitCastExpr *CastExpr) { + const auto *FromExpr = CastExpr->getSubExpr(); + + if (CastExpr->isInstantiationDependent() || + FromExpr->isInstantiationDependent()) +return false; + if (getBuiltinType(CastExpr) == getBuiltinType(FromExpr)) +return false; + + switch (CastExpr->getCastKind()) { + case CastKind::CK_BaseToDerived: + case CastKind::CK_DerivedToBaseMemberPointer: + case CastKind::CK_IntegralCast: + case CastKind::CK_FloatingToIntegral: +return true; + + default: +return false; + } +} + +std::string buildReplacementString(const Expr *InitExpr, + const ASTContext ) { + // TODO: This function does not correctly handle the case where you have in + // 'ImplicitCastExpr' as an argument for a 'CXXConstructExpr'. + // In that case the generated code will not compile due to missing explicit + // cast of the sub expression. + + const SourceManager = Context.getSourceManager(); + const LangOptions = Context.getLangOpts(); + + const StringRef InitExprStr = [&]() { +if (isa(InitExpr)) { + const auto *ConstructExpr = llvm::cast(InitExpr); + + const SourceRange ParenRange
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager , + const LangOptions ) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); + +return llvm::isSpace(CharBeforeParenExpr[0]); + }(); + + const SourceLocation OpenParenLoc = utils::lexer::findPreviousTokenKind( + NeedOffsetForOpenParen ? InitExpr->getBeginLoc().getLocWithOffset(-1) + : InitExpr->getBeginLoc(), + SM, LangOpts, tok::l_paren); + const SourceLocation CloseParenLoc = utils::lexer::findNextTokenKind( + InitExpr->getEndLoc(), SM, LangOpts, tok::r_paren); + + return {OpenParenLoc, CloseParenLoc}; +} + +const BuiltinType *getBuiltinType(const Expr *Expr) { + assert(Expr); + return Expr->getType().getCanonicalType().getTypePtr()->getAs(); PiotrZSL wrote: would be nice to check if type isn't null & expr in same time https://github.com/llvm/llvm-project/pull/91124 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { PiotrZSL wrote: static https://github.com/llvm/llvm-project/pull/91124 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager , + const LangOptions ) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); + +return llvm::isSpace(CharBeforeParenExpr[0]); + }(); + + const SourceLocation OpenParenLoc = utils::lexer::findPreviousTokenKind( + NeedOffsetForOpenParen ? InitExpr->getBeginLoc().getLocWithOffset(-1) + : InitExpr->getBeginLoc(), + SM, LangOpts, tok::l_paren); + const SourceLocation CloseParenLoc = utils::lexer::findNextTokenKind( + InitExpr->getEndLoc(), SM, LangOpts, tok::r_paren); + + return {OpenParenLoc, CloseParenLoc}; +} + +const BuiltinType *getBuiltinType(const Expr *Expr) { + assert(Expr); + return Expr->getType().getCanonicalType().getTypePtr()->getAs(); +} + +bool castRequiresStaticCast(const ImplicitCastExpr *CastExpr) { + const auto *FromExpr = CastExpr->getSubExpr(); + + if (CastExpr->isInstantiationDependent() || + FromExpr->isInstantiationDependent()) +return false; + if (getBuiltinType(CastExpr) == getBuiltinType(FromExpr)) +return false; + + switch (CastExpr->getCastKind()) { + case CastKind::CK_BaseToDerived: + case CastKind::CK_DerivedToBaseMemberPointer: + case CastKind::CK_IntegralCast: + case CastKind::CK_FloatingToIntegral: +return true; + + default: +return false; + } +} + +std::string buildReplacementString(const Expr *InitExpr, + const ASTContext ) { + // TODO: This function does not correctly handle the case where you have in + // 'ImplicitCastExpr' as an argument for a 'CXXConstructExpr'. + // In that case the generated code will not compile due to missing explicit + // cast of the sub expression. + + const SourceManager = Context.getSourceManager(); + const LangOptions = Context.getLangOpts(); + + const StringRef InitExprStr = [&]() { +if (isa(InitExpr)) { + const auto *ConstructExpr = llvm::cast(InitExpr); + + const SourceRange ParenRange
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,174 @@ +// RUN: %check_clang_tidy -std=c++11 %s modernize-use-uniform-initializer %t + +int cinit_0 = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_0 {0}; + +int cinit_1=0; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_1{0}; + +int callinit_0(0); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_0{0}; + +int callinit_1 ( 0 ); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_1 {0}; + +int callinit_2 ( ((3 + 1 + 4) + 1 + 5) ); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_2 {((3 + 1 + 4) + 1 + 5)}; + +int callinit_3((9-2)+(6+5)); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_3{(9-2)+(6+5)}; + +int callinit_4 ((3 * 5 + (8 - 9) )); +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_4 {(3 * 5 + (8 - 9) )}; + +int callinit_5((7 + (-9))); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int callinit_5{(7 + (-9))}; + +int mixed_0 = {0}; +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_0 {0}; + +int mixed_1={0}; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_1{0}; + +int noinit; + +int correct_0{0}; + +int correct_1 {0}; + +struct CInitList_0 { +CInitList_0() : x(0) {} +// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_0() : x{0} {} + +int x; +}; + +struct CInitList_1 { +CInitList_1():x(0) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_1():x{0} {} + +int x; +}; + +struct CInitList_2 { +CInitList_2() : x ( 0 ) {} +// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: CInitList_2() : x {0} {} + +int x; +}; + +struct Correct_0 { +Correct_0() : x{0} {} + +int x; +}; + +struct Correct_1 { +Correct_1():x{0} {} + +int x; +}; + +struct InClassInitializers { +int cinit_0 = 0; +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_0 {0}; + +int cinit_1=0; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int cinit_1{0}; + +int mixed_0 = {0}; +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_0 {0}; + +int mixed_1={0}; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Use uniform initializer instead of C-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: int mixed_1{0}; + +int noinit; + +int correct_0 {0}; + +int correct_1{0}; +}; + +// Defaulted function arguments cannot use the uniform initializer +void f(int x = 0) {} + +struct A { +A() = default; +A(int) {} +A(int, int) {} +}; + +A a_0; +A a_1{}; +A a_2(); // This is not a variable declaration it is actually a function definition (most vexing parse) +A a_3{21}; +A a_4{ 21 }; +A a_5(42); +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_5{42}; +A a_6 ( 42 ); +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_6 {42}; +A a_7{0, 1}; +A a_8{ 0, 1 }; +A a_9(0, 1); +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Use uniform initializer instead of call-style initializer [modernize-use-uniform-initializer] +// CHECK-FIXES: A a_9{0, 1}; +A a_10( 1, 0 ); +//
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} PiotrZSL wrote: put those into anonymous namespace under clang::tidy::modernize https://github.com/llvm/llvm-project/pull/91124 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
https://github.com/PiotrZSL commented: Overall, i would see this as readability check. And I would see this as configurable check, so I could select one of: ` = 10;`, or `(10);` or `{10};` and stick to that convention. Other thing, in project not so long ago we had issues with {} initialization. Thing was that there were let say `std::vector variable{0x12345}`, and problem were that Object had constructor that take int as argument, and when developer expected to create something like this: `std::vector variable{{0x12345}}`, in fact created std::Vector that consumed few GB of memory. At that point idea were to restrict usage of `{}` for common containers, and report this as possible miss-spell. With this check, developers could run into more issues like this or containers that accept std::initialization list but also got normal containers. Using different initialization for different things usually helps protect against that. For example I do not think that `int callinit_5{(7 + (-9))};` is better than `int callinit_5 = 7 + (-9);`. And what I learn over years is that C++ standard is a one big trashbin, and if something is put there, it doesn't mean it's better. Just look into modernize-use-trailing-return-type, that check enforces something "new", but still on github alone there is over 3800 clang-tidy config files with this check explicitly disabled. So if you want to make this check actually usable, make it readability, and add config option to enforce specific style, note that there is also open issue for a check that would enforce `int a = 0;` instead of `int a = {}`; So you could somehow merge that. Overall check is +- fine, and if you want it it's ok, but I feat that it may end up as one of those "allways disable" checks, and it may not have to many users. https://github.com/llvm/llvm-project/pull/91124 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add `modernize-use-uniform-initializer` check (PR #91124)
@@ -0,0 +1,320 @@ +//===--- UseUniformInitializerCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseUniformInitializerCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/Tooling/FixIt.h" + +AST_MATCHER(clang::VarDecl, isVarOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInit()) +return false; + + const clang::VarDecl::InitializationStyle InitStyle = Node.getInitStyle(); + + return InitStyle == clang::VarDecl::InitializationStyle::CInit || + InitStyle == clang::VarDecl::InitializationStyle::CallInit; +} + +AST_MATCHER(clang::FieldDecl, isFieldOldStyleInitializer) { + // If it doesn't have any initializer the initializer style is not defined. + if (!Node.hasInClassInitializer() || Node.getInClassInitializer() == nullptr) +return false; + + const clang::InClassInitStyle InitStyle = Node.getInClassInitStyle(); + + return InitStyle == clang::InClassInitStyle::ICIS_CopyInit; +} + +AST_MATCHER(clang::CXXCtorInitializer, isCStyleInitializer) { + const clang::Expr *Init = Node.getInit(); + if (Init == nullptr) +return false; + + return !llvm::isa(Init); +} + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +constexpr const StringRef VarDeclID = "VarDecl"; +constexpr const StringRef FieldDeclId = "FieldDecl"; +constexpr const StringRef CtorInitID = "CtorInit"; + +constexpr const StringRef CStyleWarningMessage = +"Use uniform initializer instead of C-style initializer"; + +constexpr StringRef +getInitializerStyleName(VarDecl::InitializationStyle InitStyle) { + switch (InitStyle) { + case VarDecl::InitializationStyle::CInit: +return "C"; + + case VarDecl::InitializationStyle::CallInit: +return "call"; + + default: +llvm_unreachable("Invalid initializer style!"); + } +} + +SourceRange getParenLocationsForCallInit(const Expr *InitExpr, + const SourceManager , + const LangOptions ) { + // We need to handle 'CXXConstructExpr' differently + if (isa(InitExpr)) +return cast(InitExpr)->getParenOrBraceRange(); + + // If the init expression itself is a 'ParenExpr' then + // 'InitExpr->getBeginLoc()' will already point to a '(' which is not the + // opening paren of the 'CallInit' expression. So it that case we need to + // start one character before that. + const bool NeedOffsetForOpenParen = [&]() { +if (!isa(InitExpr)) + return false; + +const clang::StringRef CharBeforeParenExpr = +Lexer::getSourceText(CharSourceRange::getCharRange( + InitExpr->getBeginLoc().getLocWithOffset(-1), + InitExpr->getBeginLoc()), + SM, LangOpts); + +return llvm::isSpace(CharBeforeParenExpr[0]); + }(); + + const SourceLocation OpenParenLoc = utils::lexer::findPreviousTokenKind( + NeedOffsetForOpenParen ? InitExpr->getBeginLoc().getLocWithOffset(-1) + : InitExpr->getBeginLoc(), + SM, LangOpts, tok::l_paren); + const SourceLocation CloseParenLoc = utils::lexer::findNextTokenKind( + InitExpr->getEndLoc(), SM, LangOpts, tok::r_paren); + + return {OpenParenLoc, CloseParenLoc}; +} + +const BuiltinType *getBuiltinType(const Expr *Expr) { + assert(Expr); + return Expr->getType().getCanonicalType().getTypePtr()->getAs(); +} + +bool castRequiresStaticCast(const ImplicitCastExpr *CastExpr) { + const auto *FromExpr = CastExpr->getSubExpr(); + + if (CastExpr->isInstantiationDependent() || + FromExpr->isInstantiationDependent()) +return false; + if (getBuiltinType(CastExpr) == getBuiltinType(FromExpr)) +return false; + + switch (CastExpr->getCastKind()) { + case CastKind::CK_BaseToDerived: + case CastKind::CK_DerivedToBaseMemberPointer: + case CastKind::CK_IntegralCast: + case CastKind::CK_FloatingToIntegral: +return true; + + default: +return false; + } +} + +std::string buildReplacementString(const Expr *InitExpr, + const ASTContext ) { + // TODO: This function does not correctly handle the case where you have in + // 'ImplicitCastExpr' as an argument for a 'CXXConstructExpr'. + // In that case the generated code will not compile due to missing explicit + // cast of the sub expression. + + const SourceManager = Context.getSourceManager(); + const LangOptions = Context.getLangOpts(); + + const StringRef InitExprStr = [&]() { +if (isa(InitExpr)) { + const auto *ConstructExpr = llvm::cast(InitExpr); + + const SourceRange ParenRange