Skip to content

Commit 71789b9

Browse files
committed
[BoundsSafety] Support arbitrary check groups for the -fbounds-safety-bringup-missing-checks= flag
Currently we have the `-fbounds-safety-bringup-missing-checks=` flag which allows switching on new bounds checks. This flag has a special `all` value that means switch on all the checks. However `all` isn't sufficient because we may have `-fbounds-safety` adopters using the `-fbounds-safety-bringup-missing-checks` flag (enables `all` checks) already but we want to introduce new bounds checks that don't get enabled automatically. This patch solves this problem by introducing support for arbitrary groups of checks. This is implemented by the `LangOptionsBase::getBoundsSafetyNewChecksMaskForGroup` function which takes a group name and returns a bit mask of the checks that should be enabled for the group. This patch introduces the `batch_0` group. It is currently the same as `all` but as we introduce support of more bounds checks `batch_0` will contain the same set of checks, but `all` will change over time to include any new checks we implement. This means an adopter of `-fbounds-safety` can provide the `-fbounds-safety-bringup-missing-checks=batch_0` flag to get a stable group of checks that will not change over time. This is preferrable to specifying `-fbounds-safety-bringup-missing-checks=all` because the enabled checks will likely change overtime which could cause regressions in an `-fbounds-safety` adopter when the compiler is upgraded. While we're here this patch also fixes how the `BoundsSafetyNewChecksMask` type was being incorrectly used as both an enum and a bitmask. While this technically worked (because enums have an underlying integer type) it isn't conceptually correct because a bit mask and an enum value are not the same thing. A value of enum type should take on only **ONE** of the valid enum values, whereas a bitmask can take on one or more of the valid enum values. This is fixed by introducing `BoundsSafetyNewChecksMaskIntTy` and using it where appropriate and also renaming `BoundsSafetyNewChecksMask` to `BoundsSafetyNewChecks`. rdar://145826593 (cherry picked from commit 704c190)
1 parent 0d67cb0 commit 71789b9

File tree

9 files changed

+210
-107
lines changed

9 files changed

+210
-107
lines changed

