summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariya Podchishchaeva <mariya.podchishchaeva@intel.com>2023-03-07 10:57:23 -0500
committerTom Stellard <tstellar@redhat.com>2023-03-08 05:16:06 -0800
commita146bdc32034dca21f09c97f99691aa8c0939e97 (patch)
tree13f1c18f4567ef7e99961aa4f850389b0f66ea1b
parentae37edf1486d35ac6f441c5ff489ab46a94e125e (diff)
downloadllvm-a146bdc32034dca21f09c97f99691aa8c0939e97.tar.gz
[clang] Fix single-element array initialization in constexpr
https://reviews.llvm.org/D130791 added an improvement that in case array element has a trivial constructor, it is evaluated once and the result is re-used for remaining elements. Make sure the constructor is evaluated for single-elements arrays too. Fixes https://github.com/llvm/llvm-project/issues/60803 Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D145486 (cherry picked from commit af682f0df83f3364dac7ab92f39c7209dfbce28a)
-rw-r--r--clang/lib/AST/ExprConstant.cpp2
-rw-r--r--clang/test/SemaCXX/constexpr-single-element-array.cpp19
2 files changed, 20 insertions, 1 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 912a210fd254..9c56ab12529c 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10913,7 +10913,7 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
for (unsigned I = OldElts; I < N; ++I)
Value->getArrayInitializedElt(I) = Filler;
- if (HasTrivialConstructor && N == FinalSize) {
+ if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
// If we have a trivial constructor, only evaluate it once and copy
// the result into all the array elements.
APValue &FirstResult = Value->getArrayInitializedElt(0);
diff --git a/clang/test/SemaCXX/constexpr-single-element-array.cpp b/clang/test/SemaCXX/constexpr-single-element-array.cpp
new file mode 100644
index 000000000000..a01b1a1c8f13
--- /dev/null
+++ b/clang/test/SemaCXX/constexpr-single-element-array.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+
+// This test makes sure that a single element array doesn't produce
+// spurious errors during constexpr evaluation.
+
+// expected-no-diagnostics
+struct Sub { int x; };
+
+struct S {
+ constexpr S() { Arr[0] = Sub{}; }
+ Sub Arr[1];
+};
+
+constexpr bool test() {
+ S s;
+ return true;
+}
+
+static_assert(test());