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 @@ -7113,10 +7113,9 @@ : Error<"vector operands to the vector conditional must be the same type " "%diff{($ and $)|}0,1}">; -def err_throw_incomplete : Error< - "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_incomplete_or_sizeless : Error< + "cannot throw %select{|pointer to }0object of %select{incomplete|sizeless}1 " + "type %2">; 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 @@ -950,10 +950,9 @@ isPointer = true; } if (!isPointer || !Ty->isVoidType()) { - if (RequireCompleteType(ThrowLoc, Ty, - isPointer ? diag::err_throw_incomplete_ptr - : diag::err_throw_incomplete, - E->getSourceRange())) + if (RequireCompleteSizedType(ThrowLoc, Ty, + diag::err_throw_incomplete_or_sizeless, + isPointer, E->getSourceRange())) return true; if (RequireNonAbstractType(ThrowLoc, ExceptionObjectTy, 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,10 @@ 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 1; + 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'}} + 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();