Opened 5 years ago
#207 new enhancement
Safe const variations are not considered for assertion satisfaction
| Reported by: | mlbrooks | Owned by: | |
|---|---|---|---|
| Priority: | minor | Component: | cfa-cc |
| Version: | 1.0 | Keywords: | |
| Cc: |
Description
Assertion satisfaction is invariant in the function type, but it should be cotravariant in the function's parameters and covariant in the function's returns:
A function that consumes a const reference does not satisfy an assertion for a function that consumes a mutation-allowed reference A function that produces a mutation-allowed reference does not satisfy an assertion for a function that produces a const reference
#ifndef QPROD
#define QPROD
#endif
#ifndef QCONS
#define QCONS
#endif
forall( | { void helpConsume( QCONS int * );
QPROD int * helpProduce( ); } )
void f() {
int copy = * helpProduce();
helpConsume( & copy );
}
void helpConsume(int * x) {
printf( "got %d\n", *x );
}
int *helpProduce() {
static int theVal = 17;
return & theVal;
}
int main() {
f();
}
expected -DQPROD=const, expected -DCONS=const, actual plain: compile succeeds; program prints "got 17"
actual -DQPROD=const: No alternatives with satisfiable assertions for Applying ... f ... Could not satisfy assertion: helpProduce
actual -DQCONS=const: No alternatives with satisfiable assertions for Applying ... f ... Could not satisfy assertion: helpConsume
A practical example occurs in the sout ?|? treatment of tuples. The intuition is if a type T is has sout | T then by that it also has sout | [ ... T ... ].
We want and have sout | const char *. It is and should be usable as sout | char *. It is and should be usable to satisfy sout | [ ... const char * ...]. It should be, but by this bug is not, usable to satisfy sout | [ ... char * ...].
int main() {
sout | "one";
sout | 2;
#ifdef WORKAROUND
sout | [ ( const char * ) "three", 4 ];
#else
sout | [ "three", 4 ];
#endif
}
expected plain, actual -DWORKAROUND: compiles and runs with
one 2 three, 4
actual plain: No alternatives with satisfiable assertions for Applying untyped: Name: ?|? to: Name: sout, Untyped Tuple ...