Skip to content
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

Start emitting overflow lints for const promoted SHL & SHRs #119339

Closed

Conversation

gurry
Copy link
Contributor

@gurry gurry commented Dec 27, 2023

Fixes #117949

The overflow lints for promoted shift ops had been accidently disabled by #108282. That is because #108282 caused Shl & Shr ops to be removed from the MIR which silenced the lints.

In this PR we start firing them again by triggering them based on the assert terminators instead which luckily are not removed from the MIR.

This fixes the issue where no lints were firing for overflowing SHL and SHR ops.
That happened because `ConstPropagator::check_binary_op()`, which is responsible
for firing these lints, was skipping them because it couldn't find any `Shl()` or `Shr()`
ops in the main MIR. That in turn occurred because our const promotion pass
`PromoteTemps` removes these ops from the MIR when it runs.

With this change, the firing of these particular lints is predicated on the presence of
an assert terminator instead, which fortunately is not removed by `PromoteTemps`
@rustbot
Copy link
Collaborator

rustbot commented Dec 27, 2023

r? @b-naber

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 27, 2023
@gurry
Copy link
Contributor Author

gurry commented Dec 27, 2023

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 27, 2023
@rust-log-analyzer

This comment has been minimized.

// but it can't because they are getting removed from the MIR
// during const promotion. So we check the associated asserts
// here instead as they are not removed by promotion.
(AssertKind::Overflow(*bin_op, eval_to_int(op1), eval_to_int(op2)), true)
Copy link
Member

Choose a reason for hiding this comment

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

If you emit the lint here then you should be able to remove the shift handling from check_binary_op. That should also fix the duplicate lints.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried that, but it eliminates only 6 of the 59 new duplicates added by this change.

Copy link
Member

Choose a reason for hiding this comment

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

What exactly did you try? I should look something like this:

diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index 99eecb567f2..d36798518e2 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -317,37 +317,9 @@ fn check_binary_op(
         });
         let l = self
             .use_ecx(location, |this| this.ecx.read_immediate(&this.ecx.eval_operand(left, None)?));
-        // Check for exceeding shifts *even if* we cannot evaluate the LHS.
+        // Shifts are linted via the `Assert` terminator, not this function.
         if matches!(op, BinOp::Shr | BinOp::Shl) {
-            let r = r.clone()?;
-            // We need the type of the LHS. We cannot use `place_layout` as that is the type
-            // of the result, which for checked binops is not the same!
-            let left_ty = left.ty(self.local_decls(), self.tcx);
-            let left_size = self.ecx.layout_of(left_ty).ok()?.size;
-            let right_size = r.layout.size;
-            let r_bits = r.to_scalar().to_bits(right_size).ok();
-            if r_bits.is_some_and(|b| b >= left_size.bits() as u128) {
-                debug!("check_binary_op: reporting assert for {:?}", location);
-                let source_info = self.body().source_info(location);
-                let panic = AssertKind::Overflow(
-                    op,
-                    match l {
-                        Some(l) => l.to_const_int(),
-                        // Invent a dummy value, the diagnostic ignores it anyway
-                        None => ConstInt::new(
-                            ScalarInt::try_from_uint(1_u8, left_size).unwrap(),
-                            left_ty.is_signed(),
-                            left_ty.is_ptr_sized_integral(),
-                        ),
-                    },
-                    r.to_const_int(),
-                );
-                self.report_assert_as_lint(
-                    source_info,
-                    AssertLint::ArithmeticOverflow(source_info.span, panic),
-                );
-                return None;
-            }
+            return None;
         }
 
         if let (Some(l), Some(r)) = (l, r) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh. I just got rid of the entire if block. Didn't realize I must return None to disable shift handling.

I have done that now in the latest commit I pushed. It has eliminated all duplicates. However, we have the opposite problem now. Many of the shift lints in release builds have been silenced possibly because we don't emit asserts in those builds.

Copy link
Member

Choose a reason for hiding this comment

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

Many of the shift lints in release builds have been silenced possibly because we don't emit asserts in those builds.

Ah... right. Yeah for debug/release consistency we really want to lint on the operation (shl/shr/add/...), not the assert. But then we need to lint in promoteds as well.

@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-16 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
GITHUB_ACTION=__run_7
GITHUB_ACTIONS=true
GITHUB_ACTION_REF=
GITHUB_ACTION_REPOSITORY=
GITHUB_ACTOR=gurry
GITHUB_API_URL=https://api.github.com
GITHUB_BASE_REF=master
GITHUB_ENV=/home/runner/work/_temp/_runner_file_commands/set_env_0167f854-3241-4cb7-92f4-7481e6564158
GITHUB_EVENT_NAME=pull_request
---
GITHUB_SERVER_URL=https://github.com
GITHUB_SHA=36eb30acd8803389751f3f839cd610e149f590c9
GITHUB_STATE=/home/runner/work/_temp/_runner_file_commands/save_state_0167f854-3241-4cb7-92f4-7481e6564158
GITHUB_STEP_SUMMARY=/home/runner/work/_temp/_runner_file_commands/step_summary_0167f854-3241-4cb7-92f4-7481e6564158
GITHUB_TRIGGERING_ACTOR=gurry
GITHUB_WORKFLOW_REF=rust-lang/rust/.github/workflows/ci.yml@refs/pull/119339/merge
GITHUB_WORKFLOW_SHA=36eb30acd8803389751f3f839cd610e149f590c9
GITHUB_WORKSPACE=/home/runner/work/rust/rust
GOROOT_1_19_X64=/opt/hostedtoolcache/go/1.19.13/x64
---
Built container sha256:9c3c93a371e5aed5c18185b24f130d95d5140dbd72a9b325e7b6b49e521a4faa
Looks like docker image is the same as before, not uploading
https://ci-caches.rust-lang.org/docker/7ebc15c01a233894034d277c8cce4e949f4e7791f66b4727c8fb6e058a0b8171d6152e1441d677cef0653843ceeee469c097b8699b2bb74249e674f6aa1a8813
sha256:9c3c93a371e5aed5c18185b24f130d95d5140dbd72a9b325e7b6b49e521a4faa
Setting extra environment values for docker:  --env ENABLE_GCC_CODEGEN=1 --env GCC_EXEC_PREFIX=/usr/lib/gcc/
[CI_JOB_NAME=x86_64-gnu-llvm-16]
##[group]Clock drift check
  local time: Fri Dec 29 04:07:37 UTC 2023
  network time: Fri, 29 Dec 2023 04:07:37 GMT
  network time: Fri, 29 Dec 2023 04:07:37 GMT
##[endgroup]
sccache: Starting the server...
##[group]Configure the build
configure: processing command line
configure: 
configure: build.configure-args := ['--build=x86_64-unknown-linux-gnu', '--llvm-root=/usr/lib/llvm-16', '--enable-llvm-link-shared', '--set', 'rust.thin-lto-import-instr-limit=10', '--enable-verbose-configure', '--enable-sccache', '--disable-manage-submodules', '--enable-locked-deps', '--enable-cargo-native-static', '--set', 'rust.codegen-units-std=1', '--set', 'dist.compression-profile=balanced', '--dist-compression-formats=xz', '--disable-dist-src', '--release-channel=nightly', '--enable-debug-assertions', '--enable-overflow-checks', '--enable-llvm-assertions', '--set', 'rust.verify-llvm-ir', '--set', 'rust.codegen-backends=llvm,cranelift,gcc', '--set', 'llvm.static-libstdcpp', '--enable-missing-tools', '--enable-new-symbol-mangling']
configure: target.x86_64-unknown-linux-gnu.llvm-config := /usr/lib/llvm-16/bin/llvm-config
configure: llvm.link-shared     := True
configure: rust.thin-lto-import-instr-limit := 10
configure: rust.codegen-units-std := 1
---
failures:

---- [ui] tests/ui/lint/lint-exceeding-bitshifts.rs#opt stdout ----

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:22: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:27: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:29: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:31: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:33: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:35: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:37: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:39: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:41: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:44: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:46: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:48: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:50: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:52: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:54: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:56: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:58: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:62: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:64: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:69: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:71: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:77: expected warning not found: arithmetic operation will overflow

error in revision `opt`: /checkout/tests/ui/lint/lint-exceeding-bitshifts.rs:78: expected warning not found: arithmetic operation will overflow

error in revision `opt`: 0 unexpected errors found, 23 expected errors not found
status: exit status: 0
command: RUSTC_ICE="0" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/lint/lint-exceeding-bitshifts.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--cfg" "opt" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/lint/lint-exceeding-bitshifts.opt" "-A" "unused" "-A" "internal_features" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/lint/lint-exceeding-bitshifts.opt/auxiliary" "-O"
    Error {
        line_num: 22,
        kind: Some(
            Warning,
---
        msg: "arithmetic operation will overflow",
    },
]

thread '[ui] tests/ui/lint/lint-exceeding-bitshifts.rs#opt' panicked at src/tools/compiletest/src/runtest.rs:1825:13:
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:

@bors
Copy link
Contributor

bors commented Jan 25, 2024

☔ The latest upstream changes (presumably #119627) made this pull request unmergeable. Please resolve the merge conflicts.

@RalfJung
Copy link
Member

I think this got superseded by #119432?

@gurry
Copy link
Contributor Author

gurry commented Jan 27, 2024

I think this got superseded by #119432?

Yes. I'll abandon it.

@gurry gurry closed this Jan 27, 2024
@gurry gurry deleted the 117949-overflow-lint-not-triggered-in-mir branch January 27, 2024 08:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

arithmetic_overflow lint not triggered for overflowing shifts in promoteds
6 participants