[qfcc] Add failing test for multi-path dealloc

This test checks for control reaching the end of the function without
invoking [super dealloc] in all paths.
This commit is contained in:
Bill Currie 2021-12-24 14:20:40 +09:00
parent 8385046486
commit 79b760b1d0
3 changed files with 102 additions and 0 deletions

View file

@ -18,6 +18,7 @@ test_progs_dat=\
tools/qfcc/test/compound.dat \ tools/qfcc/test/compound.dat \
tools/qfcc/test/deadbool.dat \ tools/qfcc/test/deadbool.dat \
tools/qfcc/test/dealloc-nowarn.dat \ tools/qfcc/test/dealloc-nowarn.dat \
tools/qfcc/test/dealloc-nowarn2.dat \
tools/qfcc/test/double.dat \ tools/qfcc/test/double.dat \
tools/qfcc/test/double-alias.dat \ tools/qfcc/test/double-alias.dat \
tools/qfcc/test/enum.dat \ tools/qfcc/test/enum.dat \
@ -66,6 +67,7 @@ test_build_errors=\
tools/qfcc/test/classarray.r \ tools/qfcc/test/classarray.r \
tools/qfcc/test/dealloc-warn.r \ tools/qfcc/test/dealloc-warn.r \
tools/qfcc/test/dealloc-warn2.r \ tools/qfcc/test/dealloc-warn2.r \
tools/qfcc/test/dealloc-warn3.r \
tools/qfcc/test/double-demote-float.r \ tools/qfcc/test/double-demote-float.r \
tools/qfcc/test/double-demote-float-ainit.r \ tools/qfcc/test/double-demote-float-ainit.r \
tools/qfcc/test/double-demote-float-ginit.r \ tools/qfcc/test/double-demote-float-ginit.r \
@ -206,6 +208,16 @@ tools/qfcc/test/dealloc-nowarn.run: $(qfcc_test_run_deps)
include $(dealloc_nowarn_dep) # am--include-marker include $(dealloc_nowarn_dep) # am--include-marker
r_depfiles_remade += $(dealloc_nowarn_dep) r_depfiles_remade += $(dealloc_nowarn_dep)
tools_qfcc_test_dealloc_nowarn2_dat_SOURCES=tools/qfcc/test/dealloc-nowarn2.r
dealloc_nowarn2_obj=$(tools_qfcc_test_dealloc_nowarn2_dat_SOURCES:.r=.o)
dealloc_nowarn2_dep=$(call qcautodep,$(tools_qfcc_test_dealloc_nowarn2_dat_SOURCES))
tools/qfcc/test/dealloc-nowarn2.dat$(EXEEXT): $(dealloc_nowarn2_obj) $(QFCC_DEP)
$(V_QFCCLD)$(QLINK) -o $@ $(dealloc_nowarn2_obj)
tools/qfcc/test/dealloc-nowarn2.run: $(qfcc_test_run_deps)
@$(top_srcdir)/tools/qfcc/test/build-run $@
include $(dealloc_nowarn2_dep) # am--include-marker
r_depfiles_remade += $(dealloc_nowarn2_dep)
tools_qfcc_test_double_dat_SOURCES=tools/qfcc/test/double.r tools_qfcc_test_double_dat_SOURCES=tools/qfcc/test/double.r
double_obj=$(tools_qfcc_test_double_dat_SOURCES:.r=.o) double_obj=$(tools_qfcc_test_double_dat_SOURCES:.r=.o)
double_dep=$(call qcautodep,$(tools_qfcc_test_double_dat_SOURCES)) double_dep=$(call qcautodep,$(tools_qfcc_test_double_dat_SOURCES))
@ -235,6 +247,9 @@ tools/qfcc/test/dealloc-warn.run$(EXEEXT): tools/qfcc/test/dealloc-warn.r $(qfcc
tools/qfcc/test/dealloc-warn2.run$(EXEEXT): tools/qfcc/test/dealloc-warn2.r $(qfcc_fail_run_deps) tools/qfcc/test/dealloc-warn2.run$(EXEEXT): tools/qfcc/test/dealloc-warn2.r $(qfcc_fail_run_deps)
@$(top_srcdir)/tools/qfcc/test/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $< @$(top_srcdir)/tools/qfcc/test/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $<
tools/qfcc/test/dealloc-warn3.run$(EXEEXT): tools/qfcc/test/dealloc-warn3.r $(qfcc_fail_run_deps)
@$(top_srcdir)/tools/qfcc/test/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $<
tools/qfcc/test/double-demote-int.run$(EXEEXT): tools/qfcc/test/double-demote-int.r $(qfcc_fail_run_deps) tools/qfcc/test/double-demote-int.run$(EXEEXT): tools/qfcc/test/double-demote-int.r $(qfcc_fail_run_deps)
@$(top_srcdir)/tools/qfcc/test/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $< @$(top_srcdir)/tools/qfcc/test/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $<

View file

@ -0,0 +1,43 @@
@interface Object
{
Class isa;
}
-(void)dealloc;
@end
@interface derived : Object
{
int free;
}
@end
@implementation Object
-(void) dealloc
{
// this is the root of the hierarchy, so no super to call, thus
// must not check for [super dealloc]
}
@end
void __obj_exec_class (struct obj_module *msg) = #0;
id obj_msgSend_super (Super *class, SEL op, ...) = #0;
@implementation derived
-(void) dealloc
{
// as this is a derived class, failure to call [super dealloc] will
// result in a memory leak (yes, there could be special allocators
// involved, in which case something will be needed to inform the
// compiler)
if (free) {
[super dealloc];
} else {
[super dealloc];
}
}
@end
int main ()
{
return 0; // test passes if compile succeeds (with -Werror)
}

View file

@ -0,0 +1,44 @@
@interface Object
{
Class isa;
}
-(void)dealloc;
@end
@interface derived : Object
{
int free;
}
@end
@implementation Object
-(void) dealloc
{
// this is the root of the hierarchy, so no super to call, thus
// must not check for [super dealloc]
}
-(void) release
{
}
@end
@implementation derived
-(void) dealloc
{
// as this is a derived class, failure to call [super dealloc] will
// result in a memory leak (yes, there could be special allocators
// involved, in which case something will be needed to inform the
// compiler)
if (free) {
[super dealloc];
}
}
@end
void __obj_exec_class (struct obj_module *msg) = #0;
id obj_msgSend_super (Super *class, SEL op, ...) = #0;
int main ()
{
return 1; // test fails if compile succeeds (with -Werror)
}