// 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
-// 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 {
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}}
+}
+}