[qfcc] Add failing test for array-typedef interaction

Two variables declared as arrays (same size) of different typedefs to
the same base type have their type encodings both pointing to the same
short alias.

From vkgen:

    51d3  ty_array  [4={int32_t>i}]      207f  0 4
    51d9  ty_array  [4=i]                1035  0 4
    51df  ty_alias  {>[4=i]}              16  51d9  51e6
    51e6  ty_array  [4={uint32_t>i}]     2063  0 4
    51ec  ty_union  {tag VkClearColorValue-} tag VkClearColorValue
	    4ca0     0 float32
	    51df     0 int32
	    51df     0 uint32

uint32 should use 51e6 and int32 should use 513d,
This commit is contained in:
Bill Currie 2023-06-29 23:33:54 +09:00
parent 56d33d1b98
commit dc61d15340
3 changed files with 120 additions and 2 deletions

View File

@ -149,7 +149,7 @@ init_qf (void)
//Cvar_Set (developer, "1");
Memory_Init (Sys_Alloc (8 * 1024 * 1024), 8 * 1024 * 1024);
Memory_Init (Sys_Alloc (32 * 1024 * 1024), 32 * 1024 * 1024);
PR_Init_Cvars ();
}
@ -242,7 +242,7 @@ load_progs (progs_t *pr, const char *name)
}
pr->progs_name = name;
pr->max_edicts = 1;
pr->zone_size = 2*1024*1024;
pr->zone_size = 8*1024*1024;
pr->stack_size = 64*1024;
PR_LoadProgsFile (pr, file, size);
Qclose (file);

View File

@ -12,6 +12,7 @@ test_progs_dat=\
tools/qfcc/test/alignment.dat \
tools/qfcc/test/arraylife.dat \
tools/qfcc/test/arraylife2.dat \
tools/qfcc/test/arraytypedef.dat \
tools/qfcc/test/assignchain.dat \
tools/qfcc/test/anonstruct.dat \
tools/qfcc/test/chewed-alias.dat \
@ -179,6 +180,16 @@ tools/qfcc/test/arraylife2.run: $(qfcc_test_run_deps)
include $(arraylife2_dep) # am--include-marker
r_depfiles_remade += $(arraylife2_dep)
tools_qfcc_test_arraytypedef_dat_SOURCES=tools/qfcc/test/arraytypedef.r
arraytypedef_obj=$(tools_qfcc_test_arraytypedef_dat_SOURCES:.r=.o)
arraytypedef_dep=$(call qcautodep,$(tools_qfcc_test_arraytypedef_dat_SOURCES))
tools/qfcc/test/arraytypedef.dat$(EXEEXT): $(arraytypedef_obj) $(QFCC_DEP)
$(V_QFCCLD)$(QLINK) -o $@ $(arraytypedef_obj)
tools/qfcc/test/arraytypedef.run: $(qfcc_test_run_deps)
@$(top_srcdir)/tools/qfcc/test/build-run $@
include $(arraytypedef_dep) # am--include-marker
r_depfiles_remade += $(arraytypedef_dep)
tools_qfcc_test_assignchain_dat_SOURCES=tools/qfcc/test/assignchain.r
assignchain_obj=$(tools_qfcc_test_assignchain_dat_SOURCES:.r=.o)
assignchain_dep=$(call qcautodep,$(tools_qfcc_test_assignchain_dat_SOURCES))

View File

@ -0,0 +1,107 @@
typedef int int32_t;
typedef int uint32_t;
int32_t foo[4];
uint32_t bar[4];
#include <types.h>
// can't link against libr.a (may not be built)
void *PR_FindGlobal (string name) = #0;
void printf (string fmt, ...) = #0;
qfot_type_encodings_t *encodings;
qfot_type_t *
next_type (qfot_type_t *type)
{
int size = type.size;
if (!size)
size = 4;
return (qfot_type_t *) ((int *) type + size);
}
typedef struct xdef_s {
qfot_type_t *type; ///< pointer to type definition
void *addr; ///< 32-bit version of ddef_t.ofs
} xdef_t;
typedef struct xdefs_s {
xdef_t *xdefs;
unsigned num_xdefs;
} xdefs_t;
xdef_t *
find_xdef (string varname)
{
void *varaddr = PR_FindGlobal (varname);
if (!varname) {
return nil;
}
//FIXME need a simple way to get at a def's meta-data
xdefs_t *xdefs = PR_FindGlobal (".xdefs");
xdef_t *xdef = xdefs.xdefs;
while (xdef - xdefs.xdefs < xdefs.num_xdefs && xdef.addr != varaddr) {
xdef++;
}
if (xdef.addr != varaddr) {
return nil;
}
return xdef;
}
int
check_alias (string name, qfot_type_t *alias)
{
if (alias.meta != ty_basic || alias.type != ev_int) {
printf ("%s is not an int alias\n", name);
return 0;
}
return 1;
}
int
main (void)
{
qfot_type_t *type;
encodings = PR_FindGlobal (".type_encodings");
xdef_t *foo_var = find_xdef ("foo");
xdef_t *bar_var = find_xdef ("bar");
if (!(foo_var && bar_var)) {
printf ("missing var: foo: %d bar:%d\n", foo_var, bar_var);
return 1;
}
printf ("typedef: foo: x:%p t:%p a:%p bar: x:%p t:%p a:%p\n",
foo_var, foo_var.type, foo_var.addr,
bar_var, bar_var.type, bar_var.addr);
if (foo_var.type == bar_var.type) {
printf ("foo and bar have the same full type: %p %p\n",
foo_var.type, bar_var.type);
return 1;
}
#if 0
int found_foo = 0;
int found_bar = 0;
for (type = encodings.types;
((int *)type - (int *) encodings.types) < encodings.size;
type = next_type (type)) {
if (type.meta == ty_alias) {
if (type.alias.name == "int32_t") {
found_foo = check_alias (type.alias.name,
type.alias.aux_type);
}
if (type.alias.name == "uint32_t") {
found_bar = check_alias (type.alias.name,
type.alias.aux_type);
}
}
}
if (!(found_bar && found_foo)) {
printf ("missing typedef: int32_t: %d uint32_t: %d\n", found_foo, found_bar);
return 1;
}
#endif
return 0;
}