Opened 3 years ago
#264 new defect
Can't compile direct call of a function pointer that's a member of a struct returned by reference
| Reported by: | mlbrooks | Owned by: | |
|---|---|---|---|
| Priority: | minor | Component: | cfa-cc |
| Version: | 1.0 | Keywords: | |
| Cc: |
Description
struct Dog {
void (*bark)(void);
};
Dog & getFido()
#ifdef SUPPRESS_RUNTIME_DEMO_CRUFT
;
#else
{
// runtime demo cruft is: Fido is a singleton dog whose bark is to print "hi"
void sayHi(void) {
printf("hi\n");
}
void ?{}( Dog & this ) {
this.bark = sayHi;
}
static Dog fido;
return fido;
}
#endif
int main() {
// indirect call
Dog & d = getFido();
d.bark();
#ifndef SUPPRESS_AT_ISSUE_COMPILE_ERROR
// direct call
getFido().bark();
#endif
}
/*
#1
$cfa x.cfa; ./a.out
ACTUAL: CFA compiler error: Attempt to take address of non-lvalue expression: pointer to instance of struct Dog with body 1
EXPECTED: compiles, runs, prints "hi" twice
#2
$cfa x.cfa -DSUPPRESS_RUNTIME_DEMO_CRUFT; ./a.out
ACTUAL: same as #1 actual
EXPECTED: same as #4 expected
#3
$cfa x.cfa -DSUPPRESS_AT_ISSUE_COMPILE_ERROR; ./a.out
ACTUAL, EXPECTED: compiles, runs, prints "hi" once
#4
$cfa x.cfa -DSUPPRESS_AT_ISSUE_COMPILE_ERROR -DSUPPRESS_RUNTIME_DEMO_CRUFT; ./a.out
ACTUAL, EXPECTED: compiles, linker error finding getFido
*/
Originally discovered by Thierry with the following, more applied, repro.
#include <assert.h>
#include <containers/array.hfa>
struct S {
void (*foo)(void *);
void * bar;
};
forall([N])
void works( array( struct S, N ) & arr ) {
void * val = arr[0].bar;
void (*func)(void * ) = arr[0].foo;
assert( func == arr[0].foo );
func( val );
#ifndef SUPPRESS_AT_ISSUE_COMPILE_ERROR
arr[0].foo( val );
#endif
}
Note:
See TracTickets
for help on using tickets.