Skip to content

Commit ac13722

Browse files
committed
Don't return the masked range from Scalar::range_metadata
1 parent c12d2f0 commit ac13722

File tree

3 files changed

+28
-30
lines changed

3 files changed

+28
-30
lines changed

src/librustc/ty/layout.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -650,16 +650,22 @@ impl Scalar {
650650
}
651651

652652
/// Returns a range suitable to be passed to LLVM for range metadata.
653-
pub fn range_metadata<C: HasDataLayout>(&self, cx: C) -> Range<u128> {
653+
pub fn range_metadata<C: HasDataLayout>(&self, cx: C) -> Option<Range<u128>> {
654654
// For a (max) value of -1, max will be `-1 as usize`, which overflows.
655655
// However, that is fine here (it would still represent the full range),
656656
// i.e., if the range is everything.
657657
let bits = self.value.size(cx).bits();
658658
assert!(bits <= 128);
659659
let mask = !0u128 >> (128 - bits);
660-
let start = self.valid_range.start & mask;
661-
let end = self.valid_range.end.wrapping_add(1) & mask;
662-
start..end
660+
let start = self.valid_range.start;
661+
let end = self.valid_range.end.wrapping_add(1);
662+
if start & mask == end & mask {
663+
// The lo==hi case would be rejected by the LLVM verifier
664+
// (it would mean either an empty set, which is impossible, or the
665+
// entire range of the type, which is pointless).
666+
return None;
667+
}
668+
Some(start..end)
663669
}
664670
}
665671

src/librustc_trans/abi.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,20 +1056,16 @@ impl<'a, 'tcx> FnType<'tcx> {
10561056
_ => {}
10571057
}
10581058
if let layout::Abi::Scalar(ref scalar) = self.ret.layout.abi {
1059-
let range = scalar.range_metadata(bx.cx);
1060-
// The lo==hi case would be rejected by the LLVM verifier
1061-
// (it would mean either an empty set, which is impossible, or the
1062-
// entire range of the type, which is pointless).
1063-
//
1064-
// If the value is a boolean, the range is 0..2 and that ultimately
1065-
// become 0..0 when the type becomes i1.
1066-
match scalar.value {
1067-
layout::Int(..) if !scalar.is_bool() && range.start != range.end => {
1068-
// llvm::ConstantRange can deal with ranges that wrap around,
1069-
// so an overflow on (max + 1) is fine.
1070-
bx.range_metadata(callsite, range);
1059+
if let Some(range) = scalar.range_metadata(bx.cx) {
1060+
// If the value is a boolean, the range is 0..2 and that ultimately
1061+
// become 0..0 when the type becomes i1, which would be rejected
1062+
// by the LLVM verifier.
1063+
match scalar.value {
1064+
layout::Int(..) if !scalar.is_bool() => {
1065+
bx.range_metadata(callsite, range);
1066+
}
1067+
_ => {}
10711068
}
1072-
_ => {}
10731069
}
10741070
}
10751071
for arg in &self.args {

src/librustc_trans/mir/place.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,20 +91,16 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
9191
}
9292

9393
let scalar_load_metadata = |load, scalar: &layout::Scalar| {
94-
let range = scalar.range_metadata(bx.cx);
95-
// The lo==hi case would be rejected by the LLVM verifier
96-
// (it would mean either an empty set, which is impossible, or the
97-
// entire range of the type, which is pointless).
98-
match scalar.value {
99-
layout::Int(..) if range.start != range.end => {
100-
// llvm::ConstantRange can deal with ranges that wrap around,
101-
// so an overflow on (max + 1) is fine.
102-
bx.range_metadata(load, range);
103-
}
104-
layout::Pointer if 0 < range.start && range.start < range.end => {
105-
bx.nonnull_metadata(load);
94+
if let Some(range) = scalar.range_metadata(bx.cx) {
95+
match scalar.value {
96+
layout::Int(..) => {
97+
bx.range_metadata(load, range);
98+
}
99+
layout::Pointer if 0 < range.start && range.start < range.end => {
100+
bx.nonnull_metadata(load);
101+
}
102+
_ => {}
106103
}
107-
_ => {}
108104
}
109105
};
110106

0 commit comments

Comments
 (0)