Skip to content

Commit f14745c

Browse files
committed
Added some sanity checks to function call compilation. This will catch *some* cases of ABI mismatch.
1 parent ac500d4 commit f14745c

File tree

2 files changed

+62
-11
lines changed

2 files changed

+62
-11
lines changed

src/builder.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -270,18 +270,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
270270
actual_val.dereference(self.location).to_rvalue()
271271
}
272272
} else {
273-
// FIXME: this condition seems wrong: it will pass when both types are not
274-
// a vector.
273+
// Check that the types are not "known to mismatch" or are vectors
275274
assert!(
276-
(!expected_ty.is_vector() || actual_ty.is_vector())
277-
&& (expected_ty.is_vector() || !actual_ty.is_vector()),
278-
"{:?} (is vector: {}) -> {:?} (is vector: {}), Function: {:?}[{}]",
279-
actual_ty,
280-
actual_ty.is_vector(),
281-
expected_ty,
282-
expected_ty.is_vector(),
283-
func_ptr,
284-
index
275+
expected_ty.known_eq(&actual_ty, self.cx).unwrap_or(true)
276+
|| expected_ty.is_vector() && actual_ty.is_vector(),
277+
"{actual_ty:?} -> {expected_ty:?}, Function: {func_ptr:?}[{index}]"
285278
);
286279
// TODO(antoyo): perhaps use __builtin_convertvector for vector casting.
287280
// TODO: remove bitcast now that vector types can be compared?

src/common.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,10 @@ pub trait TypeReflection<'gcc, 'tcx> {
425425
fn is_u128(&self, cx: &CodegenCx<'gcc, 'tcx>) -> bool;
426426

427427
fn is_vector(&self) -> bool;
428+
/// Checks if 2 types are "known to be equal". Returns Some(true) if types are equal(e.g. bool and bool),
429+
/// Some(false) if they can't possibly be equal(e.g. a struct and a float), and None if there is no way
430+
/// to check for their equality(struct and struct)
431+
fn known_eq(&self, rhs: &Self, cx: &CodegenCx<'gcc, 'tcx>) -> Option<bool>;
428432
}
429433

430434
impl<'gcc, 'tcx> TypeReflection<'gcc, 'tcx> for Type<'gcc> {
@@ -524,4 +528,58 @@ impl<'gcc, 'tcx> TypeReflection<'gcc, 'tcx> for Type<'gcc> {
524528

525529
false
526530
}
531+
fn known_eq(&self, other: &Self, cx: &CodegenCx<'gcc, 'tcx>) -> Option<bool> {
532+
// "Happy" path: types represented using the same pointer
533+
if self == other {
534+
return Some(true);
535+
}
536+
if self.is_bool() {
537+
return Some(other.is_bool());
538+
} else if self.is_integral() {
539+
if !other.is_integral() {
540+
return Some(false);
541+
}
542+
return Some(
543+
(self.get_size() == other.get_size())
544+
&& (self.is_signed(cx) == other.is_signed(cx)),
545+
);
546+
} else if self.is_vector() {
547+
if !other.is_vector() {
548+
return Some(false);
549+
}
550+
return None;
551+
} else if self.is_struct().is_some() {
552+
if other.is_struct().is_none() {
553+
return Some(false);
554+
}
555+
return None;
556+
} else if let Some(s_ptr) = self.get_pointee() {
557+
let Some(other_ptr) = other.get_pointee() else {
558+
return Some(false);
559+
};
560+
return s_ptr.known_eq(&other_ptr, cx);
561+
}
562+
#[cfg(feature = "master")]
563+
if self.is_floating_point() {
564+
if !other.is_floating_point() {
565+
return Some(false);
566+
}
567+
return Some(self.get_size() == other.get_size());
568+
}
569+
#[cfg(not(feature = "master"))]
570+
{
571+
fn is_floating_point<'gcc>(ty: &Type<'gcc>, cx: &CodegenCx<'gcc, '_>) -> bool {
572+
ty.is_compatible_with(cx.context.new_type::<f32>())
573+
|| ty.is_compatible_with(cx.context.new_type::<f64>())
574+
}
575+
if is_floating_point(self, cx) {
576+
if !is_floating_point(self, cx) {
577+
return Some(false);
578+
}
579+
return Some(self.get_size() == other.get_size());
580+
}
581+
}
582+
// Unknown type...
583+
None
584+
}
527585
}

0 commit comments

Comments
 (0)