Opened 4 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 ...