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 @@ -7120,6 +7120,8 @@ "cannot throw object of incomplete type %0">; def err_throw_incomplete_ptr : Error< "cannot throw pointer to object of incomplete type %0">; +def err_throw_sizeless : Error< + "cannot throw object of sizeless type %0">; def warn_throw_underaligned_obj : Warning< "underaligned exception object thrown">, InGroup; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -956,6 +956,11 @@ E->getSourceRange())) return true; + if (!isPointer && Ty->isSizelessType()) { + Diag(ThrowLoc, diag::err_throw_sizeless) << Ty << E->getSourceRange(); + return true; + } + if (RequireNonAbstractType(ThrowLoc, ExceptionObjectTy, diag::err_throw_abstract_type, E)) return true; 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 @@ -395,6 +395,9 @@ local_int16 = static_cast(local_int8); // expected-error {{static_cast from 'svint8_t' (aka '__SVInt8_t') to 'svint16_t' (aka '__SVInt16_t') is not allowed}} sel = static_cast(local_int8); // expected-error {{static_cast from 'svint8_t' (aka '__SVInt8_t') to 'int' is not allowed}} + throw local_int8; // expected-error {{cannot throw object of sizeless type 'svint8_t'}} + throw global_int8_ptr; + 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();