Skip to content

Commit 6846e3b

Browse files
committed
Merge commit 'ffff7bb582a3' from llvm.org/main into next
2 parents 195c739 + ffff7bb commit 6846e3b

File tree

10 files changed

+622
-49
lines changed

10 files changed

+622
-49
lines changed

clang/include/clang/Basic/CodeGenOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
382382
/// Set of sanitizer checks that trap rather than diagnose.
383383
SanitizerSet SanitizeTrap;
384384

385+
/// Set of sanitizer checks that can merge handlers (smaller code size at
386+
/// the expense of debuggability).
387+
SanitizerSet SanitizeMergeHandlers;
388+
385389
/// List of backend command-line options for -fembed-bitcode.
386390
std::vector<uint8_t> CmdArgs;
387391

clang/include/clang/Driver/Options.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2657,6 +2657,21 @@ def fno_sanitize_trap : Flag<["-"], "fno-sanitize-trap">, Group<f_clang_Group>,
26572657
Alias<fno_sanitize_trap_EQ>, AliasArgs<["all"]>,
26582658
Visibility<[ClangOption, CLOption]>,
26592659
HelpText<"Disable trapping for all sanitizers">;
2660+
def fsanitize_merge_handlers_EQ
2661+
: CommaJoined<["-"], "fsanitize-merge=">,
2662+
Group<f_clang_Group>,
2663+
HelpText<"Allow compiler to merge handlers for specified sanitizers">;
2664+
def fno_sanitize_merge_handlers_EQ
2665+
: CommaJoined<["-"], "fno-sanitize-merge=">,
2666+
Group<f_clang_Group>,
2667+
HelpText<"Do not allow compiler to merge handlers for specified sanitizers">;
2668+
def fsanitize_merge_handlers : Flag<["-"], "fsanitize-merge">, Group<f_clang_Group>,
2669+
Alias<fsanitize_merge_handlers_EQ>, AliasArgs<["all"]>,
2670+
HelpText<"Allow compiler to merge handlers for all sanitizers">;
2671+
def fno_sanitize_merge_handlers : Flag<["-"], "fno-sanitize-merge">, Group<f_clang_Group>,
2672+
Alias<fno_sanitize_merge_handlers_EQ>, AliasArgs<["all"]>,
2673+
Visibility<[ClangOption, CLOption]>,
2674+
HelpText<"Do not allow compiler to merge handlers for any sanitizers">;
26602675
def fsanitize_undefined_trap_on_error
26612676
: Flag<["-"], "fsanitize-undefined-trap-on-error">, Group<f_clang_Group>,
26622677
Alias<fsanitize_trap_EQ>, AliasArgs<["undefined"]>;