clang/include/clang/Basic/LangOptions.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ LANGOPT(BoundsAttributesCXXExperimental, 1, 0, "Experimental bounds attributes f
540540
LANGOPT(BoundsAttributesObjCExperimental, 1, 0, "Experimental bounds attributes for Objective-C")
541541
LANGOPT(BoundsSafetyRelaxedSystemHeaders, 1, 1,
542542
"Relax bounds safety assignment rules in system headers")
543-
ENUM_LANGOPT(BoundsSafetyBringUpMissingChecks, BoundsSafetyNewChecksMask, 7, BS_CHK_Default,
543+
LANGOPT(BoundsSafetyBringUpMissingChecks, 7, clang::LangOptions::getDefaultBoundsSafetyNewChecksMask(),
544544
"Bring up new -fbounds-safety run-time checks")
545545
/* TO_UPSTREAM(BoundsSafety) OFF*/
546546

clang/include/clang/Basic/LangOptions.h

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ class LangOptionsBase {
411411
};
412412

413413
/* TODO(BoundsSafety) Deprecate the flag */
414-
enum BoundsSafetyNewChecksMask {
414+
enum BoundsSafetyNewChecks {
415415
BS_CHK_None = 0,
416416

417417
BS_CHK_AccessSize = 1 << 0, // rdar://72252593
@@ -421,17 +421,13 @@ class LangOptionsBase {
421421
BS_CHK_CompoundLiteralInit = 1 << 4, // rdar://110871666
422422
BS_CHK_LibCAttributes = 1 << 5, // rdar://84733153
423423
BS_CHK_ArraySubscriptAgg = 1 << 6, // rdar://145020583
424-
425-
BS_CHK_All = BS_CHK_AccessSize | BS_CHK_IndirectCountUpdate |
426-
BS_CHK_ReturnSize | BS_CHK_EndedByLowerBound |
427-
BS_CHK_CompoundLiteralInit | BS_CHK_LibCAttributes |
428-
BS_CHK_ArraySubscriptAgg,
429-
430-
// This sets the default value assumed by clang if no
431-
// `-fbounds-safety-bringup-missing-checks` flags are
432-
// passed to clang.
433-
BS_CHK_Default = BS_CHK_None,
434424
};
425+
using BoundsSafetyNewChecksMaskIntTy =
426+
std::underlying_type_t<BoundsSafetyNewChecks>;
427+
428+
static BoundsSafetyNewChecksMaskIntTy
429+
getBoundsSafetyNewChecksMaskForGroup(StringRef GroupName);
430+
static BoundsSafetyNewChecksMaskIntTy getDefaultBoundsSafetyNewChecksMask();
435431

436432
/// Controls the various implementations for complex multiplication and
437433
// division.
@@ -819,10 +815,10 @@ class LangOptions : public LangOptionsBase {
819815
return hasBoundsSafetyAttributes() && !hasBoundsSafety();
820816
}
821817

822-
// Take `enum BoundsSafetyNewChecksMask` value as input and return true if
823-
// the mask is set. New -fbounds-safety run-time checks should use this helper
824-
// to decide whether to enable/disable the checks.
825-
bool hasNewBoundsSafetyCheck(BoundsSafetyNewChecksMask ChkMask) const {
818+
// Take a BoundsSafetyNewChecksMask (or check mask) and return true if
819+
// the check (or mask) is set. New -fbounds-safety run-time checks should use
820+
// this helper to decide whether to enable/disable the checks.
821+
bool hasNewBoundsSafetyCheck(BoundsSafetyNewChecksMaskIntTy ChkMask) const {
826822
return (BoundsSafetyBringUpMissingChecks & ChkMask) != 0;
827823
}
828824

clang/include/clang/Driver/BoundsSafetyArgs.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@
1313

1414
namespace clang {
1515
namespace driver {
16-
using BoundsSafetyNewChecksMaskTy =
17-
std::underlying_type<LangOptions::BoundsSafetyNewChecksMask>::type;
1816

19-
BoundsSafetyNewChecksMaskTy
17+
LangOptions::BoundsSafetyNewChecksMaskIntTy
2018
ParseBoundsSafetyNewChecksMaskFromArgs(const llvm::opt::ArgList &Args,
2119
DiagnosticsEngine *Diags);
2220
} // namespace driver

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,12 +2004,12 @@ defm bounds_safety_adoption_mode : BoolFOption<"bounds-safety-adoption-mode",
20042004
def fbounds_safety_bringup_missing_checks_EQ : CommaJoined<["-"], "fbounds-safety-bringup-missing-checks=">, Group<f_Group>,
20052005
MetaVarName<"<check>">,
20062006
Visibility<[ClangOption, CC1Option]>,
2007-
HelpText<"Enable a set of new -fbounds-safety run-time checks, (option: access_size, indirect_count_update, return_size, ended_by_lower_bound, compound_literal_init, libc_attributes, array_subscript_agg, all)">;
2007+
HelpText<"Enable a set of new -fbounds-safety run-time checks, (option: access_size, indirect_count_update, return_size, ended_by_lower_bound, compound_literal_init, libc_attributes, array_subscript_agg, all, batch_0)">;
20082008

20092009
def fno_bounds_safety_bringup_missing_checks_EQ : CommaJoined<["-"], "fno-bounds-safety-bringup-missing-checks=">, Group<f_Group>,
20102010
MetaVarName<"<check>">,
20112011
Visibility<[ClangOption, CC1Option]>,
2012-
HelpText<"Disable a set of new -fbounds-safety run-time checks, (option: access_size, indirect_count_update, return_size, ended_by_lower_bound, compound_literal_init, libc_attributes, array_subscript_agg, all)">;
2012+
HelpText<"Disable a set of new -fbounds-safety run-time checks, (option: access_size, indirect_count_update, return_size, ended_by_lower_bound, compound_literal_init, libc_attributes, array_subscript_agg, all, batch_0)">;
20132013

20142014
def fbounds_safety_bringup_missing_checks : Flag<["-"], "fbounds-safety-bringup-missing-checks">, Group<f_Group>,
20152015
Visibility<[ClangOption]>,

clang/lib/Basic/LangOptions.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,25 @@ LLVM_DUMP_METHOD void FPOptionsOverride::dump() {
238238
#include "clang/Basic/FPOptions.def"
239239
llvm::errs() << "\n";
240240
}
241+
242+
/* TO_UPSTREAM(BoundsSafety) ON*/
243+
LangOptionsBase::BoundsSafetyNewChecksMaskIntTy
244+
LangOptionsBase::getBoundsSafetyNewChecksMaskForGroup(StringRef GroupName) {
245+
const uint64_t Batch0 = BS_CHK_AccessSize | BS_CHK_IndirectCountUpdate |
246+
BS_CHK_ReturnSize | BS_CHK_EndedByLowerBound |
247+
BS_CHK_CompoundLiteralInit | BS_CHK_LibCAttributes |
248+
BS_CHK_ArraySubscriptAgg;
249+
250+
// Currently "all" and "batch_0" are the same
251+
if (GroupName == "all" || GroupName == "batch_0")
252+
return Batch0;
253+
254+
// Invalid GroupName
255+
return BS_CHK_None;
256+
}
257+
258+
LangOptionsBase::BoundsSafetyNewChecksMaskIntTy
259+
LangOptionsBase::getDefaultBoundsSafetyNewChecksMask() {
260+
return BS_CHK_None;
261+
}
262+
/* TO_UPSTREAM(BoundsSafety) OFF*/

clang/lib/Driver/BoundsSafetyArgs.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,30 @@ namespace clang {
1616

1717
namespace driver {
1818

19-
BoundsSafetyNewChecksMaskTy
19+
LangOptions::BoundsSafetyNewChecksMaskIntTy
2020
ParseBoundsSafetyNewChecksMaskFromArgs(const llvm::opt::ArgList &Args,
2121
DiagnosticsEngine *Diags) {
2222
auto FilteredArgs =
2323
Args.filtered(OPT_fbounds_safety_bringup_missing_checks_EQ,
2424
OPT_fno_bounds_safety_bringup_missing_checks_EQ);
2525
if (FilteredArgs.empty()) {
2626
// No flags present. Use the default
27-
return LangOptions::BS_CHK_Default;
27+
return LangOptions::getDefaultBoundsSafetyNewChecksMask();
2828
}
2929

3030
// If flags are present then start with BS_CHK_None as the initial mask and
3131
// update the mask based on the flags. This preserves compiler behavior for
3232
// users that adopted the `-fbounds-safety-bringup-missing-checks` flag when
33-
// `BS_CHK_Default == BS_CHK_None`.
34-
BoundsSafetyNewChecksMaskTy Result = LangOptions::BS_CHK_None;
33+
// `getDefaultBoundsSafetyNewChecksMask() == BS_CHK_None`.
34+
LangOptions::BoundsSafetyNewChecksMaskIntTy Result = LangOptions::BS_CHK_None;
3535
// All the options will be applied as masks in the command line order, to make
3636
// it easier to enable all but certain checks (or disable all but certain
3737
// checks).
3838
for (const Arg *A : FilteredArgs) {
3939
for (const char *Value : A->getValues()) {
40-
std::optional<LangOptions::BoundsSafetyNewChecksMask> Mask =
40+
std::optional<LangOptions::BoundsSafetyNewChecksMaskIntTy> Mask =
4141
llvm::StringSwitch<
42-
std::optional<LangOptions::BoundsSafetyNewChecksMask>>(Value)
42+
std::optional<LangOptions::BoundsSafetyNewChecksMaskIntTy>>(Value)
4343
.Case("access_size", LangOptions::BS_CHK_AccessSize)
4444
.Case("indirect_count_update",
4545
LangOptions::BS_CHK_IndirectCountUpdate)
@@ -51,7 +51,11 @@ ParseBoundsSafetyNewChecksMaskFromArgs(const llvm::opt::ArgList &Args,
5151
.Case("libc_attributes", LangOptions::BS_CHK_LibCAttributes)
5252
.Case("array_subscript_agg",
5353
LangOptions::BS_CHK_ArraySubscriptAgg)
54-
.Case("all", LangOptions::BS_CHK_All)
54+
.Case("all",
55+
LangOptions::getBoundsSafetyNewChecksMaskForGroup("all"))
56+
.Case(
57+
"batch_0",
58+
LangOptions::getBoundsSafetyNewChecksMaskForGroup("batch_0"))
5559
.Case("none", LangOptions::BS_CHK_None)
5660
.Default(std::nullopt);
5761
if (!Mask) {

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3923,10 +3923,15 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
39233923

39243924
/*TO_UPSTREAM(BoundsSafety) ON*/
39253925
if (Opts.BoundsSafety &&
3926-
Opts.BoundsSafetyBringUpMissingChecks != LangOptions::BS_CHK_Default) {
3926+
Opts.BoundsSafetyBringUpMissingChecks !=
3927+
LangOptions::getDefaultBoundsSafetyNewChecksMask()) {
39273928
std::string Checks;
3928-
if (Opts.BoundsSafetyBringUpMissingChecks == LangOptions::BS_CHK_All) {
3929+
if (Opts.BoundsSafetyBringUpMissingChecks ==
3930+
LangOptions::getBoundsSafetyNewChecksMaskForGroup("all")) {
39293931
Checks = "all";
3932+
} else if (Opts.BoundsSafetyBringUpMissingChecks ==
3933+
LangOptions::getBoundsSafetyNewChecksMaskForGroup("batch_0")) {
3934+
Checks = "batch_0";
39303935
} else {
39313936
if (Opts.hasNewBoundsSafetyCheck(LangOptions::BS_CHK_AccessSize))
39323937
Checks += "access_size,";

clang/test/BoundsSafety/Driver/bounds-safety-bringup-missing-checks.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
// EMPTY-NOT: -fno-bounds-safety-bringup-missing-checks
88
// EMPTY-NOT: -fbounds-safety-bringup-missing-checks=all
99
// EMPTY-NOT: -fno-bounds-safety-bringup-missing-checks=all
10+
// EMPTY-NOT: -fbounds-safety-bringup-missing-checks=batch_0
11+
// EMPTY-NOT: -fno-bounds-safety-bringup-missing-checks=batch_0
1012

1113
// RUN: %clang -fbounds-safety -fno-bounds-safety-bringup-missing-checks -c %s -### 2>&1 | FileCheck %s --check-prefix=DISABLED
1214
// DISABLED: -fno-bounds-safety-bringup-missing-checks=all
@@ -45,6 +47,9 @@
4547
// RUN: %clang -fbounds-safety -fbounds-safety-bringup-missing-checks=all -c %s -### 2>&1 | FileCheck %s --check-prefix=POS_ALL
4648
// POS_ALL: -fbounds-safety-bringup-missing-checks=all
4749

50+
// RUN: %clang -fbounds-safety -fbounds-safety-bringup-missing-checks=batch_0 -c %s -### 2>&1 | FileCheck %s --check-prefix=POS_batch_0
51+
// POS_batch_0: -fbounds-safety-bringup-missing-checks=batch_0
52+
4853
// RUN: %clang -fbounds-safety -fno-bounds-safety-bringup-missing-checks=access_size -c %s -### 2>&1 | FileCheck %s --check-prefix=NEG_ACCESS
4954
// NEG_ACCESS: -fno-bounds-safety-bringup-missing-checks=access_size
5055

@@ -66,6 +71,9 @@
6671
// RUN: %clang -fbounds-safety -fno-bounds-safety-bringup-missing-checks=all -c %s -### 2>&1 | FileCheck %s --check-prefix=NEG_ALL
6772
// NEG_ALL: -fno-bounds-safety-bringup-missing-checks=all
6873

74+
// RUN: %clang -fbounds-safety -fno-bounds-safety-bringup-missing-checks=batch_0 -c %s -### 2>&1 | FileCheck %s --check-prefix=NEG_batch_0
75+
// NEG_batch_0: -fno-bounds-safety-bringup-missing-checks=batch_0
76+
6977
// RUN: %clang -fbounds-safety -fbounds-safety-bringup-missing-checks=access_size,indirect_count_update,return_size,ended_by_lower_bound,compound_literal_init,libc_attributes,all -c %s -### 2>&1 | FileCheck %s --check-prefix=POS_COMMA
7078
// POS_COMMA: -fbounds-safety-bringup-missing-checks=access_size,indirect_count_update,return_size,ended_by_lower_bound,compound_literal_init,libc_attributes,all
7179

@@ -86,3 +94,8 @@
8694
// RUN: %clang -fbounds-safety-bringup-missing-checks -c %s -### 2>&1 | FileCheck %s --check-prefixes=UNUSED_POS
8795
// UNUSED_POS: warning: argument unused during compilation: '-fbounds-safety-bringup-missing-checks'
8896

97+
// RUN: %clang -fno-bounds-safety-bringup-missing-checks=batch_0 -c %s -### 2>&1 | FileCheck %s --check-prefixes=UNUSED_NEG_BATCH_0
98+
// UNUSED_NEG_BATCH_0: warning: argument unused during compilation: '-fno-bounds-safety-bringup-missing-checks=batch_0'
99+
100+
// RUN: %clang -fbounds-safety-bringup-missing-checks=batch_0 -c %s -### 2>&1 | FileCheck %s --check-prefixes=UNUSED_POS_BATCH_0
101+
// UNUSED_POS_BATCH_0: warning: argument unused during compilation: '-fbounds-safety-bringup-missing-checks=batch_0'

0 commit comments

Comments
 (0)