Skip to content

Commit

Permalink
Prevent overflowing enum cast from ICEing
Browse files Browse the repository at this point in the history
  • Loading branch information
clubby789 committed Oct 19, 2024
1 parent f7b5e54 commit ab4222a
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
9 changes: 8 additions & 1 deletion compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,14 @@ impl<'tcx> Cx<'tcx> {
.unwrap_or_else(|e| panic!("could not compute layout for {param_env_ty:?}: {e:?}"))
.size;

let lit = ScalarInt::try_from_uint(discr_offset as u128, size).unwrap();
let (lit, overflowing) = ScalarInt::truncate_from_uint(discr_offset as u128, size);
if overflowing {
// An erroneous enum with too many variants for its repr will emit E0081 and E0370
self.tcx.dcx().span_delayed_bug(
source.span,
"overflowing enum wasn't rejected by hir analysis",
);
}
let kind = ExprKind::NonHirLiteral { lit, user_ty: None };
let offset = self.thir.exprs.push(Expr { temp_lifetime, ty: discr_ty, span, kind });

Expand Down
42 changes: 42 additions & 0 deletions tests/ui/error-codes/E0081.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,47 @@ enum MultipleDuplicates {
//~^ NOTE `-2` assigned here
}

// Test for #131902
// Ensure that casting an enum with too many variants for its repr
// does not ICE
#[repr(u8)]
enum TooManyVariants {
//~^ ERROR discriminant value `0` assigned more than once
X000, X001, X002, X003, X004, X005, X006, X007, X008, X009,
//~^ NOTE `0` assigned here
//~| NOTE discriminant for `X256` incremented from this startpoint
X010, X011, X012, X013, X014, X015, X016, X017, X018, X019,
X020, X021, X022, X023, X024, X025, X026, X027, X028, X029,
X030, X031, X032, X033, X034, X035, X036, X037, X038, X039,
X040, X041, X042, X043, X044, X045, X046, X047, X048, X049,
X050, X051, X052, X053, X054, X055, X056, X057, X058, X059,
X060, X061, X062, X063, X064, X065, X066, X067, X068, X069,
X070, X071, X072, X073, X074, X075, X076, X077, X078, X079,
X080, X081, X082, X083, X084, X085, X086, X087, X088, X089,
X090, X091, X092, X093, X094, X095, X096, X097, X098, X099,
X100, X101, X102, X103, X104, X105, X106, X107, X108, X109,
X110, X111, X112, X113, X114, X115, X116, X117, X118, X119,
X120, X121, X122, X123, X124, X125, X126, X127, X128, X129,
X130, X131, X132, X133, X134, X135, X136, X137, X138, X139,
X140, X141, X142, X143, X144, X145, X146, X147, X148, X149,
X150, X151, X152, X153, X154, X155, X156, X157, X158, X159,
X160, X161, X162, X163, X164, X165, X166, X167, X168, X169,
X170, X171, X172, X173, X174, X175, X176, X177, X178, X179,
X180, X181, X182, X183, X184, X185, X186, X187, X188, X189,
X190, X191, X192, X193, X194, X195, X196, X197, X198, X199,
X200, X201, X202, X203, X204, X205, X206, X207, X208, X209,
X210, X211, X212, X213, X214, X215, X216, X217, X218, X219,
X220, X221, X222, X223, X224, X225, X226, X227, X228, X229,
X230, X231, X232, X233, X234, X235, X236, X237, X238, X239,
X240, X241, X242, X243, X244, X245, X246, X247, X248, X249,
X250, X251, X252, X253, X254, X255,
X256,
//~^ ERROR enum discriminant overflowed
//~| NOTE overflowed on value after 255
//~| NOTE explicitly set `X256 = 0`
//~| NOTE `0` assigned here
}

fn main() {
TooManyVariants::X256 as u8;
}
28 changes: 26 additions & 2 deletions tests/ui/error-codes/E0081.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,30 @@ LL |
LL | V9,
| -- `-2` assigned here

error: aborting due to 5 previous errors
error[E0370]: enum discriminant overflowed
--> $DIR/E0081.rs:87:5
|
LL | X256,
| ^^^^ overflowed on value after 255
|
= note: explicitly set `X256 = 0` if that is desired outcome

error[E0081]: discriminant value `0` assigned more than once
--> $DIR/E0081.rs:57:1
|
LL | enum TooManyVariants {
| ^^^^^^^^^^^^^^^^^^^^
LL |
LL | X000, X001, X002, X003, X004, X005, X006, X007, X008, X009,
| ----
| |
| `0` assigned here
| discriminant for `X256` incremented from this startpoint (`X000` + 256 variants later => `X256` = 0)
...
LL | X256,
| ---- `0` assigned here

error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0081`.
Some errors have detailed explanations: E0081, E0370.
For more information about an error, try `rustc --explain E0081`.

0 comments on commit ab4222a

Please sign in to comment.