clang/include/clang/Driver/SanitizerArgs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class SanitizerArgs {
2525
SanitizerSet Sanitizers;
2626
SanitizerSet RecoverableSanitizers;
2727
SanitizerSet TrapSanitizers;
28+
SanitizerSet MergeHandlers;
2829

2930
std::vector<std::string> UserIgnorelistFiles;
3031
std::vector<std::string> SystemIgnorelistFiles;

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4067,7 +4067,7 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
40674067
ArrayRef<llvm::Value *> FnArgs,
40684068
SanitizerHandler CheckHandler,
40694069
CheckRecoverableKind RecoverKind, bool IsFatal,
4070-
llvm::BasicBlock *ContBB) {
4070+
llvm::BasicBlock *ContBB, bool NoMerge) {
40714071
assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
40724072
std::optional<ApplyDebugLocation> DL;
40734073
if (!CGF.Builder.getCurrentDebugLocation()) {
@@ -4102,10 +4102,9 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
41024102
llvm::AttributeList::FunctionIndex, B),
41034103
/*Local=*/true);
41044104
llvm::CallInst *HandlerCall = CGF.EmitNounwindRuntimeCall(Fn, FnArgs);
4105-
bool NoMerge =
4106-
ClSanitizeDebugDeoptimization ||
4107-
!CGF.CGM.getCodeGenOpts().OptimizationLevel ||
4108-
(CGF.CurCodeDecl && CGF.CurCodeDecl->hasAttr<OptimizeNoneAttr>());
4105+
NoMerge = NoMerge || ClSanitizeDebugDeoptimization ||
4106+
!CGF.CGM.getCodeGenOpts().OptimizationLevel ||
4107+
(CGF.CurCodeDecl && CGF.CurCodeDecl->hasAttr<OptimizeNoneAttr>());
41094108
if (NoMerge)
41104109
HandlerCall->addFnAttr(llvm::Attribute::NoMerge);
41114110
if (!MayReturn) {
@@ -4129,6 +4128,7 @@ void CodeGenFunction::EmitCheck(
41294128
llvm::Value *FatalCond = nullptr;
41304129
llvm::Value *RecoverableCond = nullptr;
41314130
llvm::Value *TrapCond = nullptr;
4131+
bool NoMerge = false;
41324132
for (int i = 0, n = Checked.size(); i < n; ++i) {
41334133
llvm::Value *Check = Checked[i].first;
41344134
// -fsanitize-trap= overrides -fsanitize-recover=.
@@ -4139,6 +4139,9 @@ void CodeGenFunction::EmitCheck(
41394139
? RecoverableCond
41404140
: FatalCond;
41414141
Cond = Cond ? Builder.CreateAnd(Cond, Check) : Check;
4142+
4143+
if (!CGM.getCodeGenOpts().SanitizeMergeHandlers.has(Checked[i].second))
4144+
NoMerge = true;
41424145
}
41434146

41444147
if (ClSanitizeGuardChecks) {
@@ -4153,7 +4156,7 @@ void CodeGenFunction::EmitCheck(
41534156
}
41544157

41554158
if (TrapCond)
4156-
EmitTrapCheck(TrapCond, CheckHandler);
4159+
EmitTrapCheck(TrapCond, CheckHandler, NoMerge);
41574160
if (!FatalCond && !RecoverableCond)
41584161
return;
41594162

@@ -4219,7 +4222,7 @@ void CodeGenFunction::EmitCheck(
42194222
// Simple case: we need to generate a single handler call, either
42204223
// fatal, or non-fatal.
42214224
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind,
4222-
(FatalCond != nullptr), Cont);
4225+
(FatalCond != nullptr), Cont, NoMerge);
42234226
} else {
42244227
// Emit two handler calls: first one for set of unrecoverable checks,
42254228
// another one for recoverable.
@@ -4229,10 +4232,10 @@ void CodeGenFunction::EmitCheck(
42294232
Builder.CreateCondBr(FatalCond, NonFatalHandlerBB, FatalHandlerBB);
42304233
EmitBlock(FatalHandlerBB);
42314234
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, true,
4232-
NonFatalHandlerBB);
4235+
NonFatalHandlerBB, NoMerge);
42334236
EmitBlock(NonFatalHandlerBB);
42344237
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, false,
4235-
Cont);
4238+
Cont, NoMerge);
42364239
}
42374240

42384241
EmitBlock(Cont);
@@ -4423,6 +4426,7 @@ void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
44234426

44244427
void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
44254428
SanitizerHandler CheckHandlerID,
4429+
bool NoMerge,
44264430
/*TO_UPSTREAM(BoundsSafety) ON*/
44274431
StringRef Annotation,
44284432
StringRef TrapMessage) {
@@ -4444,9 +4448,9 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
44444448
}
44454449
/*TO_UPSTREAM(BoundsSafety) OFF*/
44464450

4447-
bool NoMerge = ClSanitizeDebugDeoptimization ||
4448-
!CGM.getCodeGenOpts().OptimizationLevel ||
4449-
(CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>());
4451+
NoMerge = NoMerge || ClSanitizeDebugDeoptimization ||
4452+
!CGM.getCodeGenOpts().OptimizationLevel ||
4453+
(CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>());
44504454

44514455
/*TO_UPSTREAM(BoundsSafety) ON*/
44524456
NoMerge |= CGM.getCodeGenOpts().TrapFuncReturns;

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5316,6 +5316,7 @@ class CodeGenFunction : public CodeGenTypeCache {
53165316
/// Create a basic block that will call the trap intrinsic, and emit a
53175317
/// conditional branch to it, for the -ftrapv checks.
53185318
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID,
5319+
bool NoMerge = false,
53195320
StringRef Annotation = "", StringRef TrapMessage = "");
53205321

53215322
/* TO_UPSTREAM(BoundsSafety) ON*/

