Opened 4 months ago
#309 new defect
Resolver selects arbitrary candidate from ambiguity when return types are reused
Reported by: | mlbrooks | Owned by: | |
---|---|---|---|
Priority: | major | Component: | cfa-cc |
Version: | 1.0 | Keywords: | candidate ambiguous return |
Cc: |
Description
struct Cat{}; struct Dog{}; struct X{}; struct Y{}; struct Z{}; Cat foo(X) { printf("a\n"); } Cat foo(Y) { printf("b\n"); } Dog foo(Z) { printf("c\n"); } X bar(double) { printf("1-"); } Y bar(double) { printf("2-"); } Z bar(int) { printf("3-"); } void fred() { foo(bar(3.14)); // HERE } int main() { fred(); return 0; }
Actual: Compiles, runs, prints, "3-c."
Expected: Ambiguous at HERE: Cannot decide between 1-a and 2-b.
Comment out options 1 or a to see 2b get picked. Shows 2b < 3c.
Comment out options 2 or b to see 1a get picked. Shows 1a < 3c.
Comment out options 3 or c to see ambiguity. Shows 1a = 2b.
Therefore, expected handling for the all-in scenario is ambiguity among 1a and 2b. But it actually picks 3c.
So, here, the all-in answer is picking a non-cheapest alternative (3c) when 1a and 2a are available and cheaper.
Change return type of foo-a from Cat to int. Now, actual = expected = ambiguity among 1a and 2b.
A larger, more realistic, scenario, with a different dubious selection:
struct string{}; typedef signed long long int strmul_factor_t; string times(string, strmul_factor_t) { printf("times1( s=s*n )\n"); } string times(char, strmul_factor_t) { printf("times2( s=c*n )\n"); } string times(strmul_factor_t, string) { printf("times3( s=n*s )\n"); } string times(strmul_factor_t, char) { printf("times4( s=n*c )\n"); } int times(int, int) { printf("times5( i=i*i )\n"); } string plus(string, string) { printf("plusA( s=s+s ), "); } string plus(string, char) { printf("plusB( s=s+c ), "); } string plus(char, string) { printf("plusC( s=c+s ), "); } string plus(char, char) { printf("plusD( s=c+c ), "); } char plus(char, char) { printf("plusE( c=c+c ), "); } void fred() { times(plus('a', 'b'), 3); // HERE } int main() { fred(); return 0; }
Actual: Compiles, runs, prints, "plusE( c=c+c ), times5( i=i*i )."
Expected: Ambiguity at HERE: cannot choose between D1, E2, and E5.
Comment out times5: actual = expected = ambiguity among
- plusE( c=c+c ), times2( s=c*n )
- plusD( s=c+c ), times1( s=s*n )
Error message showing both with cost ( 0, 0, 0, 4, 0, 0, 0, 0 )
Comment out times2: actual = expected = get ambiguity among
- plusD( s=c+c ), times1( s=s*n )
- plusE( c=c+c ), times5( i=i*i )
Error message showing both with cost ( 0, 0, 0, 4, 0, 0, 0, 0 )
So, alternatives E2, D1 and E5 all have the same cost.
And this time, the all-in answer is picking one among equals.