Opened 4 months 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
}

Change History (0)

Note: See TracTickets for help on using tickets.