Prevent overflowing enum cast from ICEing

This commit is contained in:
clubby789 2024-10-18 22:05:31 +00:00
parent f7b5e5471b
commit ab4222ad97
3 changed files with 77 additions and 4 deletions

View File

@ -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 });

View File

@ -50,5 +50,47 @@ enum MultipleDuplicates {
//~^ NOTE `-2` assigned here
}
fn main() {
// 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;
}

View File

@ -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
For more information about this error, try `rustc --explain E0081`.
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
Some errors have detailed explanations: E0081, E0370.
For more information about an error, try `rustc --explain E0081`.