Skip to content

Commit 7aaba19

Browse files
cirrasfourls
authored andcommitted
Fix ambiguous type comparisons from variants to real types
`Variant` -> `Double` and `Variant` -> `Extended` were being treated as equally good conversions on toolchains where `Double` and `Extended` are the same size, such as `DCC64`.
1 parent c318277 commit 7aaba19

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
12+
- Ambiguous type comparisons from variants to real types.
13+
1014
## [1.17.1] - 2025-06-10
1115

1216
### Fixed

delphi-frontend/src/main/java/au/com/integradev/delphi/symbol/resolve/InvocationResolver.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ private static int isBetterVariantConversion(Type current, Type best) {
530530
.compare(current, best, Comparator.comparing(InvocationResolver::isIInterface))
531531
.compare(current, best, Comparator.comparing(Type::isUntyped))
532532
.compare(current, best, InvocationResolver::compareNumericType)
533-
.compare(current, best, InvocationResolver::compareRealSize)
533+
.compare(current, best, InvocationResolver::compareRealTypes)
534534
.compare(current, best, InvocationResolver::compareIntegerRange)
535535
.compare(current, best, InvocationResolver::compareStringType)
536536
.result();
@@ -550,14 +550,30 @@ private static int compareNumericType(Type a, Type b) {
550550
}
551551
}
552552

553-
private static int compareRealSize(Type a, Type b) {
553+
private static int compareRealTypes(Type a, Type b) {
554554
if (!a.isReal() || !b.isReal()) {
555555
return 0;
556556
}
557+
557558
if (isCurrencyCompConflict(a, b) || isCurrencyCompConflict(b, a)) {
558559
return 0;
559560
}
560-
return Objects.compare(a, b, Comparator.comparingInt(Type::size));
561+
562+
return Comparator.<Type>comparingInt(
563+
type -> {
564+
type = TypeUtils.findBaseType(type);
565+
if (type.is(IntrinsicType.EXTENDED)) {
566+
return 1;
567+
} else if (type.is(IntrinsicType.DOUBLE)) {
568+
return 2;
569+
} else if (type.is(IntrinsicType.REAL48)) {
570+
return 3;
571+
} else {
572+
return 4;
573+
}
574+
})
575+
.reversed()
576+
.compare(a, b);
561577
}
562578

563579
private static boolean isCurrencyCompConflict(Type currencyComp, Type real) {

delphi-frontend/src/test/java/au/com/integradev/delphi/symbol/resolve/InvocationResolverTest.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,7 @@ void testVariantTypes(Toolchain toolchain) {
365365
assertResolved(type(VARIANT), TypeFactory.untypedType(), type(UNICODESTRING));
366366
assertResolved(type(VARIANT), TypeFactory.untypedType(), type(BOOLEAN));
367367

368-
assertResolved(type(VARIANT), type(EXTENDED), type(CURRENCY));
369368
assertResolved(type(VARIANT), type(CURRENCY), type(UINT64));
370-
assertResolved(type(VARIANT), type(EXTENDED), type(COMP));
371369
assertResolved(type(VARIANT), type(COMP), type(UINT64));
372370

373371
assertAmbiguous(type(VARIANT), type(CURRENCY), type(DOUBLE));
@@ -418,6 +416,19 @@ void testVariantTypes(Toolchain toolchain) {
418416
assertIncompatible(type(VARIANT), type(ANSICHAR));
419417
}
420418

419+
@Test
420+
void testVariantToExtendedCurrencyShouldResolveOnDcc32() {
421+
assertResolved(type(VARIANT), type(EXTENDED), type(CURRENCY));
422+
assertResolved(type(VARIANT), type(EXTENDED), type(COMP));
423+
}
424+
425+
@Test
426+
void testVariantToExtendedCurrencyShouldBeAmbiguousOnDcc64() {
427+
factory = new TypeFactoryImpl(Toolchain.DCC64, DelphiProperties.COMPILER_VERSION_DEFAULT);
428+
assertAmbiguous(type(VARIANT), type(EXTENDED), type(CURRENCY));
429+
assertAmbiguous(type(VARIANT), type(EXTENDED), type(COMP));
430+
}
431+
421432
@Test
422433
void testInheritedTypes() {
423434
Type grandparent = TypeMocker.struct("Grandparent", CLASS);

0 commit comments

Comments
 (0)