mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 07:11:41 +00:00
[qfcc] Add a failing test case for if-super calls
The common idiom for self init (below) causes a double-call when compiling with --advanced, resulting in an incorrect retain count. if (!(self = [super init])) { return nil; }
This commit is contained in:
parent
2d3c2da64d
commit
bfda4e776f
3 changed files with 69 additions and 0 deletions
|
@ -29,6 +29,7 @@ test_progs_dat=\
|
||||||
tools/qfcc/test/func-expr2.dat \
|
tools/qfcc/test/func-expr2.dat \
|
||||||
tools/qfcc/test/func-static.dat \
|
tools/qfcc/test/func-static.dat \
|
||||||
tools/qfcc/test/gcd.dat \
|
tools/qfcc/test/gcd.dat \
|
||||||
|
tools/qfcc/test/ifsuper.dat \
|
||||||
tools/qfcc/test/infloop.dat \
|
tools/qfcc/test/infloop.dat \
|
||||||
tools/qfcc/test/iterfunc.dat \
|
tools/qfcc/test/iterfunc.dat \
|
||||||
tools/qfcc/test/ivar-struct-return.dat \
|
tools/qfcc/test/ivar-struct-return.dat \
|
||||||
|
@ -369,6 +370,16 @@ tools/qfcc/test/gcd.run: $(qfcc_test_run_deps)
|
||||||
include $(gcd_dep) # am--include-marker
|
include $(gcd_dep) # am--include-marker
|
||||||
pas_depfiles_remade += $(gcd_dep)
|
pas_depfiles_remade += $(gcd_dep)
|
||||||
|
|
||||||
|
tools_qfcc_test_ifsuper_dat_SOURCES=tools/qfcc/test/ifsuper.r
|
||||||
|
ifsuper_obj=$(tools_qfcc_test_ifsuper_dat_SOURCES:.r=.o)
|
||||||
|
ifsuper_dep=$(call qcautodep,$(tools_qfcc_test_ifsuper_dat_SOURCES))
|
||||||
|
tools/qfcc/test/ifsuper.dat$(EXEEXT): $(ifsuper_obj) $(QFCC_DEP)
|
||||||
|
$(V_QFCCLD)$(QLINK) --advanced -o $@ $(ifsuper_obj)
|
||||||
|
tools/qfcc/test/ifsuper.run: $(qfcc_test_run_deps)
|
||||||
|
@$(top_srcdir)/tools/qfcc/test/build-run $@
|
||||||
|
include $(ifsuper_dep) # am--include-marker
|
||||||
|
r_depfiles_remade += $(ifsuper_dep)
|
||||||
|
|
||||||
tools_qfcc_test_infloop_dat_SOURCES=tools/qfcc/test/infloop.r
|
tools_qfcc_test_infloop_dat_SOURCES=tools/qfcc/test/infloop.r
|
||||||
infloop_obj=$(tools_qfcc_test_infloop_dat_SOURCES:.r=.o)
|
infloop_obj=$(tools_qfcc_test_infloop_dat_SOURCES:.r=.o)
|
||||||
infloop_dep=$(call qcautodep,$(tools_qfcc_test_infloop_dat_SOURCES))
|
infloop_dep=$(call qcautodep,$(tools_qfcc_test_infloop_dat_SOURCES))
|
||||||
|
|
56
tools/qfcc/test/ifsuper.r
Normal file
56
tools/qfcc/test/ifsuper.r
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#pragma advanced
|
||||||
|
#include "test-harness.h"
|
||||||
|
|
||||||
|
int obj_increment_retaincount (id object) = #0;
|
||||||
|
int obj_get_retaincount (id object) = #0;
|
||||||
|
id (Class class) class_create_instance = #0;
|
||||||
|
id obj_msgSend_super (Super *class, SEL op, ...) = #0;
|
||||||
|
|
||||||
|
@interface Object
|
||||||
|
{
|
||||||
|
Class isa;
|
||||||
|
}
|
||||||
|
+(id) alloc;
|
||||||
|
-(id) init;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface Foo : Object
|
||||||
|
-(id) init;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Object
|
||||||
|
+(id) alloc
|
||||||
|
{
|
||||||
|
return class_create_instance (self);
|
||||||
|
}
|
||||||
|
-(id) init
|
||||||
|
{
|
||||||
|
obj_increment_retaincount (self);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Foo
|
||||||
|
-(id) init
|
||||||
|
{
|
||||||
|
if (!(self = [super init])) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
Foo *foo = [[Foo alloc] init];
|
||||||
|
if (!foo) {
|
||||||
|
printf ("foo is nil\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int retain = obj_get_retaincount (foo);
|
||||||
|
if (retain != 1) {
|
||||||
|
printf ("retain count != 1: %d\n", retain);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -3,6 +3,8 @@ void printf (string fmt, ...) = #0;
|
||||||
int errno (void) = #0;
|
int errno (void) = #0;
|
||||||
string strerror (int err) = #0;
|
string strerror (int err) = #0;
|
||||||
void exit (int code) = #0;
|
void exit (int code) = #0;
|
||||||
|
void traceon (void) = #0;
|
||||||
|
void traceoff (void) = #0;
|
||||||
entity spawn (void) = #0;
|
entity spawn (void) = #0;
|
||||||
void remove (entity e) = #0;
|
void remove (entity e) = #0;
|
||||||
id obj_msgSend (id receiver, SEL op, ...) = #0;
|
id obj_msgSend (id receiver, SEL op, ...) = #0;
|
||||||
|
|
Loading…
Reference in a new issue