diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7007,11 +7007,9 @@ "volatile qualifier in structured binding declaration is deprecated">, InGroup; -def err_catch_incomplete_ptr : Error< - "cannot catch pointer to incomplete type %0">; -def err_catch_incomplete_ref : Error< - "cannot catch reference to incomplete type %0">; -def err_catch_incomplete : Error<"cannot catch incomplete type %0">; +def err_catch_incomplete_or_sizeless : Error< + "cannot catch %select{|pointer to |reference to }0" + "%select{incomplete|sizeless}1 type %2">; def err_catch_rvalue_ref : Error<"cannot catch exceptions by rvalue reference">; def err_catch_variably_modified : Error< "cannot catch variably modified type %0">; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -15472,19 +15472,18 @@ QualType BaseType = ExDeclType; int Mode = 0; // 0 for direct type, 1 for pointer, 2 for reference - unsigned DK = diag::err_catch_incomplete; if (const PointerType *Ptr = BaseType->getAs()) { BaseType = Ptr->getPointeeType(); Mode = 1; - DK = diag::err_catch_incomplete_ptr; } else if (const ReferenceType *Ref = BaseType->getAs()) { // For the purpose of error recovery, we treat rvalue refs like lvalue refs. BaseType = Ref->getPointeeType(); Mode = 2; - DK = diag::err_catch_incomplete_ref; } if (!Invalid && (Mode == 0 || !BaseType->isVoidType()) && - !BaseType->isDependentType() && RequireCompleteType(Loc, BaseType, DK)) + !BaseType->isDependentType() && + RequireCompleteSizedType(Loc, BaseType, + diag::err_catch_incomplete_or_sizeless, Mode)) Invalid = true; if (!Invalid && !ExDeclType->isDependentType() && diff --git a/clang/test/SemaCXX/sizeless-1.cpp b/clang/test/SemaCXX/sizeless-1.cpp --- a/clang/test/SemaCXX/sizeless-1.cpp +++ b/clang/test/SemaCXX/sizeless-1.cpp @@ -399,6 +399,19 @@ throw local_int8; // expected-error {{cannot throw object of sizeless type 'svint8_t'}} throw global_int8_ptr; // expected-error {{cannot throw pointer to object of sizeless type 'svint8_t'}} + try { + } catch (int) { + } + try { + } catch (svint8_t) { // expected-error {{cannot catch sizeless type 'svint8_t'}} + } + try { + } catch (svint8_t *) { // expected-error {{cannot catch pointer to sizeless type 'svint8_t'}} + } + try { + } catch (svint8_t &) { // expected-error {{cannot catch reference to sizeless type 'svint8_t'}} + } + local_int8.~__SVInt8_t(); // expected-error {{object expression of non-scalar type 'svint8_t' (aka '__SVInt8_t') cannot be used in a pseudo-destructor expression}} (void)svint8_t();