diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -561,6 +561,8 @@ when an immediate invocation appears as a part of an expression that produces temporaries. (`#60709 <https://github.com/llvm/llvm-project/issues/60709>`_). +- Fixed `static_cast` to array of unknown bound. + (`#62863 <https://github.com/llvm/llvm-project/issues/62863>`_). Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -1262,6 +1262,15 @@ } else { SrcExpr = ExprError(); } + + if (const auto *IAT = Self.Context.getAsIncompleteArrayType(DestType)) { + // C++20 [expr.static.cast]p.4: ... If T is “array of unknown bound of Uâ€, + // this direct-initialization defines the type of the expression as U[1] + ResultType = Self.Context.getConstantArrayType( + IAT->getElementType(), + llvm::APInt(Self.Context.getTypeSize(Self.Context.getSizeType()), 1), + /*SizeExpr=*/nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0); + } } static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType) { diff --git a/clang/test/SemaCXX/paren-list-agg-init.cpp b/clang/test/SemaCXX/paren-list-agg-init.cpp --- a/clang/test/SemaCXX/paren-list-agg-init.cpp +++ b/clang/test/SemaCXX/paren-list-agg-init.cpp @@ -272,3 +272,14 @@ // expected-warning@-1 {{braces around scalar init}} // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} } + +namespace gh62863 { +int (&&arr)[] = static_cast<int[]>(42); +// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}} +int (&&arr1)[1] = static_cast<int[]>(42); +// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}} +int (&&arrr2)[2] = static_cast<int[]>(42); // expected-error {{reference to type 'int[2]' could not bind to an rvalue of type 'int[1]'}} +// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}} +int (&&arr3)[3] = static_cast<int[3]>(42); +// beforecxx20-warning@-1 {{aggregate initialization of type 'int[3]' from a parenthesized list of values is a C++20 extension}} +}