Skip to content

[BoundsSafety][Attempt 2] Add warning diagnostics for uses of legacy bounds checks #10898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 8, 2025

Conversation

delcypher
Copy link

@delcypher delcypher commented Jun 25, 2025

** This is the second attempt landing this patch. This first (#10800
4c8f6e7) failed because there was a bug. **

The bug was in ParseBoundsSafetyNewChecksMaskFromArgs where the call to
DiagnoseDisabledBoundsSafetyChecks was not guarded with
DiagnoseMissingChecks. This missing check caused diagnostics to appear
when they shouldn't and caused crashes in cases where the Diags
pointer was nullptr. To fix this the missing guard has been added and
an assert that Diags is not null has been added.

Unfortunately it isn't possible to write a regression test for this
because the behavior depends on having at least some bounds checks
disabled by default, which is not desirable behavior. While techinically
we could add a hidden flag to change the default for the purposes of
testing the added complexity of doing this doesn't really justify the
added test coverage.

This version of the patch also guards assigning to
Opts.BoundsSafetyBringUpMissingChecks in
CompilerInvocation::ParseLangArgs so that it is only assigned to
when -fbounds-safety is enabled. This is done for several reasons

  • It avoids unnecessarily parsing the -fbounds-safety-bringup-missing-checks= flags
    when -fbounds-safety is disabled.
  • Isolates code built without -fbounds-safety from bugs in
    ParseBoundsSafetyNewChecksMaskFromArgs.
  • It is more consistent with CompilerInvocationBase::GenerateLangArgs
    which only emits -fbounds-safety-bring-checks= when
    -fbounds-safety is enabled.

This adds warning diagnostics when any of the new bounds checks that can
be enabled with -fbounds-safety-bringup-missing-checks=batch_0 are
disabled.

If all bounds checks in the batch are disabled a single diagnostic is
emitted. If only some of the bounds checks in the batch are disabled
then a diagnostic is emitted for each disabled bounds check. The
implementation will either suggest enabling a batch of checks (e.g.
-fbounds-safety-bringup-missing-checks=batch_0) or will suggest
removing a flag that is explicitly disabling a check (e.g.
-fno-bounds-safety-bringup-missing-checks=access_size).

The current implementation supports there being multple batches of
checks. However, there is currently only one batch (batch_0).

I originally tried to emit these warnings in the frontend. Unfortunately
it turns out warning suppression (i.e.
-Wno-bounds-safety-legacy-checks-enabled) and -Werror don't work
correctly if warnings are emitted from the frontend (rdar://152730261).
To workaround this the -fbounds-safety-bringup-missing-checks= flags
are now also parsed in the Driver and at this point (and only this
point) diagnostics for missing checks are emitted.

The intention is to make these warnings be errors eventually.

rdar://150805550

@delcypher
Copy link
Author

@swift-ci test llvm

@delcypher delcypher force-pushed the dliew/rdar-150805550-v2 branch from 349afa5 to bf4fa08 Compare June 25, 2025 17:39
auto FilteredArgs =
Args.filtered(OPT_fbounds_safety_bringup_missing_checks_EQ,
OPT_fno_bounds_safety_bringup_missing_checks_EQ);
if (FilteredArgs.empty()) {
// No flags present. Use the default
return LangOptions::getDefaultBoundsSafetyNewChecksMask();
auto Result = LangOptions::getDefaultBoundsSafetyNewChecksMask();
if (DiagnoseMissingChecks && Diags)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hnrklssn This is where the bug was in the first version. There was a missing guard for the call to DiagnoseDisabledBoundsSafetyChecks which meant if DiagnoseMissingChecks was false we'd try to diagnose the issues anyway.

Copy link
Author

@delcypher delcypher Jun 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. So I think I need to write a test case for this because all the BoundsSafety tests for this passed without making this fix.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I figured out it's not possible to (easily) write a test case for this. The buggy behavior depends on bounds checks being disabled by default which is not desirable behavior. While technically we could add a hidden flag that changes the default for the purposes of testing I think this adds a lot of complexity without a huge benefit.

@delcypher delcypher added the clang:bounds-safety Issue relating to the experimental -fbounds-safety feature in Clang label Jun 26, 2025
@delcypher delcypher force-pushed the dliew/rdar-150805550-v2 branch from bf4fa08 to ddcf48d Compare July 8, 2025 16:00
…bounds checks

** This is the second attempt landing this patch. This first (swiftlang#10800
4c8f6e7) failed because there was a bug. **

The bug was in `ParseBoundsSafetyNewChecksMaskFromArgs` where the call to
`DiagnoseDisabledBoundsSafetyChecks` was not guarded with
`DiagnoseMissingChecks`. This missing check caused diagnostics to appear
when they shouldn't and caused crashes in cases where the `Diags`
pointer was nullptr. To fix this the missing guard has been added and
an assert that `Diags` is not null has been added.

Unfortunately it isn't possible to write a regression test for this
because the behavior depends on having at least some bounds checks
disabled by default, which is not desirable behavior. While techinically
we could add a hidden flag to change the default for the purposes of
testing the added complexity of doing this doesn't really justify the
added test coverage.

This version of the patch also guards assigning to
`Opts.BoundsSafetyBringUpMissingChecks` in
`CompilerInvocation::ParseLangArgs` so that it is only assigned to
when `-fbounds-safety` is enabled. This is done for several reasons

* It avoids unnecessarily parsing the `-fbounds-safety-bringup-missing-checks=` flags
  when `-fbounds-safety` is disabled.
* Isolates code built without `-fbounds-safety` from bugs in
  `ParseBoundsSafetyNewChecksMaskFromArgs`.
* It is more consistent with `CompilerInvocationBase::GenerateLangArgs`
  which only emits `-fbounds-safety-bring-checks=` when
  `-fbounds-safety` is enabled.

---

This adds warning diagnostics when any of the new bounds checks that can
be enabled with `-fbounds-safety-bringup-missing-checks=batch_0` are
disabled.

If all bounds checks in the batch are disabled a single diagnostic is
emitted. If only some of the bounds checks in the batch are disabled
then a diagnostic is emitted for each disabled bounds check. The
implementation will either suggest enabling a batch of checks (e.g.
`-fbounds-safety-bringup-missing-checks=batch_0`) or will suggest
removing a flag that is explicitly disabling a check (e.g.
`-fno-bounds-safety-bringup-missing-checks=access_size`).

The current implementation supports there being multple batches of
checks. However, there is currently only one batch (`batch_0`).

I originally tried to emit these warnings in the frontend. Unfortunately
it turns out warning suppression (i.e.
`-Wno-bounds-safety-legacy-checks-enabled`) and `-Werror` don't work
correctly if warnings are emitted from the frontend (rdar://152730261).
To workaround this the `-fbounds-safety-bringup-missing-checks=` flags
are now also parsed in the Driver and at this point (and only this
point) diagnostics for missing checks are emitted.

The intention is to make these warnings be errors eventually.

rdar://150805550
@delcypher delcypher force-pushed the dliew/rdar-150805550-v2 branch from ddcf48d to 0aab1a8 Compare July 8, 2025 16:02
@delcypher
Copy link
Author

@swift-ci test llvm

@delcypher delcypher merged commit 5856ac4 into swiftlang:next Jul 8, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:bounds-safety Issue relating to the experimental -fbounds-safety feature in Clang
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants