[clang] c77a91b - [clang] Remove overly restrictive aggregate paren init logic

Alan Zhao via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 21 08:21:11 PST 2022


Author: Alan Zhao
Date: 2022-12-21T08:21:05-08:00
New Revision: c77a91bb7ba793ec3a6a5da3743ed55056291658

URL: https://github.com/llvm/llvm-project/commit/c77a91bb7ba793ec3a6a5da3743ed55056291658
DIFF: https://github.com/llvm/llvm-project/commit/c77a91bb7ba793ec3a6a5da3743ed55056291658.diff

LOG: [clang] Remove overly restrictive aggregate paren init logic

Previously, we would only attempt to perform a parenthesized aggregate
initialization if constructor initialization failed for only the default
constructor, default copy constructor, and default move constructor. The
original intent of this logic was to reject initializing objects that
have failed resolving a user-defined constructor. However, this check is
redundant because we check for isAggregate() before attempting to
perform a parenthesized aggregate initialization, and classes that have
user-defined or user-declared constructors are not aggregates.
Furthermore, this check is too restrictive - the following valid
examples fail:
* Aggregate class with user-defined destructor - fails because default
  move constructors are not generated for classes with user-defined
  destructors
  (https://github.com/llvm/llvm-project/issues/54040#issuecomment-1356926048)
* Concept-guarded conversion operator on an aggregate's member:
  (https://github.com/llvm/llvm-project/issues/54040#issuecomment-1356931745)

The solution therefore is to remove this logic; existing tests still
pass, and the previously failing examples now compile.

Reviewed By: ilya-biryukov

Differential Revision: https://reviews.llvm.org/D140327

Added: 
    

Modified: 
    clang/lib/Sema/SemaInit.cpp
    clang/test/CodeGen/paren-list-agg-init.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index de419cae490ff..103986521f76e 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -5930,25 +5930,6 @@ static bool canPerformArrayCopy(const InitializedEntity &Entity) {
   return false;
 }
 
-static bool onlyHasDefaultedCtors(OverloadCandidateSet &OCS) {
-  if (OCS.size() != 3)
-    return false;
-
-  bool HasDefaultCtor = false, HasCopyCtor = false, HasMoveCtor = false;
-  for (const auto &Candidate : OCS) {
-    if (auto *Ctor = dyn_cast_or_null<CXXConstructorDecl>(Candidate.Function);
-        Ctor != nullptr && Ctor->isDefaulted()) {
-      if (Ctor->isDefaultConstructor())
-        HasDefaultCtor = true;
-      else if (Ctor->isCopyConstructor())
-        HasCopyCtor = true;
-      else if (Ctor->isMoveConstructor())
-        HasMoveCtor = true;
-    }
-  }
-  return HasDefaultCtor && HasCopyCtor && HasMoveCtor;
-}
-
 void InitializationSequence::InitializeFrom(Sema &S,
                                             const InitializedEntity &Entity,
                                             const InitializationKind &Kind,
@@ -6196,8 +6177,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
       if (const auto *RD =
               dyn_cast<CXXRecordDecl>(DestType->getAs<RecordType>()->getDecl());
           S.getLangOpts().CPlusPlus20 && RD && RD->isAggregate() && Failed() &&
-          getFailureKind() == FK_ConstructorOverloadFailed &&
-          onlyHasDefaultedCtors(getFailedCandidateSet())) {
+          getFailureKind() == FK_ConstructorOverloadFailed) {
         // C++20 [dcl.init] 17.6.2.2:
         //   - Otherwise, if no constructor is viable, the destination type is
         //   an

diff  --git a/clang/test/CodeGen/paren-list-agg-init.cpp b/clang/test/CodeGen/paren-list-agg-init.cpp
index 991cb4950b187..a7534fb907d2b 100644
--- a/clang/test/CodeGen/paren-list-agg-init.cpp
+++ b/clang/test/CodeGen/paren-list-agg-init.cpp
@@ -1,9 +1,25 @@
 // RUN: %clang_cc1 -std=c++20 %s -emit-llvm -triple x86_64-unknown-linux-gnu -o - | FileCheck %s
 
+template <typename T>
+struct IsChar {
+  constexpr operator bool() const { return false; }
+};
+
+template<>
+struct IsChar<char> {
+  constexpr operator bool() const { return true; }
+};
+
+template <typename T>
+concept SameAsChar = (bool)IsInt<T>();
+
 // CHECK-DAG: [[STRUCT_A:%.*]] = type { i8, double }
 struct A {
   char i;
   double j;
+
+  template <SameAsChar T>
+  operator T() const { return i; };
 };
 
 // CHECK-DAG: [[STRUCT_B:%.*]] = type { [[STRUCT_A]], i32 }
@@ -29,6 +45,7 @@ struct D {
 struct E {
   int a;
   const char* fn = __builtin_FUNCTION();
+  ~E() {};
 };
 
 // CHECK-DAG: [[STRUCT_F:%.*]] = type { i8 }


        


More information about the cfe-commits mailing list