https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/139859
>From a385808a47e3a7b585a225b9fbf10c55ba01ef5b Mon Sep 17 00:00:00 2001 From: Rajveer <rajveer.develo...@icloud.com> Date: Wed, 14 May 2025 13:44:31 +0530 Subject: [PATCH] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks Resolves #138939 When enabling `--fno-exceptions` flag, discarded statements containing `try/catch/throw` in an independent context can be avoided from being rejected. --- clang/include/clang/Sema/Sema.h | 2 ++ clang/lib/Sema/SemaExprCXX.cpp | 9 ++------- clang/lib/Sema/SemaStmt.cpp | 26 +++++++++++++++++++------- clang/lib/Sema/TreeTransform.h | 4 ++++ clang/test/SemaCXX/no-exceptions.cpp | 25 ++++++++++++++++++++++++- 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 6ea7ee281e14d..ebb40498e11aa 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11154,6 +11154,8 @@ class Sema final : public SemaBase { StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef<Stmt *> Handlers); + void DiagnoseExceptionUse(SourceLocation Loc, bool IsTry); + StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index b2a982e953012..cc75371a82ec5 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -851,13 +851,8 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, const llvm::Triple &T = Context.getTargetInfo().getTriple(); const bool IsOpenMPGPUTarget = getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()); - // Don't report an error if 'throw' is used in system headers or in an OpenMP - // target region compiled for a GPU architecture. - if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions && - !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) { - // Delay error emission for the OpenMP device code. - targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw"; - } + + DiagnoseExceptionUse(OpLoc, /* IsTry= */ false); // In OpenMP target regions, we replace 'throw' with a trap on GPU targets. if (IsOpenMPGPUTarget) diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index e8c1f8490342a..d882b04202caf 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -4302,13 +4302,8 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, const llvm::Triple &T = Context.getTargetInfo().getTriple(); const bool IsOpenMPGPUTarget = getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()); - // Don't report an error if 'try' is used in system headers or in an OpenMP - // target region compiled for a GPU architecture. - if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions && - !getSourceManager().isInSystemHeader(TryLoc) && !getLangOpts().CUDA) { - // Delay error emission for the OpenMP device code. - targetDiag(TryLoc, diag::err_exceptions_disabled) << "try"; - } + + DiagnoseExceptionUse(TryLoc, /* IsTry= */ true); // In OpenMP target regions, we assume that catch is never reached on GPU // targets. @@ -4410,6 +4405,23 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, Handlers); } +void Sema::DiagnoseExceptionUse(SourceLocation Loc, bool IsTry) { + const llvm::Triple &T = Context.getTargetInfo().getTriple(); + const bool IsOpenMPGPUTarget = + getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()); + + // Don't report an error if 'try' is used in system headers or in an OpenMP + // target region compiled for a GPU architecture. + if (IsOpenMPGPUTarget || getLangOpts().CUDA) + // Delay error emission for the OpenMP device code. + return; + + if (!getLangOpts().CXXExceptions && + !getSourceManager().isInSystemHeader(Loc) && + !CurContext->isDependentContext()) + targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ? "try" : "throw"); +} + StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler) { assert(TryBlock && Handler); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 335e21d927b76..b8ee3fedd6812 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -9162,6 +9162,8 @@ StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) { Handlers.push_back(Handler.getAs<Stmt>()); } + getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true); + if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && !HandlerChanged) return S; @@ -14384,6 +14386,8 @@ TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) { if (SubExpr.isInvalid()) return ExprError(); + getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false); + if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr()) return E; diff --git a/clang/test/SemaCXX/no-exceptions.cpp b/clang/test/SemaCXX/no-exceptions.cpp index 097123d3fe523..e8ac8a657ab84 100644 --- a/clang/test/SemaCXX/no-exceptions.cpp +++ b/clang/test/SemaCXX/no-exceptions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s // Various tests for -fno-exceptions @@ -30,5 +30,28 @@ void g() { } catch (...) { } } +} + +namespace test2 { +template <auto enable> void foo(auto &&Fnc) { + if constexpr (enable) + try { + Fnc(); + } catch (...) { + } + else + Fnc(); +} + +void bar1() { + foo<false>([] {}); +} +template <typename T> void foo() { + try { // expected-error {{cannot use 'try' with exceptions disabled}} + } catch (...) { + } + throw 1; // expected-error {{cannot use 'throw' with exceptions disabled}} +} +void bar2() { foo<int>(); } // expected-note {{in instantiation of function template specialization 'test2::foo<int>' requested here}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits