Skip to content

Commit 46a9b01

Browse files
committed
[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.
1 parent ddf1249 commit 46a9b01

File tree

4 files changed

+42
-11
lines changed

4 files changed

+42
-11
lines changed

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -853,11 +853,11 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
853853
getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN());
854854
// Don't report an error if 'throw' is used in system headers or in an OpenMP
855855
// target region compiled for a GPU architecture.
856-
if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions &&
857-
!getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) {
858-
// Delay error emission for the OpenMP device code.
859-
targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw";
860-
}
856+
// if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions &&
857+
// !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) {
858+
// // Delay error emission for the OpenMP device code.
859+
// targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw";
860+
// }
861861

862862
// In OpenMP target regions, we replace 'throw' with a trap on GPU targets.
863863
if (IsOpenMPGPUTarget)

clang/lib/Sema/SemaStmt.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4304,11 +4304,12 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
43044304
getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN());
43054305
// Don't report an error if 'try' is used in system headers or in an OpenMP
43064306
// target region compiled for a GPU architecture.
4307-
if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions &&
4308-
!getSourceManager().isInSystemHeader(TryLoc) && !getLangOpts().CUDA) {
4309-
// Delay error emission for the OpenMP device code.
4310-
targetDiag(TryLoc, diag::err_exceptions_disabled) << "try";
4311-
}
4307+
// if (!IsOpenMPGPUTarget && !getLangOpts().CXXExceptions &&
4308+
// !getSourceManager().isInSystemHeader(TryLoc) && !getLangOpts().CUDA &&
4309+
// !CurContext->isDependentContext()) {
4310+
// // Delay error emission for the OpenMP device code.
4311+
// targetDiag(TryLoc, diag::err_exceptions_disabled) << "try";
4312+
// }
43124313

43134314
// In OpenMP target regions, we assume that catch is never reached on GPU
43144315
// targets.

clang/lib/Sema/TreeTransform.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9162,6 +9162,10 @@ StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
91629162
Handlers.push_back(Handler.getAs<Stmt>());
91639163
}
91649164

9165+
if (!getSema().getLangOpts().CXXExceptions &&
9166+
!getSema().getCurContext()->isDependentContext())
9167+
getSema().Diag(S->getTryLoc(), diag::err_exceptions_disabled) << "try";
9168+
91659169
if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
91669170
!HandlerChanged)
91679171
return S;
@@ -14384,6 +14388,9 @@ TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
1438414388
if (SubExpr.isInvalid())
1438514389
return ExprError();
1438614390

14391+
if (!getSema().getLangOpts().CXXExceptions && !E->isInstantiationDependent())
14392+
getSema().Diag(E->getThrowLoc(), diag::err_exceptions_disabled) << "throw";
14393+
1438714394
if (!getDerived().AlwaysRebuild() &&
1438814395
SubExpr.get() == E->getSubExpr())
1438914396
return E;

clang/test/SemaCXX/no-exceptions.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify %s
1+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
22

33
// Various tests for -fno-exceptions
44

@@ -30,5 +30,28 @@ void g() {
3030
} catch (...) {
3131
}
3232
}
33+
}
34+
35+
namespace test2 {
36+
template <auto enable> void foo(auto &&Fnc) {
37+
if constexpr (enable)
38+
try {
39+
Fnc();
40+
} catch (...) {
41+
}
42+
else
43+
Fnc();
44+
}
45+
46+
void bar1() {
47+
foo<false>([] {});
48+
}
3349

50+
template <typename T> void foo() {
51+
try { // expected-error {{cannot use 'try' with exceptions disabled}}
52+
} catch (...) {
53+
}
54+
throw 1; // expected-error {{cannot use 'throw' with exceptions disabled}}
55+
}
56+
void bar2() { foo<int>(); } // expected-note {{in instantiation of function template specialization 'test2::foo<int>' requested here}}
3457
}

0 commit comments

Comments
 (0)