aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariya Podchishchaeva <mariya.podchishchaeva@intel.com>2024-06-20 11:03:27 +0300
committerGitHub <noreply@github.com>2024-06-20 10:03:27 +0200
commitb9ad0b6875950a0e161ad31447f796562f55a83a (patch)
treee02694d64c981abc075771645a6f22764677b8c9
parent7cf84d3b0bc5eda3a907dfd026d51a17e28114a3 (diff)
downloadllvm-b9ad0b6875950a0e161ad31447f796562f55a83a.zip
llvm-b9ad0b6875950a0e161ad31447f796562f55a83a.tar.gz
llvm-b9ad0b6875950a0e161ad31447f796562f55a83a.tar.bz2
[clang] Fix `static_cast` to array of unknown bound (#96041)
Per P1975R0 an expression like static_cast<U[]>(...) defines the type of the expression as U[1]. Fixes https://github.com/llvm/llvm-project/issues/62863
-rw-r--r--clang/docs/ReleaseNotes.rst2
-rw-r--r--clang/lib/Sema/SemaType.cpp14
-rw-r--r--clang/test/SemaCXX/paren-list-agg-init.cpp21
3 files changed, 37 insertions, 0 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7112d1f..d0e5e67 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -695,6 +695,8 @@ Bug Fixes in This Version
- Correctly reject declarations where a statement is required in C.
Fixes #GH92775
+- Fixed `static_cast` to array of unknown bound. Fixes (#GH62863).
+
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 441fdcc..9bb12c6 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8771,6 +8771,20 @@ void Sema::completeExprArrayBound(Expr *E) {
}
}
}
+ if (const auto CastE = dyn_cast<ExplicitCastExpr>(E)) {
+ QualType DestType = CastE->getTypeAsWritten();
+ if (const auto *IAT = Context.getAsIncompleteArrayType(DestType)) {
+ // C++20 [expr.static.cast]p.4: ... If T is array of unknown bound,
+ // this direct-initialization defines the type of the expression
+ // as U[1]
+ QualType ResultType = Context.getConstantArrayType(
+ IAT->getElementType(),
+ llvm::APInt(Context.getTypeSize(Context.getSizeType()), 1),
+ /*SizeExpr=*/nullptr, ArraySizeModifier::Normal,
+ /*IndexTypeQuals=*/0);
+ E->setType(ResultType);
+ }
+ }
}
QualType Sema::getCompletedType(Expr *E) {
diff --git a/clang/test/SemaCXX/paren-list-agg-init.cpp b/clang/test/SemaCXX/paren-list-agg-init.cpp
index c1964a5..efc1e95 100644
--- a/clang/test/SemaCXX/paren-list-agg-init.cpp
+++ b/clang/test/SemaCXX/paren-list-agg-init.cpp
@@ -313,3 +313,24 @@ namespace GH63903 {
constexpr S s(0); // beforecxx20-warning {{aggregate initialization of type 'const S' from a parenthesized list of values is a C++20 extension}} \
// expected-error {{constexpr variable 's' must be initialized by a constant expression}}
}
+
+
+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 (&&arr2)[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}}
+
+int (&&arr4)[] = (int[])(42);
+// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
+int (&&arr5)[1] = (int[])(42);
+// beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
+int (&&arr6)[2] = (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 (&&arr7)[3] = (int[3])(42);
+// beforecxx20-warning@-1 {{aggregate initialization of type 'int[3]' from a parenthesized list of values is a C++20 extension}}
+}