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 @@ -7012,6 +7012,8 @@ 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_sizeless : Error< + "cannot catch %select{|reference to }0sizeless type %1">; 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 @@ -15487,6 +15487,11 @@ !BaseType->isDependentType() && RequireCompleteType(Loc, BaseType, DK)) Invalid = true; + if (!Invalid && Mode != 1 && BaseType->isSizelessType()) { + Diag(Loc, diag::err_catch_sizeless) << (Mode == 2 ? 1 : 0) << BaseType; + Invalid = true; + } + if (!Invalid && !ExDeclType->isDependentType() && RequireNonAbstractType(Loc, ExDeclType, diag::err_abstract_type_in_decl, 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 @@ -398,6 +398,19 @@ throw local_int8; // expected-error {{cannot throw object of sizeless type 'svint8_t'}} throw global_int8_ptr; + try { + } catch (int) { + } + try { + } catch (svint8_t) { // expected-error {{cannot catch sizeless type 'svint8_t'}} + } + try { + } catch (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();