https://github.com/mordante updated https://github.com/llvm/llvm-project/pull/76833
>From 77abc737eebd5cf62b52248a6e35e4c74fbeca80 Mon Sep 17 00:00:00 2001 From: Mark de Wever <ko...@xs4all.nl> Date: Wed, 3 Jan 2024 18:00:43 +0100 Subject: [PATCH 1/2] "Reapply "[Sema] Fix crash on invalid code with parenthesized aggregate initialization" (#76272)"" With updates the libc++ tests. This reverts commit 2205d23 and relands 86dc6e1 and 7ab16fb. Original commit was reverted because of failing libc++ tests, see #76232 for the discussion. The errors in the tests are spurious in the first place (coming from initialization of invalid classes), so update the tests to match new behavior that does not show those errors. --- clang/lib/Sema/SemaInit.cpp | 8 ++++++ clang/test/SemaCXX/crash-GH76228.cpp | 28 +++++++++++++++++++ clang/test/SemaCXX/paren-list-agg-init.cpp | 2 +- .../transform_error.mandates.verify.cpp | 8 ------ .../transform_error.mandates.verify.cpp | 8 ------ 5 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 clang/test/SemaCXX/crash-GH76228.cpp diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 61d244f3bb9798a..cc9db5ded1149a0 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -5512,6 +5512,14 @@ static void TryOrBuildParenListInitialization( } else if (auto *RT = Entity.getType()->getAs<RecordType>()) { bool IsUnion = RT->isUnionType(); const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); + if (RD->isInvalidDecl()) { + // Exit early to avoid confusion when processing members. + // We do the same for braced list initialization in + // `CheckStructUnionTypes`. + Sequence.SetFailed( + clang::InitializationSequence::FK_ParenthesizedListInitFailed); + return; + } if (!IsUnion) { for (const CXXBaseSpecifier &Base : RD->bases()) { diff --git a/clang/test/SemaCXX/crash-GH76228.cpp b/clang/test/SemaCXX/crash-GH76228.cpp new file mode 100644 index 000000000000000..33a9395823127ea --- /dev/null +++ b/clang/test/SemaCXX/crash-GH76228.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -std=c++20 -verify %s +// Check we don't crash on incomplete members and bases when handling parenthesized initialization. +class incomplete; // expected-note@-0 3 {{forward declaration of 'incomplete'}} +struct foo { + int a; + incomplete b; + // expected-error@-1 {{incomplete type}} +}; +foo a1(0); + +struct one_int { + int a; +}; +struct bar : one_int, incomplete {}; +// expected-error@-1 {{incomplete type}} +bar a2(0); + +incomplete a3[3](1,2,3); +// expected-error@-1 {{incomplete type}} + +struct qux : foo { +}; +qux a4(0); + +struct fred { + foo a[3]; +}; +fred a5(0); diff --git a/clang/test/SemaCXX/paren-list-agg-init.cpp b/clang/test/SemaCXX/paren-list-agg-init.cpp index f60b20e0d465685..c1964a5a9eb0058 100644 --- a/clang/test/SemaCXX/paren-list-agg-init.cpp +++ b/clang/test/SemaCXX/paren-list-agg-init.cpp @@ -289,7 +289,7 @@ int test() { // used to crash S a(0, 1); S b(0); - S c(0, 0, 1); // beforecxx20-warning {{aggregate initialization of type 'S' from a parenthesized list of values is a C++20 extension}} + S c(0, 0, 1); S d {0, 1}; S e {0}; diff --git a/libcxx/test/libcxx/utilities/expected/expected.expected/transform_error.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/transform_error.mandates.verify.cpp index 965e82a7b403465..3260a8cbc7f8e68 100644 --- a/libcxx/test/libcxx/utilities/expected/expected.expected/transform_error.mandates.verify.cpp +++ b/libcxx/test/libcxx/utilities/expected/expected.expected/transform_error.mandates.verify.cpp @@ -46,11 +46,9 @@ void test() { { std::expected<int, int> e; e.transform_error(return_unexpected<int&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} // expected-error-re@*:* {{static assertion failed {{.*}}[expected.object.general] A program that instantiates the definition of template expected<T, E> for {{.*}} is ill-formed.}} e.transform_error(return_no_object<int&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} // expected-error-re@*:* {{static assertion failed {{.*}}[expected.object.general] A program that instantiates the definition of template expected<T, E> for {{.*}} is ill-formed.}} } @@ -58,27 +56,21 @@ void test() { { const std::expected<int, int> e; e.transform_error(return_unexpected<const int &>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} e.transform_error(return_no_object<const int &>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} } // Test && overload { std::expected<int, int> e; std::move(e).transform_error(return_unexpected<int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} std::move(e).transform_error(return_no_object<int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} } // Test const&& overload { const std::expected<int, int> e; std::move(e).transform_error(return_unexpected<const int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} std::move(e).transform_error(return_no_object<const int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* 2 {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} } } // clang-format on diff --git a/libcxx/test/libcxx/utilities/expected/expected.void/transform_error.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.void/transform_error.mandates.verify.cpp index 09aa1332e980005..21dc24768791862 100644 --- a/libcxx/test/libcxx/utilities/expected/expected.void/transform_error.mandates.verify.cpp +++ b/libcxx/test/libcxx/utilities/expected/expected.void/transform_error.mandates.verify.cpp @@ -46,11 +46,9 @@ void test() { { std::expected<void, int> e; e.transform_error(return_unexpected<int&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} // expected-error-re@*:* {{static assertion failed {{.*}}A program that instantiates expected<T, E> with a E that is not a valid argument for unexpected<E> is ill-formed}} e.transform_error(return_no_object<int&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} // expected-error-re@*:* {{static assertion failed {{.*}}A program that instantiates expected<T, E> with a E that is not a valid argument for unexpected<E> is ill-formed}} } @@ -58,27 +56,21 @@ void test() { { const std::expected<void, int> e; e.transform_error(return_unexpected<const int &>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} e.transform_error(return_no_object<const int &>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} } // Test && overload { std::expected<void, int> e; std::move(e).transform_error(return_unexpected<int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} std::move(e).transform_error(return_no_object<int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} } // Test const&& overload { const std::expected<void, int> e; std::move(e).transform_error(return_unexpected<const int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} std::move(e).transform_error(return_no_object<const int&&>); // expected-error-re@*:* {{static assertion failed {{.*}}The result of {{.*}} must be a valid template argument for unexpected}} - // expected-error-re@*:* {{{{(excess elements in struct initializer|no matching constructor for initialization of)}}{{.*}}}} } } // clang-format on >From 9e32e29c3413139db312f360e2d3930ccd8679f8 Mon Sep 17 00:00:00 2001 From: Mark de Wever <ko...@xs4all.nl> Date: Wed, 3 Jan 2024 18:27:48 +0100 Subject: [PATCH 2/2] Test the bootstrap build. --- .github/workflows/libcxx-build-and-test.yaml | 110 ------------------- 1 file changed, 110 deletions(-) diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml index 25e8c8c1ef21aa7..65997d9c1ca411a 100644 --- a/.github/workflows/libcxx-build-and-test.yaml +++ b/.github/workflows/libcxx-build-and-test.yaml @@ -48,124 +48,14 @@ env: jobs: - stage1: - if: github.repository_owner == 'llvm' - runs-on: libcxx-runners-8-set - continue-on-error: false - strategy: - fail-fast: false - matrix: - config: [ - 'generic-cxx03', - 'generic-cxx26', - 'generic-modules' - ] - cc: [ 'clang-18' ] - cxx: [ 'clang++-18' ] - clang_tidy: [ 'ON' ] - include: - - config: 'generic-gcc' - cc: 'gcc-13' - cxx: 'g++-13' - clang_tidy: 'OFF' - steps: - - uses: actions/checkout@v4 - - name: ${{ matrix.config }}.${{ matrix.cxx }} - run: libcxx/utils/ci/run-buildbot ${{ matrix.config }} - env: - CC: ${{ matrix.cc }} - CXX: ${{ matrix.cxx }} - ENABLE_CLANG_TIDY: ${{ matrix.clang_tidy }} - - uses: actions/upload-artifact@v3 - if: always() - with: - name: ${{ matrix.config }}-${{ matrix.cxx }}-results - path: | - **/test-results.xml - **/*.abilist - **/CMakeError.log - **/CMakeOutput.log - **/crash_diagnostics/* - stage2: - if: github.repository_owner == 'llvm' - runs-on: libcxx-runners-8-set - needs: [ stage1 ] - continue-on-error: false - strategy: - fail-fast: false - matrix: - config: [ - 'generic-cxx11', - 'generic-cxx14', - 'generic-cxx17', - 'generic-cxx20', - 'generic-cxx23' - ] - cc: [ 'clang-18' ] - cxx: [ 'clang++-18' ] - clang_tidy: [ 'ON' ] - include: - - config: 'generic-gcc-cxx11' - cc: 'gcc-13' - cxx: 'g++-13' - clang_tidy: 'OFF' - - config: 'generic-cxx23' - cc: 'clang-16' - cxx: 'clang++-16' - clang_tidy: 'OFF' - - config: 'generic-cxx23' - cc: 'clang-17' - cxx: 'clang++-17' - clang_tidy: 'OFF' - steps: - - uses: actions/checkout@v4 - - name: ${{ matrix.config }} - run: libcxx/utils/ci/run-buildbot ${{ matrix.config }} - env: - CC: ${{ matrix.cc }} - CXX: ${{ matrix.cxx }} - ENABLE_CLANG_TIDY: ${{ matrix.clang_tidy }} - - uses: actions/upload-artifact@v3 - if: always() # Upload artifacts even if the build or test suite fails - with: - name: ${{ matrix.config }}-results - path: | - **/test-results.xml - **/*.abilist - **/CMakeError.log - **/CMakeOutput.log - **/crash_diagnostics/* stage3: if: github.repository_owner == 'llvm' - needs: [ stage1, stage2 ] continue-on-error: false strategy: fail-fast: false max-parallel: 8 matrix: config: [ - 'generic-abi-unstable', - 'generic-hardening-mode-debug', - 'generic-hardening-mode-extensive', - 'generic-hardening-mode-fast', - 'generic-hardening-mode-fast-with-abi-breaks', - 'generic-merged', - 'generic-modules-lsv', - 'generic-no-exceptions', - 'generic-no-experimental', - 'generic-no-filesystem', - 'generic-no-localization', - 'generic-no-random_device', - 'generic-no-threads', - 'generic-no-tzdb', - 'generic-no-unicode', - 'generic-no-wide-characters', - 'generic-no-rtti', - 'generic-static', - 'generic-with_llvm_unwinder', - # TODO Find a better place for the benchmark and bootstrapping builds to live. They're either very expensive - # or don't provide much value since the benchmark run results are too noise on the bots. - 'benchmarks', 'bootstrapping-build' ] machine: [ 'libcxx-runners-8-set' ] _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits