[PATCH] D113518: [clang] Create delegating constructors even in templates

Fabian Wolff via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 10 13:15:29 PST 2021


fwolff updated this revision to Diff 386297.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113518/new/

https://reviews.llvm.org/D113518

Files:
  clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init.cpp
  clang/lib/Sema/SemaDeclCXX.cpp


Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -4496,6 +4496,8 @@
   // (broken) code in a non-template! SetCtorInitializers does not expect this.
   bool Dependent = CurContext->isDependentContext() &&
                    (BaseType->isDependentType() || Init->isTypeDependent());
+  bool Delegating = Context.hasSameUnqualifiedType(
+      QualType(ClassDecl->getTypeForDecl(), 0), BaseType);
 
   SourceRange InitRange = Init->getSourceRange();
   if (EllipsisLoc.isValid()) {
@@ -4519,8 +4521,7 @@
   const CXXBaseSpecifier *DirectBaseSpec = nullptr;
   const CXXBaseSpecifier *VirtualBaseSpec = nullptr;
   if (!Dependent) {
-    if (Context.hasSameUnqualifiedType(QualType(ClassDecl->getTypeForDecl(),0),
-                                       BaseType))
+    if (Delegating)
       return BuildDelegatingInitializer(BaseTInfo, Init, ClassDecl);
 
     FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec,
@@ -4548,10 +4549,14 @@
   if (Dependent) {
     DiscardCleanupsInEvaluationContext();
 
-    return new (Context) CXXCtorInitializer(Context, BaseTInfo,
-                                            /*IsVirtual=*/false,
-                                            InitRange.getBegin(), Init,
-                                            InitRange.getEnd(), EllipsisLoc);
+    if (!Delegating)
+      return new (Context)
+          CXXCtorInitializer(Context, BaseTInfo,
+                             /*IsVirtual=*/false, InitRange.getBegin(), Init,
+                             InitRange.getEnd(), EllipsisLoc);
+    else
+      return new (Context) CXXCtorInitializer(
+          Context, BaseTInfo, InitRange.getBegin(), Init, InitRange.getEnd());
   }
 
   // C++ [base.class.init]p2:
@@ -5063,14 +5068,16 @@
   memcpy(initializer, &Initializer, sizeof (CXXCtorInitializer*));
   Constructor->setCtorInitializers(initializer);
 
-  if (CXXDestructorDecl *Dtor = LookupDestructor(Constructor->getParent())) {
-    MarkFunctionReferenced(Initializer->getSourceLocation(), Dtor);
-    DiagnoseUseOfDecl(Dtor, Initializer->getSourceLocation());
-  }
+  if (!Constructor->isDependentContext()) {
+    if (CXXDestructorDecl *Dtor = LookupDestructor(Constructor->getParent())) {
+      MarkFunctionReferenced(Initializer->getSourceLocation(), Dtor);
+      DiagnoseUseOfDecl(Dtor, Initializer->getSourceLocation());
+    }
 
-  DelegatingCtorDecls.push_back(Constructor);
+    DelegatingCtorDecls.push_back(Constructor);
 
-  DiagnoseUninitializedFields(*this, Constructor);
+    DiagnoseUninitializedFields(*this, Constructor);
+  }
 
   return false;
 }
Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init.cpp
@@ -372,8 +372,6 @@
 class PositiveSelfInitialization : NegativeAggregateType
 {
   PositiveSelfInitialization() : PositiveSelfInitialization() {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType
-  // CHECK-FIXES: PositiveSelfInitialization() : NegativeAggregateType(), PositiveSelfInitialization() {}
 };
 
 class PositiveIndirectMember {
@@ -552,3 +550,18 @@
   int A;
   // CHECK-FIXES-NOT: int A{};
 };
+
+// Check that a delegating constructor in a template does not trigger false positives (PR#37902).
+template <typename T>
+struct TemplateWithDelegatingCtor {
+  int X;
+  TemplateWithDelegatingCtor() : X{} {};
+  TemplateWithDelegatingCtor(int) : TemplateWithDelegatingCtor(){};
+};
+
+template <typename T>
+struct TemplateWithDelegatingCtorNSDMI {
+  int X{};
+  TemplateWithDelegatingCtorNSDMI() = default;
+  TemplateWithDelegatingCtorNSDMI(int) : TemplateWithDelegatingCtorNSDMI() {}
+};


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113518.386297.patch
Type: text/x-patch
Size: 4020 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211110/6e85eabd/attachment.bin>


More information about the cfe-commits mailing list