[clang] Fix single-element array initialization in constexpr
authorMariya Podchishchaeva <mariya.podchishchaeva@intel.com>
Tue, 7 Mar 2023 15:57:23 +0000 (10:57 -0500)
committerMariya Podchishchaeva <mariya.podchishchaeva@intel.com>
Tue, 7 Mar 2023 15:57:35 +0000 (10:57 -0500)
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

clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/constexpr-single-element-array.cpp [new file with mode: 0644]

index 6b0beb1..26c2342 100644 (file)
@@ -10917,7 +10917,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 (file)
index 0000000..a01b1a1
--- /dev/null
@@ -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());