diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 77aad0c9731be..29b730c2e0179 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -248,6 +248,9 @@ Bug Fixes in This Version (`#66047 `_) - Fix parser crash when dealing with ill-formed objective C++ header code. Fixes (`#64836 `_) +- Fix crash in implicit conversions from initialize list to arrays of unknown + bound for C++20. Fixes + (`#62945 `_) - Clang now allows an ``_Atomic`` qualified integer in a switch statement. Fixes (`#65557 `_) diff --git a/clang/include/clang/AST/OperationKinds.def b/clang/include/clang/AST/OperationKinds.def index 96b5a4db55e0c..8dd98730dff74 100644 --- a/clang/include/clang/AST/OperationKinds.def +++ b/clang/include/clang/AST/OperationKinds.def @@ -80,6 +80,7 @@ CAST_OPERATION(LValueToRValue) /// (possibly) adding qualifiers or removing noexcept. /// int -> int /// char** -> const char * const * +/// int[1] -> int[] /// void () noexcept -> void () CAST_OPERATION(NoOp) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index cb57a2d1a555c..de576cc52c42e 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -18,6 +18,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Designator.h" #include "clang/Sema/EnterExpressionEvaluationContext.h" @@ -4528,6 +4529,17 @@ static void TryReferenceListInitialization(Sema &S, if (Sequence) { if (DestType->isRValueReferenceType() || (T1Quals.hasConst() && !T1Quals.hasVolatile())) { + if (S.getLangOpts().CPlusPlus20 && + isa(T1->getUnqualifiedDesugaredType()) && + DestType->isRValueReferenceType()) { + // C++20 [dcl.init.list]p3.10: + // List-initialization of an object or reference of type T is defined as + // follows: + // ..., unless T is “reference to array of unknown bound of U”, in which + // case the type of the prvalue is the type of x in the declaration U + // x[] H, where H is the initializer list. + Sequence.AddQualificationConversionStep(cv1T1, clang::VK_PRValue); + } Sequence.AddReferenceBindingStep(cv1T1IgnoreAS, /*BindingTemporary=*/true); if (T1Quals.hasAddressSpace()) diff --git a/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp b/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp index 78f35a024a540..a29f4d720c1de 100644 --- a/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp +++ b/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp @@ -23,4 +23,13 @@ auto &frob2(int (&arp)[1]) { return r2; } + +// CHECK-LABEL: @_ZN3One3fooEi +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void +void foo(int a) { + auto f = [](int(&&)[]) {}; + f({a}); +} + } // namespace One