[clang] [clang][Sema] Diagnose exceptions only in non-dependent context in discarded `try/catch/throw` blocks (PR #139859)
Rajveer Singh Bharadwaj via cfe-commits
cfe-commits at lists.llvm.org
Sat May 24 04:46:27 PDT 2025
https://github.com/Rajveer100 updated https://github.com/llvm/llvm-project/pull/139859
>From f3201c1089203963f8cb73c58ea498a84848dd88 Mon Sep 17 00:00:00 2001
From: Rajveer <rajveer.developer at 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 | 5 ++---
clang/lib/Sema/SemaStmt.cpp | 13 ++++++++++---
clang/lib/Sema/TreeTransform.h | 14 ++++++++++++++
clang/test/SemaCXX/no-exceptions.cpp | 25 ++++++++++++++++++++++++-
5 files changed, 52 insertions(+), 7 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..5383153728468 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -853,10 +853,9 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
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) {
+ if (!IsOpenMPGPUTarget && !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.
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index e8c1f8490342a..eea50e66484da 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -4304,10 +4304,9 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
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) {
+ if (!IsOpenMPGPUTarget && !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
@@ -4410,6 +4409,14 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
Handlers);
}
+void Sema::DiagnoseExceptionUse(SourceLocation Loc, bool IsTry) {
+ 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..8b663b2c6240b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -9162,6 +9162,13 @@ StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
Handlers.push_back(Handler.getAs<Stmt>());
}
+ const llvm::Triple &T = getSema().Context.getTargetInfo().getTriple();
+ const bool IsOpenMPGPUTarget = getSema().getLangOpts().OpenMPIsTargetDevice &&
+ (T.isNVPTX() || T.isAMDGCN());
+
+ if (!IsOpenMPGPUTarget && !getSema().getLangOpts().CUDA)
+ getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry */ true);
+
if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
!HandlerChanged)
return S;
@@ -14384,6 +14391,13 @@ TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
if (SubExpr.isInvalid())
return ExprError();
+ const llvm::Triple &T = getSema().Context.getTargetInfo().getTriple();
+ const bool IsOpenMPGPUTarget = getSema().getLangOpts().OpenMPIsTargetDevice &&
+ (T.isNVPTX() || T.isAMDGCN());
+
+ if (!IsOpenMPGPUTarget && !getSema().getLangOpts().CUDA)
+ 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}}
}
More information about the cfe-commits
mailing list