[clang] [Sema]Report error for non-base types in constructor initializers before causing issue in initializer order (PR #201379)
Gábor Spaits via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 4 12:50:39 PDT 2026
https://github.com/spaits updated https://github.com/llvm/llvm-project/pull/201379
>From 1b3e9c78b14c01668d493c4376f19ee3c806cca3 Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
Date: Thu, 4 Jun 2026 21:50:26 +0200
Subject: [PATCH] [Sema]Report error for non-base types in constructor
initializers before causing issue in initializer order
---
clang/lib/Sema/SemaDeclCXX.cpp | 49 +++++++++++++++++-----------------
1 file changed, 25 insertions(+), 24 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index de837ff0608d0..7e44efae52bce 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/ComparisonCategories.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DynamicRecursiveASTVisitor.h"
@@ -4816,33 +4817,33 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
return true;
}
+ if (!Dependent && declaresSameEntity(ClassDecl, BaseType->getAsCXXRecordDecl()))
+ return BuildDelegatingInitializer(BaseTInfo, Init, ClassDecl);
+
// Check for direct and virtual base classes.
const CXXBaseSpecifier *DirectBaseSpec = nullptr;
const CXXBaseSpecifier *VirtualBaseSpec = nullptr;
- if (!Dependent) {
- if (declaresSameEntity(ClassDecl, BaseType->getAsCXXRecordDecl()))
- return BuildDelegatingInitializer(BaseTInfo, Init, ClassDecl);
-
- FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec,
- VirtualBaseSpec);
-
- // C++ [base.class.init]p2:
- // Unless the mem-initializer-id names a nonstatic data member of the
- // constructor's class or a direct or virtual base of that class, the
- // mem-initializer is ill-formed.
- if (!DirectBaseSpec && !VirtualBaseSpec) {
- // If the class has any dependent bases, then it's possible that
- // one of those types will resolve to the same type as
- // BaseType. Therefore, just treat this as a dependent base
- // class initialization. FIXME: Should we try to check the
- // initialization anyway? It seems odd.
- if (ClassDecl->hasAnyDependentBases())
- Dependent = true;
- else
- return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
- << BaseType << Context.getCanonicalTagType(ClassDecl)
- << BaseTInfo->getTypeLoc().getSourceRange();
- }
+
+ FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec,
+ VirtualBaseSpec);
+
+ // C++ [base.class.init]p2:
+ // Unless the mem-initializer-id names a nonstatic data member of the
+ // constructor's class or a direct or virtual base of that class, the
+ // mem-initializer is ill-formed.
+ if (!DirectBaseSpec && !VirtualBaseSpec) {
+ // If the class has any dependent bases, then it's possible that
+ // one of those types will resolve to the same type as
+ // BaseType. Therefore, just treat this as a dependent base
+ // class initialization. FIXME: Should we try to check the
+ // initialization anyway? It seems odd.
+ if (ClassDecl->hasAnyDependentBases())
+ Dependent = true;
+ // We may have a delegating initializer
+ else if (!declaresSameEntity(ClassDecl, BaseType->getAsCXXRecordDecl()))
+ return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
+ << BaseType << Context.getCanonicalTagType(ClassDecl)
+ << BaseTInfo->getTypeLoc().getSourceRange();
}
if (Dependent) {
More information about the cfe-commits
mailing list