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 @@ -1537,6 +1537,9 @@ def err_incomplete_in_exception_spec : Error< "%select{|pointer to |reference to }0incomplete type %1 is not allowed " "in exception specification">; +def err_sizeless_in_exception_spec : Error< + "%select{|reference to }0sizeless type %1 is not allowed " + "in exception specification">; def ext_incomplete_in_exception_spec : ExtWarn, InGroup; def err_rref_in_exception_spec : Error< diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -167,6 +167,14 @@ RequireCompleteType(Range.getBegin(), PointeeT, DiagID, Kind, Range)) return ReturnValueOnError; + // The MSVC compatibility mode doesn't extend to sizeless types, + // so diagnose them separately. + if (PointeeT->isSizelessType() && Kind != 1) { + Diag(Range.getBegin(), diag::err_sizeless_in_exception_spec) + << (Kind == 2 ? 1 : 0) << PointeeT << Range; + return true; + } + return false; } 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 @@ -345,6 +345,12 @@ constexpr int ce_taking_int8(svint8_t) { return 1; } // expected-error {{constexpr function's 1st parameter type 'svint8_t' (aka '__SVInt8_t') is not a literal type}} #endif +#if __cplusplus < 201703L +void throwing_func() throw(svint8_t); // expected-error {{sizeless type 'svint8_t' (aka '__SVInt8_t') is not allowed in exception specification}} +void throwing_pointer_func() throw(svint8_t *); +void throwing_reference_func() throw(svint8_t &); // expected-error {{reference to sizeless type 'svint8_t' (aka '__SVInt8_t') is not allowed in exception specification}} +#endif + template void template_fn_direct(T) {} template