clang/lib/Driver/SanitizerArgs.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ static const SanitizerMask TrappingSupported =
6868
SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
6969
SanitizerKind::LocalBounds | SanitizerKind::CFI |
7070
SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
71+
static const SanitizerMask MergeDefault = SanitizerKind::Undefined;
7172
static const SanitizerMask TrappingDefault = SanitizerKind::CFI;
7273
static const SanitizerMask CFIClasses =
7374
SanitizerKind::CFIVCall | SanitizerKind::CFINVCall |
@@ -699,6 +700,13 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
699700
TrappingKinds &= Kinds;
700701
RecoverableKinds &= ~TrappingKinds;
701702

703+
// Parse -f(no-)?sanitize-nonmerged-handlers flags
704+
SanitizerMask MergeKinds =
705+
parseSanitizeArgs(D, Args, DiagnoseErrors, MergeDefault, {}, {},
706+
options::OPT_fsanitize_merge_handlers_EQ,
707+
options::OPT_fno_sanitize_merge_handlers_EQ);
708+
MergeKinds &= Kinds;
709+
702710
// Setup ignorelist files.
703711
// Add default ignorelist from resource directory for activated sanitizers,
704712
// and validate special case lists format.
@@ -1116,6 +1124,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
11161124
TrapSanitizers.Mask |= TrappingKinds;
11171125
assert(!(RecoverableKinds & TrappingKinds) &&
11181126
"Overlap between recoverable and trapping sanitizers");
1127+
1128+
MergeHandlers.Mask |= MergeKinds;
11191129
}
11201130

11211131
static std::string toString(const clang::SanitizerSet &Sanitizers) {
@@ -1277,6 +1287,10 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
12771287
CmdArgs.push_back(
12781288
Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers)));
12791289

1290+
if (!MergeHandlers.empty())
1291+
CmdArgs.push_back(
1292+
Args.MakeArgString("-fsanitize-merge=" + toString(MergeHandlers)));
1293+
12801294
addSpecialCaseListOpt(Args, CmdArgs,
12811295
"-fsanitize-ignorelist=", UserIgnorelistFiles);
12821296
addSpecialCaseListOpt(Args, CmdArgs,
@@ -1444,13 +1458,16 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
14441458

14451459
SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
14461460
bool DiagnoseErrors) {
1447-
assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
1448-
A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
1449-
A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
1450-
A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
1451-
A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
1452-
A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
1453-
"Invalid argument in parseArgValues!");
1461+
assert(
1462+
(A->getOption().matches(options::OPT_fsanitize_EQ) ||
1463+
A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
1464+
A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
1465+
A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
1466+
A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
1467+
A->getOption().matches(options::OPT_fno_sanitize_trap_EQ) ||
1468+
A->getOption().matches(options::OPT_fsanitize_merge_handlers_EQ) ||
1469+
A->getOption().matches(options::OPT_fno_sanitize_merge_handlers_EQ)) &&
1470+
"Invalid argument in parseArgValues!");
14541471
SanitizerMask Kinds;
14551472
for (int i = 0, n = A->getNumValues(); i != n; ++i) {
14561473
const char *Value = A->getValue(i);

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1988,6 +1988,10 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
19881988
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeTrap))
19891989
GenerateArg(Consumer, OPT_fsanitize_trap_EQ, Sanitizer);
19901990

1991+
for (StringRef Sanitizer :
1992+
serializeSanitizerKinds(Opts.SanitizeMergeHandlers))
1993+
GenerateArg(Consumer, OPT_fsanitize_merge_handlers_EQ, Sanitizer);
1994+
19911995
if (!Opts.EmitVersionIdentMetadata)
19921996
GenerateArg(Consumer, OPT_Qn);
19931997

@@ -2477,6 +2481,9 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
24772481
parseSanitizerKinds("-fsanitize-trap=",
24782482
Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
24792483
Opts.SanitizeTrap);
2484+
parseSanitizerKinds("-fsanitize-merge=",
2485+
Args.getAllArgValues(OPT_fsanitize_merge_handlers_EQ),
2486+
Diags, Opts.SanitizeMergeHandlers);
24802487

24812488
Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
24822489

clang/test/CodeGen/ubsan-trap-debugloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow %s -o - -debug-info-kind=line-tables-only | FileCheck %s
1+
// RUN: %clang_cc1 -emit-llvm -disable-llvm-passes -O -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -fsanitize-merge=signed-integer-overflow %s -o - -debug-info-kind=line-tables-only | FileCheck %s
22

33

44
void foo(volatile int a) {

0 commit comments

Comments
 (0)