Skip to content

Commit f3201c1

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 f3201c1

File tree

5 files changed

+52
-7
lines changed

5 files changed

+52
-7
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11154,6 +11154,8 @@ class Sema final : public SemaBase {
1115411154
StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
1115511155
ArrayRef<Stmt *> Handlers);
1115611156

11157+
void DiagnoseExceptionUse(SourceLocation Loc, bool IsTry);
11158+
1115711159
StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ?
1115811160
SourceLocation TryLoc, Stmt *TryBlock,
1115911161
Stmt *Handler);

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -853,10 +853,9 @@ 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) {
856+
if (!IsOpenMPGPUTarget && !getLangOpts().CUDA) {
858857
// Delay error emission for the OpenMP device code.
859-
targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw";
858+
DiagnoseExceptionUse(OpLoc, /* IsTry */ false);
860859
}
861860

862861
// In OpenMP target regions, we replace 'throw' with a trap on GPU targets.

clang/lib/Sema/SemaStmt.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4304,10 +4304,9 @@ 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) {
4307+
if (!IsOpenMPGPUTarget && !getLangOpts().CUDA) {
43094308
// Delay error emission for the OpenMP device code.
4310-
targetDiag(TryLoc, diag::err_exceptions_disabled) << "try";
4309+
DiagnoseExceptionUse(TryLoc, /* IsTry */ true);
43114310
}
43124311

43134312
// In OpenMP target regions, we assume that catch is never reached on GPU
@@ -4410,6 +4409,14 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
44104409
Handlers);
44114410
}
44124411

4412+
void Sema::DiagnoseExceptionUse(SourceLocation Loc, bool IsTry) {
4413+
if (!getLangOpts().CXXExceptions &&
4414+
!getSourceManager().isInSystemHeader(Loc) &&
4415+
!CurContext->isDependentContext()) {
4416+
targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ? "try" : "throw");
4417+
}
4418+
}
4419+
44134420
StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc,
44144421
Stmt *TryBlock, Stmt *Handler) {
44154422
assert(TryBlock && Handler);

clang/lib/Sema/TreeTransform.h

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

9165+
const llvm::Triple &T = getSema().Context.getTargetInfo().getTriple();
9166+
const bool IsOpenMPGPUTarget = getSema().getLangOpts().OpenMPIsTargetDevice &&
9167+
(T.isNVPTX() || T.isAMDGCN());
9168+
9169+
if (!IsOpenMPGPUTarget && !getSema().getLangOpts().CUDA)
9170+
getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry */ true);
9171+
91659172
if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
91669173
!HandlerChanged)
91679174
return S;
@@ -14384,6 +14391,13 @@ TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
1438414391
if (SubExpr.isInvalid())
1438514392
return ExprError();
1438614393

14394+
const llvm::Triple &T = getSema().Context.getTargetInfo().getTriple();
14395+
const bool IsOpenMPGPUTarget = getSema().getLangOpts().OpenMPIsTargetDevice &&
14396+
(T.isNVPTX() || T.isAMDGCN());
14397+
14398+
if (!IsOpenMPGPUTarget && !getSema().getLangOpts().CUDA)
14399+
getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry */ false);
14400+
1438714401
if (!getDerived().AlwaysRebuild() &&
1438814402
SubExpr.get() == E->getSubExpr())
1438914403
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)