Opened 4 years ago

Closed 2 years ago

#214 closed defect (fixed)

Assertion with sized generic parameter breaks the declaring function's body

Reported by: m3zulfiq Owned by:
Priority: major Component: cfa-cc
Version: 1.0 Keywords: dtype, ttype, generic struct, union
Cc:

Description (last modified by mlbrooks)

A sized generic struct cannot be instantiated in a function with an assertion that takes this struct as a parameter.

forall( otype X )
struct wrapper { X item; };

forall( otype Y 
                #ifndef HIDE_ERROR
                                    | { void unusedHelper( wrapper(Y) ); }
                #endif
      )
void f() {
    wrapper(Y) myvar;
}

Actual (plain): GCC error: '_sizeof_S7wrapper_Y1Y_' undeclared
Actual (-DHIDE_ERROR), Expected (both): Compiler success

Desired for the following case in the memory allocator. Here, the affected function is balloc, whose assertion for $balloc_internal takes a parameter of type SS_fill(T). In the affected function's body, the object declaration where the failure happens is the (SS_fill(T)){...} argument initializer.

forall( dtype T | sized(T) ) {
	union  U_fill 	{ char c; T * a; T t; };
	struct SS_fill 	{ char tag; U_fill(T) fill; };
}

static inline forall( dtype T | sized(T) ) {
	T * $balloc_internal( void * Resize, void * Realloc, size_t Align, size_t Dim, SS_fill(T) Fill) {
		return (T*)0p;
	} // $balloc_internal

	forall( ttype TT | { T * $balloc_internal( void *, void *, size_t, size_t, SS_fill(T), TT ); } ) {
	    T * balloc( TT all ) {
	        return $balloc_internal( (void*)0p, (void*)0p, 16, 1, (SS_fill(T)){'0', (U_fill(T)){'0'}}, all);
	    } // balloc
	} // distribution TT
} // distribution T

int main() {
	int * abc = balloc();
	free(abc);
	return 0;
}

Actual: GCC error: '_sizeof_S7SS_fill_Y1T_' undeclared
Expected: Compiler success

This revision shows the assertion is at fault (but it does not provide a workaround). The assumption of a TT-fitting $balloc_internal is changed from an assertion to a declaration.

forall( dtype T | sized(T) ) {
	union  U_fill 	{ char c; T * a; T t; };
	struct SS_fill 	{ char tag; U_fill(T) fill; };
}

static inline forall( dtype T | sized(T) ) {
	T * $balloc_internal( void * Resize, void * Realloc, size_t Align, size_t Dim, SS_fill(T) Fill) {
		return (T*)0p;
	} // $balloc_internal

	forall( ttype TT ) {
	    T * $balloc_internal( void *, void *, size_t, size_t, SS_fill(T), TT );
	    T * balloc( TT all ) {
	        return $balloc_internal( (void*)0p, (void*)0p, 16, 1, (SS_fill(T)){'0', (U_fill(T)){'0'}}, all);
	    } // balloc
	} // distribution TT
} // distribution T

int main() {
	int * abc = balloc();
	free(abc);
	return 0;
}

Actual and expected: Compiler success, linker failure to find $balloc_internal( ..., TT ).

Change History (3)

comment:1 Changed 4 years ago by m3zulfiq

Once this ticket is resolved, alloc interface in stdlib.hfa should be fixed to support the const object of dtype T of any size for filling dynamic memory.

comment:2 Changed 4 years ago by mlbrooks

Description: modified (diff)
Summary: C Errors in dtype/ttype combination with Generic struct/unionAssertion with sized generic parameter breaks the declaring function's body

comment:3 Changed 2 years ago by Thierry Delisle

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.