Skip to content

Commit a385808

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 a385808

File tree

5 files changed

+51
-15
lines changed

5 files changed

+51
-15
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 & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -851,13 +851,8 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
851851
const llvm::Triple &T = Context.getTargetInfo().getTriple();
852852
const bool IsOpenMPGPUTarget =
853853
getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN());
854-
// Don't report an error if 'throw' is used in system headers or in an OpenMP
855-
// 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-
}
854+
855+
DiagnoseExceptionUse(OpLoc, /* IsTry= */ false);
861856

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

clang/lib/Sema/SemaStmt.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4302,13 +4302,8 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
43024302
const llvm::Triple &T = Context.getTargetInfo().getTriple();
43034303
const bool IsOpenMPGPUTarget =
43044304
getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN());
4305-
// Don't report an error if 'try' is used in system headers or in an OpenMP
4306-
// 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-
}
4305+
4306+
DiagnoseExceptionUse(TryLoc, /* IsTry= */ true);
43124307

43134308
// In OpenMP target regions, we assume that catch is never reached on GPU
43144309
// targets.
@@ -4410,6 +4405,23 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
44104405
Handlers);
44114406
}
44124407

4408+
void Sema::DiagnoseExceptionUse(SourceLocation Loc, bool IsTry) {
4409+
const llvm::Triple &T = Context.getTargetInfo().getTriple();
4410+
const bool IsOpenMPGPUTarget =
4411+
getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN());
4412+
4413+
// Don't report an error if 'try' is used in system headers or in an OpenMP
4414+
// target region compiled for a GPU architecture.
4415+
if (IsOpenMPGPUTarget || getLangOpts().CUDA)
4416+
// Delay error emission for the OpenMP device code.
4417+
return;
4418+
4419+
if (!getLangOpts().CXXExceptions &&
4420+
!getSourceManager().isInSystemHeader(Loc) &&
4421+
!CurContext->isDependentContext())
4422+
targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ? "try" : "throw");
4423+
}
4424+
44134425
StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc,
44144426
Stmt *TryBlock, Stmt *Handler) {
44154427
assert(TryBlock && Handler);

clang/lib/Sema/TreeTransform.h

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

9165+
getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9166+
91659167
if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
91669168
!HandlerChanged)
91679169
return S;
@@ -14384,6 +14386,8 @@ TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
1438414386
if (SubExpr.isInvalid())
1438514387
return ExprError();
1438614388

14389+
getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
14390+
1438714391
if (!getDerived().AlwaysRebuild() &&
1438814392
SubExpr.get() == E->getSubExpr())
1438914393
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)