rsandifo-arm created this revision. rsandifo-arm added reviewers: sdesmalen, efriedma, rovka, rjmccall. Herald added subscribers: cfe-commits, psnobl, rkruppe, tschuett. Herald added a project: clang. rsandifo-arm added a parent revision: D76088: [Sema][SVE] Don't allow sizeless objects to be thrown.
The same rules for throwing and catching incomplete types also apply to sizeless types. This patch enforces that for try-catch statements. It also makes sure that we use "sizeless type" rather "incomplete type" in the associated message. (Both are correct, but "sizeless type" is more specific and hopefully more user-friendly.) Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D76090 Files: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaDeclCXX.cpp clang/test/SemaCXX/sizeless-1.cpp Index: clang/test/SemaCXX/sizeless-1.cpp =================================================================== --- clang/test/SemaCXX/sizeless-1.cpp +++ 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(); Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ 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<PointerType>()) { BaseType = Ptr->getPointeeType(); Mode = 1; - DK = diag::err_catch_incomplete_ptr; } else if (const ReferenceType *Ref = BaseType->getAs<ReferenceType>()) { // 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() && Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7007,11 +7007,9 @@ "volatile qualifier in structured binding declaration is deprecated">, InGroup<DeprecatedVolatile>; -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">;
Index: clang/test/SemaCXX/sizeless-1.cpp =================================================================== --- clang/test/SemaCXX/sizeless-1.cpp +++ 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(); Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ 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<PointerType>()) { BaseType = Ptr->getPointeeType(); Mode = 1; - DK = diag::err_catch_incomplete_ptr; } else if (const ReferenceType *Ref = BaseType->getAs<ReferenceType>()) { // 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() && Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7007,11 +7007,9 @@ "volatile qualifier in structured binding declaration is deprecated">, InGroup<DeprecatedVolatile>; -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">;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits