[clang-tools-extra] [clang-tidy] Add new check misc-use-braced-initialization (PR #184009)
Baranov Victor via cfe-commits
cfe-commits at lists.llvm.org
Mon May 11 02:34:24 PDT 2026
================
@@ -0,0 +1,160 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "UseBracedInitializationCheck.h"
+#include "../utils/LexerUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::misc {
+
+namespace {
+
+AST_MATCHER_P(VarDecl, hasInitStyle, VarDecl::InitializationStyle, Style) {
+ return Node.getInitStyle() == Style;
+}
+
+AST_MATCHER(Type, isDependentType) { return Node.isDependentType(); }
+
+AST_MATCHER(CXXConstructExpr, noMacroParens) {
+ const SourceRange Range = Node.getParenOrBraceRange();
+ return Range.isValid() && !Range.getBegin().isMacroID() &&
+ !Range.getEnd().isMacroID();
+}
+
+AST_MATCHER(Expr, isCXXParenListInitExpr) {
+ return isa<CXXParenListInitExpr>(Node);
+}
+
+/// Matches CXXConstructExpr whose target class has any constructor
+/// taking 'std::initializer_list'. When such a constructor exists, braced
+/// initialization may call it instead of the intended constructor.
+AST_MATCHER(CXXConstructExpr, constructsTypeWithInitListCtor) {
+ const CXXRecordDecl *RD = Node.getConstructor()->getParent();
+ if (!RD || !RD->hasDefinition())
+ return false;
+ return llvm::any_of(RD->ctors(), [](const CXXConstructorDecl *Ctor) {
+ if (Ctor->getNumParams() == 0)
+ return false;
+ const QualType FirstParam =
+ Ctor->getParamDecl(0)->getType().getNonReferenceType();
+ const auto *Record = FirstParam->getAsCXXRecordDecl();
+ if (!Record || !Record->getDeclName().isIdentifier() ||
+ Record->getName() != "initializer_list" || !Record->isInStdNamespace())
+ return false;
+ // [dcl.init.list] p2: all other params must have defaults.
+ for (unsigned I = 1; I < Ctor->getNumParams(); ++I)
+ if (!Ctor->getParamDecl(I)->hasDefaultArg())
+ return false;
+ return true;
+ });
+}
+
+} // namespace
+
+void UseBracedInitializationCheck::registerMatchers(MatchFinder *Finder) {
+ auto GoodCtor = allOf(
+ noMacroParens(), unless(constructsTypeWithInitListCtor()),
+ unless(isInTemplateInstantiation()), unless(isListInitialization()));
----------------
vbvictor wrote:
Most of them was ok, one left with AS_IS
https://github.com/llvm/llvm-project/pull/184009
More information about the cfe-commits
mailing list