This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG32d7aae04fdb: [clang] Fix a clang crash on invalid code in C++20 mode. (authored by hokein).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D140587/new/ https://reviews.llvm.org/D140587 Files: clang/lib/Sema/SemaInit.cpp clang/test/SemaCXX/recovery-expr-type.cpp Index: clang/test/SemaCXX/recovery-expr-type.cpp =================================================================== --- clang/test/SemaCXX/recovery-expr-type.cpp +++ clang/test/SemaCXX/recovery-expr-type.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -o - %s -std=gnu++17 -fsyntax-only -verify +// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++17 -fsyntax-only -verify +// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++20 -fsyntax-only -verify + namespace test0 { struct Indestructible { @@ -171,3 +173,13 @@ S.m(1); // no crash } } + +namespace test16 { +// verify we do not crash on incomplete class type. +template<typename T, typename U> struct A; // expected-note 5{{template is declared here}} +A<int, int> foo() { // expected-error {{implicit instantiation of undefined template}} + if (1 == 1) + return A<int, int>{1}; // expected-error 2{{implicit instantiation of undefined template}} + return A<int, int>(1); // expected-error 2{{implicit instantiation of undefined template}} +} +} Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -6176,7 +6176,11 @@ // constructors. For example, conversion function. if (const auto *RD = dyn_cast<CXXRecordDecl>(DestType->getAs<RecordType>()->getDecl()); - S.getLangOpts().CPlusPlus20 && RD && RD->isAggregate() && Failed() && + // In general, we should call isCompleteType for RD to check its + // completeness, we don't call it here as it was already called in the + // above TryConstructorInitialization. + S.getLangOpts().CPlusPlus20 && RD && RD->hasDefinition() && + RD->isAggregate() && Failed() && getFailureKind() == FK_ConstructorOverloadFailed) { // C++20 [dcl.init] 17.6.2.2: // - Otherwise, if no constructor is viable, the destination type is
Index: clang/test/SemaCXX/recovery-expr-type.cpp =================================================================== --- clang/test/SemaCXX/recovery-expr-type.cpp +++ clang/test/SemaCXX/recovery-expr-type.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -frecovery-ast -frecovery-ast-type -o - %s -std=gnu++17 -fsyntax-only -verify +// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++17 -fsyntax-only -verify +// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++20 -fsyntax-only -verify + namespace test0 { struct Indestructible { @@ -171,3 +173,13 @@ S.m(1); // no crash } } + +namespace test16 { +// verify we do not crash on incomplete class type. +template<typename T, typename U> struct A; // expected-note 5{{template is declared here}} +A<int, int> foo() { // expected-error {{implicit instantiation of undefined template}} + if (1 == 1) + return A<int, int>{1}; // expected-error 2{{implicit instantiation of undefined template}} + return A<int, int>(1); // expected-error 2{{implicit instantiation of undefined template}} +} +} Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -6176,7 +6176,11 @@ // constructors. For example, conversion function. if (const auto *RD = dyn_cast<CXXRecordDecl>(DestType->getAs<RecordType>()->getDecl()); - S.getLangOpts().CPlusPlus20 && RD && RD->isAggregate() && Failed() && + // In general, we should call isCompleteType for RD to check its + // completeness, we don't call it here as it was already called in the + // above TryConstructorInitialization. + S.getLangOpts().CPlusPlus20 && RD && RD->hasDefinition() && + RD->isAggregate() && Failed() && getFailureKind() == FK_ConstructorOverloadFailed) { // C++20 [dcl.init] 17.6.2.2: // - Otherwise, if no constructor is viable, the destination type is
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits