diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index fd0b6d9096f50..107360ff0b80c 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -529,6 +529,9 @@ ENUM_CODEGENOPT(WinControlFlowGuardMechanism, ControlFlowGuardMechanism, /// Adds attributes that prevent outlining (`-mno-outline`) CODEGENOPT(DisableOutlining, 1, 0, Benign) +/// Forces backend to emit trap instruction for LLVM IR unreachable +CODEGENOPT(ForceTrapUnreachable, 1, 0, Benign) + /// FIXME: Make DebugOptions its own top-level .def file. #include "DebugOptions.def" diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 5eeabf4c33b76..1973eba313ca7 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -4804,6 +4804,11 @@ defm virtual_function_elimination : BoolFOption<"virtual-function-elimination", "Enables dead virtual function elimination optimization. Requires -flto=full">, NegFlag, BothFlags<[], [ClangOption, CLOption]>>; +def ftrap_unreachable : Flag<["-"], "ftrap-unreachable">, + Group, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Force emission of a trap instruction at the end of noreturn functions">, + MarshallingInfoFlag>; def fwrapv : Flag<["-"], "fwrapv">, Group, Visibility<[ClangOption, CLOption, CC1Option, FlangOption, FC1Option]>, HelpText<"Treat signed integer overflow as two's complement">; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index a46a25c4492f2..7bcbce4cb48cb 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -477,6 +477,9 @@ static bool initTargetOptions(const CompilerInstance &CI, Options.VecLib = convertDriverVectorLibraryToVectorLibrary(CodeGenOpts.getVecLib()); + if (CodeGenOpts.ForceTrapUnreachable) + Options.TrapUnreachable = true; + switch (CodeGenOpts.getSwiftAsyncFramePointer()) { case CodeGenOptions::SwiftAsyncFramePointerKind::Auto: Options.SwiftAsyncFramePointer = diff --git a/clang/test/CodeGen/trap-unreachable.c b/clang/test/CodeGen/trap-unreachable.c new file mode 100644 index 0000000000000..deaa8a42ac48a --- /dev/null +++ b/clang/test/CodeGen/trap-unreachable.c @@ -0,0 +1,13 @@ +// REQUIRES: x86-registered-target +// RUN: %clang_cc1 -ftrap-unreachable -fms-extensions -triple x86_64-windows-msvc -O2 -S %s -o - | FileCheck %s + +// CHECK-LABEL: my_noreturn_func: +// CHECK: movl $0, (%rax) +// CHECK-NEXT: ud2 + +extern long volatile *gtrap; + +__declspec(noreturn) void my_noreturn_func(void) { + *gtrap = 0; +} +