https://github.com/Rajveer100 updated 
https://github.com/llvm/llvm-project/pull/139859

>From 46a9b0193bb5bdb9a082582f19e7a32ac2a3973d 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/lib/Sema/SemaExprCXX.cpp       | 10 +++++-----
 clang/lib/Sema/SemaStmt.cpp          | 11 ++++++-----
 clang/lib/Sema/TreeTransform.h       |  7 +++++++
 clang/test/SemaCXX/no-exceptions.cpp | 25 ++++++++++++++++++++++++-
 4 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index b2a982e953012..275754ad54068 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -853,11 +853,11 @@ 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) {
-    // Delay error emission for the OpenMP device code.
-    targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw";
-  }
+  // if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions &&
+  //     !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) {
+  //   // Delay error emission for the OpenMP device code.
+  //   targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw";
+  // }
 
   // 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..9be264160f984 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -4304,11 +4304,12 @@ 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) {
-    // Delay error emission for the OpenMP device code.
-    targetDiag(TryLoc, diag::err_exceptions_disabled) << "try";
-  }
+  // if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions &&
+  //     !getSourceManager().isInSystemHeader(TryLoc) && !getLangOpts().CUDA &&
+  //     !CurContext->isDependentContext()) {
+  //   // Delay error emission for the OpenMP device code.
+  //   targetDiag(TryLoc, diag::err_exceptions_disabled) << "try";
+  // }
 
   // In OpenMP target regions, we assume that catch is never reached on GPU
   // targets.
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 335e21d927b76..1f46f530691c5 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -9162,6 +9162,10 @@ StmtResult 
TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
     Handlers.push_back(Handler.getAs<Stmt>());
   }
 
+  if (!getSema().getLangOpts().CXXExceptions &&
+      !getSema().getCurContext()->isDependentContext())
+    getSema().Diag(S->getTryLoc(), diag::err_exceptions_disabled) << "try";
+
   if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
       !HandlerChanged)
     return S;
@@ -14384,6 +14388,9 @@ 
TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
   if (SubExpr.isInvalid())
     return ExprError();
 
+  if (!getSema().getLangOpts().CXXExceptions && !E->isInstantiationDependent())
+    getSema().Diag(E->getThrowLoc(), diag::err_exceptions_disabled) << "throw";
+
   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

Reply via email to