Fznamznon created this revision. Herald added a project: All. Fznamznon requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
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 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D145486 Files: clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constexpr-single-element-array.cpp Index: clang/test/SemaCXX/constexpr-single-element-array.cpp =================================================================== --- /dev/null +++ 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 single element array in constexpr doesn't produce +/// spurious errors. + +/// 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()); Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -10917,7 +10917,7 @@ for (unsigned I = OldElts; I < N; ++I) Value->getArrayInitializedElt(I) = Filler; - if (HasTrivialConstructor && N == FinalSize) { + if (HasTrivialConstructor && N == FinalSize && N != 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);
Index: clang/test/SemaCXX/constexpr-single-element-array.cpp =================================================================== --- /dev/null +++ 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 single element array in constexpr doesn't produce +/// spurious errors. + +/// 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()); Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -10917,7 +10917,7 @@ for (unsigned I = OldElts; I < N; ++I) Value->getArrayInitializedElt(I) = Filler; - if (HasTrivialConstructor && N == FinalSize) { + if (HasTrivialConstructor && N == FinalSize && N != 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);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits