{"id":"45bb2c77894e3704","repo":"rust-lang/rust","slug":"tried-to-get-overflow-intrinsic-for-op-applied-to","errorCode":null,"errorMessage":"tried to get overflow intrinsic for op applied to non-int type","messagePattern":"tried to get overflow intrinsic for op applied to non-int type","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_gcc/src/int.rs","lineNumber":284,"sourceCode":"        self.multiplicative_operation(BinaryOp::Divide, \"div\", false, a, b)\n    }\n\n    pub fn gcc_checked_binop(\n        &self,\n        oop: OverflowOp,\n        typ: Ty<'_>,\n        lhs: <Self as BackendTypes>::Value,\n        rhs: <Self as BackendTypes>::Value,\n    ) -> (<Self as BackendTypes>::Value, <Self as BackendTypes>::Value) {\n        use rustc_middle::ty::IntTy::*;\n        use rustc_middle::ty::UintTy::*;\n        use rustc_middle::ty::{Int, Uint};\n\n        let new_kind = match *typ.kind() {\n            Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)),\n            Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)),\n            t @ (Uint(_) | Int(_)) => t,\n            _ => panic!(\"tried to get overflow intrinsic for op applied to non-int type\"),\n        };\n\n        // FIXME(antoyo): remove duplication with intrinsic?\n        let name = if self.is_native_int_type(lhs.get_type()) {\n            match oop {\n                OverflowOp::Add => \"__builtin_add_overflow\",\n                OverflowOp::Sub => \"__builtin_sub_overflow\",\n                OverflowOp::Mul => \"__builtin_mul_overflow\",\n            }\n        } else {\n            let (func_name, width) = match oop {\n                OverflowOp::Add => match new_kind {\n                    Int(I128) => (\"__rust_i128_addo\", 128),\n                    Uint(U128) => (\"__rust_u128_addo\", 128),\n                    _ => unreachable!(),\n                },\n                OverflowOp::Sub => match new_kind {\n                    Int(I128) => (\"__rust_i128_subo\", 128),","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_gcc/src/int.rs#L266-L302","documentation":"`Builder::gcc_checked_binop` (overflow-checking add/sub/mul) matches on `typ.kind()` and only handles `Int`/`Uint`. Any other `TyKind` (e.g. a pointer-sized type that wasn't normalized, a `Bool`, a char, or an enum/struct) reaches the panic arm. The function is meant to be called only for integer overflow intrinsics, so a non-int type indicates a dispatch bug upstream.","triggerScenarios":"`rustc_codegen_ssa` calls `gcc_checked_binop(oop, typ, lhs, rhs)` with a `typ` whose `TyKind` is not `Int(_)` or `Uint(_)` (after `Isize`/`Usize` normalization). Occurs when an overflow check is emitted for an operand whose type the middle end did not constrain to an integer.","commonSituations":"Triggered by edge cases in MIR: overflow checks on `char` arithmetic, raw-pointer offsetting that lowers to a checked binop, or after a rustc upgrade that introduces a new `TyKind` not yet reflected here. Symptom of an upstream type-system mismatch rather than user code.","solutions":["Identify the offending `typ` by dumping `typ.kind()` at the panic site; trace back to the MIR `BinOp`/`OverflowOp` that produced it.","If the type is logically an integer (e.g. char-as-u32), normalize it before calling `gcc_checked_binop`, or handle the case in the caller.","Guard the call site in the SSA layer so overflow intrinsics are only requested for integer types.","Add a regression test exercising the offending MIR construct on the i128/non-native path."],"exampleFix":"// before\n_ => panic!(\"tried to get overflow intrinsic for op applied to non-int type\"),\n\n// after (actionable message including the kind)\nother => panic!(\n    \"gcc_checked_binop: non-int type {:?} for op {:?}\",\n    other, oop,\n),","handlingStrategy":"type-guard","validationCode":"// gcc_checked_binop panics when typ.kind() is not Int/Uint. Narrow first.\nuse rustc_middle::ty::{Int, Uint, TyKind};\nmatch *typ.kind() {\n    TyKind::Int(_) | TyKind::Uint(_) => builder.gcc_checked_binop(oop, typ, lhs, rhs),\n    _ => return Err(format!(\"checked overflow on non-int type {:?}\", typ)),\n}","typeGuard":"use rustc_middle::ty::{Int, Uint, TyKind};\n\n/// True only for integer (signed or unsigned) Rust types.\nfn ty_is_integer<'tcx>(typ: rustc_middle::ty::Ty<'tcx>) -> bool {\n    matches!(typ.kind(), TyKind::Int(_) | TyKind::Uint(_))\n}\n\nif ty_is_integer(typ) {\n    builder.gcc_checked_binop(oop, typ, lhs, rhs)\n}","tryCatchPattern":null,"preventionTips":["Overflow ops (wrapping_add, checked_*, saturating_*) are only defined on integers in Rust; never pass pointer, float, char, or enum types into a checked-binop codegen path.","If you need overflow detection on a newtype, delegate to the inner integer field, not the wrapper type.","Normalize isize/usize to a concrete width (via normalize(target.pointer_width)) before calling gcc_checked_binop so the kind stays Int/Uint."],"tags":["rustc-codegen-gcc","ice","overflow","type-mismatch","tykind"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}