Skip to content

Commit

Permalink
[SEH] Ignore async exception flag when the environment is not MSVC (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
phoebewang committed Apr 16, 2024
1 parent a831c54 commit b0194d2
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
28 changes: 20 additions & 8 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,14 @@ static bool addExceptionArgs(const ArgList &Args, types::ID InputType,
bool EH = Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
false);

bool EHa = Args.hasFlag(options::OPT_fasync_exceptions,
options::OPT_fno_async_exceptions, false);
if (EHa) {
CmdArgs.push_back("-fasync-exceptions");
EH = true;
// Async exceptions are Windows MSVC only.
if (Triple.isWindowsMSVCEnvironment()) {
bool EHa = Args.hasFlag(options::OPT_fasync_exceptions,
options::OPT_fno_async_exceptions, false);
if (EHa) {
CmdArgs.push_back("-fasync-exceptions");
EH = true;
}
}

// Obj-C exceptions are enabled by default, regardless of -fexceptions. This
Expand Down Expand Up @@ -8102,7 +8105,8 @@ struct EHFlags {
/// The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
/// - c: Assume that extern "C" functions are implicitly nounwind.
/// The default is /EHs-c-, meaning cleanups are disabled.
static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args,
bool isWindowsMSVC) {
EHFlags EH;

std::vector<std::string> EHArgs =
Expand All @@ -8112,8 +8116,15 @@ static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
switch (EHVal[I]) {
case 'a':
EH.Asynch = maybeConsumeDash(EHVal, I);
if (EH.Asynch)
if (EH.Asynch) {
// Async exceptions are Windows MSVC only.
if (!isWindowsMSVC) {
EH.Asynch = false;
D.Diag(clang::diag::warn_drv_unused_argument) << "/EHa" << EHVal;
continue;
}
EH.Synch = false;
}
continue;
case 'c':
EH.NoUnwindC = maybeConsumeDash(EHVal, I);
Expand Down Expand Up @@ -8177,7 +8188,8 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,

const Driver &D = getToolChain().getDriver();

EHFlags EH = parseClangCLEHFlags(D, Args);
bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
EHFlags EH = parseClangCLEHFlags(D, Args, IsWindowsMSVC);
if (!isNVPTX && (EH.Synch || EH.Asynch)) {
if (types::isCXX(InputType))
CmdArgs.push_back("-fcxx-exceptions");
Expand Down
24 changes: 24 additions & 0 deletions clang/test/Driver/windows-seh-async-verify.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// RUN: %clang --target=x86_64-pc-windows -fasync-exceptions -fsyntax-only %s -### 2>&1 | FileCheck %s
// RUN: %clang_cl --target=x86_64-pc-windows /EHa -fsyntax-only %s -### 2>&1 | FileCheck %s
// RUN: %clang --target=x86_64-pc-windows-gnu -fasync-exceptions -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefixes=GNU-ALL,GNU
// RUN: %clang_cl --target=x86_64-pc-windows-gnu /EHa -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefixes=GNU-ALL,CL-GNU

// CHECK-NOT: warning
// GNU: warning: argument unused during compilation: '-fasync-exceptions' [-Wunused-command-line-argument]
// CL-GNU: warning: argument unused during compilation: '/EHa' [-Wunused-command-line-argument]

// CHECK: -fasync-exceptions
// GNU-ALL-NOT: -fasync-exceptions
struct S {
union _Un {
~_Un() {}
char _Buf[12];
};
_Un _un;
};

struct Embed {
S v2;
};

void PR62449() { Embed v{}; }

0 comments on commit b0194d2

Please sign in to comment.