History

tests: add memory leak test

Also ... tcctest.c: - exclude stuff that gcc doesn't compile on windows. libtcc.c/tccpp.c: - use unsigned for memory sizes to avoid printf format warnings - use "file:line: message" to make IDE error parsers happy. tccgen.c: fix typo

grischka committed 9 years ago

Commit a1c12b91 parent f7fc4f07 files · +54 −37Browse files

Unified · Split

7 files
  1. libtcc.c +13 −10
  2. tcc.h +1 −0
  3. tccgen.c +5 −8
  4. tccpp.c +19 −16
  5. tests/Makefile +8 −1
  6. tests/tcctest.c +7 −1
  7. tests/tests2/Makefile +1 −1
libtcc.c+13−10
@@ -248,20 +248,20 @@ PUB_FUNC void tcc_memstats(int bench) · 247 unmodified lines
248#define MEM_DEBUG_FILE_LEN 15248#define MEM_DEBUG_FILE_LEN 15
249 249
250struct mem_debug_header {250struct mem_debug_header {
251 size_t magic1;251 unsigned magic1;
252 size_t size;252 unsigned size;
253 struct mem_debug_header *prev;253 struct mem_debug_header *prev;
254 struct mem_debug_header *next;254 struct mem_debug_header *next;
255 size_t line_num;255 int line_num;
256 char file_name[MEM_DEBUG_FILE_LEN + 1];256 char file_name[MEM_DEBUG_FILE_LEN + 1];
257 size_t magic2;257 unsigned magic2;
258};258};
259 259
260typedef struct mem_debug_header mem_debug_header_t;260typedef struct mem_debug_header mem_debug_header_t;
261 261
262static mem_debug_header_t *mem_debug_chain;262static mem_debug_header_t *mem_debug_chain;
263static size_t mem_cur_size;263static unsigned mem_cur_size;
264static size_t mem_max_size;264static unsigned mem_max_size;
265 265
266PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)266PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
267{267{
@@ -312,13 +312,13 @@ PUB_FUNC void tcc_free_debug(void *ptr) · 44 unmodified lines
312 header = (mem_debug_header_t *)ptr;312 header = (mem_debug_header_t *)ptr;
313 if (header->magic1 != MEM_DEBUG_MAGIC1 ||313 if (header->magic1 != MEM_DEBUG_MAGIC1 ||
314 header->magic2 != MEM_DEBUG_MAGIC2 ||314 header->magic2 != MEM_DEBUG_MAGIC2 ||
315 header->size == (size_t)-1 )315 header->size == (unsigned)-1 )
316 {316 {
317 tcc_error("tcc_free check failed");317 tcc_error("tcc_free check failed");
318 }318 }
319 319
320 mem_cur_size -= header->size;320 mem_cur_size -= header->size;
321 header->size = (size_t)-1;321 header->size = (unsigned)-1;
322 322
323 if (header->next)323 if (header->next)
324 header->next->prev = header->prev;324 header->next->prev = header->prev;
@@ -355,7 +355,7 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file · 30 unmodified lines
355 header = (mem_debug_header_t *)ptr;355 header = (mem_debug_header_t *)ptr;
356 if (header->magic1 != MEM_DEBUG_MAGIC1 ||356 if (header->magic1 != MEM_DEBUG_MAGIC1 ||
357 header->magic2 != MEM_DEBUG_MAGIC2 ||357 header->magic2 != MEM_DEBUG_MAGIC2 ||
358 header->size == (size_t)-1 )358 header->size == (unsigned)-1 )
359 {359 {
360 check_error:360 check_error:
361 tcc_error("tcc_realloc check failed");361 tcc_error("tcc_realloc check failed");
@@ -414,6 +414,9 @@ PUB_FUNC void tcc_memstats(int bench) · 52 unmodified lines
414 header->file_name, header->line_num, header->size);414 header->file_name, header->line_num, header->size);
415 header = header->next;415 header = header->next;
416 }416 }
417#if MEM_DEBUG-0 == 2
418 exit(2);
419#endif
417 }420 }
418 else if (bench)421 else if (bench)
419 fprintf(stderr, "mem_max_size= %d bytes\n", mem_max_size);422 fprintf(stderr, "mem_max_size= %d bytes\n", mem_max_size);
tcc.h+1−0
@@ -71,6 +71,7 @@ · 70 unmodified lines
71# pragma warning (disable : 4996) // The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name71# pragma warning (disable : 4996) // The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
72# pragma warning (disable : 4018) // signed/unsigned mismatch72# pragma warning (disable : 4018) // signed/unsigned mismatch
73# pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned73# pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
74# define ssize_t intptr_t
74# endif75# endif
75# undef CONFIG_TCC_STATIC76# undef CONFIG_TCC_STATIC
76#endif77#endif
tccgen.c+5−8
@@ -5288,8 +5288,8 @@ static void expr_cond(void) · 5287 unmodified lines
5288 5288
5289 /* this is horrible, but we must also convert first5289 /* this is horrible, but we must also convert first
5290 operand */5290 operand */
5291 vpushv(&sv);5291 if (c != 0) {
5292 if (c != 2) {5292 *vtop = sv;
5293 gen_cast(&type);5293 gen_cast(&type);
5294 if (islv) {5294 if (islv) {
5295 mk_pointer(&vtop->type);5295 mk_pointer(&vtop->type);
@@ -5298,17 +5298,14 @@ static void expr_cond(void) · 2 unmodified lines
5298 gaddrof();5298 gaddrof();
5299 }5299 }
5300 5300
5301 if (c != 0)
5302 vswap();
5303 vtop--;
5304 if (c < 0) {5301 if (c < 0) {
5305 r1 = gv(rc);5302 r1 = gv(rc);
5306 move_reg(r2, r1, type.t);5303 move_reg(r2, r1, type.t);
5307 vtop->r = r2;5304 vtop->r = r2;
5305 gsym(tt);
5306 if (islv)
5307 indir();
5308 }5308 }
5309 gsym(tt);
5310 if (islv)
5311 indir();
5312 }5309 }
5313 }5310 }
5314}5311}
tccpp.c+19−16
@@ -137,22 +137,22 @@ ST_FUNC void expect(const char *msg) · 136 unmodified lines
137#define CSTR_TAL_LIMIT 1024137#define CSTR_TAL_LIMIT 1024
138 138
139typedef struct TinyAlloc {139typedef struct TinyAlloc {
140 size_t limit;140 unsigned limit;
141 size_t size;141 unsigned size;
142 uint8_t *buffer;142 uint8_t *buffer;
143 uint8_t *p;143 uint8_t *p;
144 size_t nb_allocs;144 unsigned nb_allocs;
145 struct TinyAlloc *next, *top;145 struct TinyAlloc *next, *top;
146#ifdef TAL_INFO146#ifdef TAL_INFO
147 size_t nb_peak;147 unsigned nb_peak;
148 size_t nb_total;148 unsigned nb_total;
149 size_t nb_missed;149 unsigned nb_missed;
150 uint8_t *peak_p;150 uint8_t *peak_p;
151#endif151#endif
152} TinyAlloc;152} TinyAlloc;
153 153
154typedef struct tal_header_t {154typedef struct tal_header_t {
155 size_t size;155 unsigned size;
156#ifdef TAL_DEBUG156#ifdef TAL_DEBUG
157 int line_num; /* negative line_num used for double free check */157 int line_num; /* negative line_num used for double free check */
158 char file_name[TAL_DEBUG_FILE_LEN + 1];158 char file_name[TAL_DEBUG_FILE_LEN + 1];
@@ -161,7 +161,7 @@ typedef struct tal_header_t { · 2 unmodified lines
161 161
162/* ------------------------------------------------------------------------- */162/* ------------------------------------------------------------------------- */
163 163
164ST_FUNC TinyAlloc *tal_new(TinyAlloc **pal, size_t limit, size_t size)164static TinyAlloc *tal_new(TinyAlloc **pal, unsigned limit, unsigned size)
165{165{
166 TinyAlloc *al = tcc_mallocz(sizeof(TinyAlloc));166 TinyAlloc *al = tcc_mallocz(sizeof(TinyAlloc));
167 al->p = al->buffer = tcc_malloc(size);167 al->p = al->buffer = tcc_malloc(size);
@@ -171,7 +171,7 @@ ST_FUNC TinyAlloc *tal_new(TinyAlloc **pal, size_t limit, size_t size) · 3 unmodified lines
171 return al;171 return al;
172}172}
173 173
174ST_FUNC void tal_delete(TinyAlloc *al)174static void tal_delete(TinyAlloc *al)
175{175{
176 TinyAlloc *next;176 TinyAlloc *next;
177 177
@@ -192,11 +192,14 @@ tail_call: · 14 unmodified lines
192 while (p < al->p) {192 while (p < al->p) {
193 tal_header_t *header = (tal_header_t *)p;193 tal_header_t *header = (tal_header_t *)p;
194 if (header->line_num > 0) {194 if (header->line_num > 0) {
195 fprintf(stderr, " file %s, line %u: %u bytes\n",195 fprintf(stderr, "%s:%d: chunk of %d bytes\n",
196 header->file_name, header->line_num, header->size);196 header->file_name, header->line_num, header->size);
197 }197 }
198 p += header->size + sizeof(tal_header_t);198 p += header->size + sizeof(tal_header_t);
199 }199 }
200#if MEM_DEBUG-0 == 2
201 exit(2);
202#endif
200 }203 }
201#endif204#endif
202 next = al->next;205 next = al->next;
@@ -206,7 +209,7 @@ tail_call: · 3 unmodified lines
206 goto tail_call;209 goto tail_call;
207}210}
208 211
209ST_FUNC void tal_free_impl(TinyAlloc *al, void *p TAL_DEBUG_PARAMS)212static void tal_free_impl(TinyAlloc *al, void *p TAL_DEBUG_PARAMS)
210{213{
211 if (!p)214 if (!p)
212 return;215 return;
@@ -215,10 +218,10 @@ tail_call: · 2 unmodified lines
215#ifdef TAL_DEBUG218#ifdef TAL_DEBUG
216 tal_header_t *header = (((tal_header_t *)p) - 1);219 tal_header_t *header = (((tal_header_t *)p) - 1);
217 if (header->line_num < 0) {220 if (header->line_num < 0) {
218 fprintf(stderr, "TAL_DEBUG: file %s, line %u double frees chunk from\n",221 fprintf(stderr, "%s:%d: TAL_DEBUG: double frees chunk from\n",
219 file, line);222 file, line);
220 fprintf(stderr, " file %s, line %u: %u bytes\n",223 fprintf(stderr, "%s:%d: %d bytes\n",
221 header->file_name, -header->line_num, header->size);224 header->file_name, (int)-header->line_num, (int)header->size);
222 } else225 } else
223 header->line_num = -header->line_num;226 header->line_num = -header->line_num;
224#endif227#endif
@@ -233,12 +236,12 @@ tail_call: · 8 unmodified lines
233 tcc_free(p);236 tcc_free(p);
234}237}
235 238
236ST_FUNC void *tal_realloc_impl(TinyAlloc **pal, void *p, size_t size TAL_DEBUG_PARAMS)239static void *tal_realloc_impl(TinyAlloc **pal, void *p, unsigned size TAL_DEBUG_PARAMS)
237{240{
238 tal_header_t *header;241 tal_header_t *header;
239 void *ret;242 void *ret;
240 int is_own;243 int is_own;
241 size_t adj_size = (size + 3) & -4;244 unsigned adj_size = (size + 3) & -4;
242 TinyAlloc *al = *pal;245 TinyAlloc *al = *pal;
243 246
244tail_call:247tail_call:
tests/Makefile+8−1
@@ -5,7 +5,7 @@ · 4 unmodified lines
5TOP = ..5TOP = ..
6include $(TOP)/Makefile6include $(TOP)/Makefile
7VPATH = $(TOPSRC)/tests $(TOPSRC) $(TOP)7VPATH = $(TOPSRC)/tests $(TOPSRC) $(TOP)
8CFLAGS = -I$(TOPSRC) -I$(TOP)8CFLAGS := $(filter-out -W% -g% -O%,$(CFLAGS)) -I$(TOPSRC)
9 9
10# what tests to run10# what tests to run
11TESTS = \11TESTS = \
@@ -13,6 +13,7 @@ TESTS = \ · 1 unmodified line
13 hello-run \13 hello-run \
14 libtest \14 libtest \
15 test3 \15 test3 \
16 memtest \
16 dlltest \17 dlltest \
17 abitest \18 abitest \
18 vla_test-run \19 vla_test-run \
@@ -145,6 +146,12 @@ ifndef CONFIG_WIN32 · 126 unmodified lines
145endif146endif
146 @rm tcc2$(EXESUF) libtcc2$(DLLSUF)147 @rm tcc2$(EXESUF) libtcc2$(DLLSUF)
147 148
149memtest:
150 @echo ------------ $@ ------------
151 $(CC) $(CFLAGS) $(NATIVE_DEFINES) -DONE_SOURCE -DMEM_DEBUG=2 ../tcc.c $(LIBS) -o memtest-tcc$(EXESUF)
152 ./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) -DONE_SOURCE ../tcc.c $(LIBS)
153 ./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) -DONE_SOURCE -run ../tcc.c $(TCCFLAGS) tcctest.c
154
148 155
149# memory and bound check auto test156# memory and bound check auto test
150BOUNDS_OK = 1 4 8 10 14157BOUNDS_OK = 1 4 8 10 14
tests/tcctest.c+7−1
@@ -3122,6 +3122,7 @@ void other_constraints_test(void) · 3121 unmodified lines
3122 printf ("oc1: %d\n", ret == (unsigned long)&var);3122 printf ("oc1: %d\n", ret == (unsigned long)&var);
3123}3123}
3124 3124
3125#ifndef _WIN32
3125/* Test global asm blocks playing with aliases. */3126/* Test global asm blocks playing with aliases. */
3126void base_func(void)3127void base_func(void)
3127{3128{
@@ -3161,6 +3162,7 @@ char * get_asm_string (void) · 33 unmodified lines
3161 char * str = ((char*)bug_table) + bug_table[1];3162 char * str = ((char*)bug_table) + bug_table[1];
3162 return str;3163 return str;
3163}3164}
3165#endif
3164 3166
3165unsigned int set;3167unsigned int set;
3166 3168
@@ -3301,12 +3303,15 @@ void asm_test(void) · 134 unmodified lines
3301 printf("set=0x%x\n", set);3303 printf("set=0x%x\n", set);
3302 val = 0x01020304;3304 val = 0x01020304;
3303 printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));3305 printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));
3306#ifndef _WIN32
3304 override_func1();3307 override_func1();
3305 override_func2();3308 override_func2();
3306 /* The base_func ref from the following inline asm should find3309 /* The base_func ref from the following inline asm should find
3307 the global one, not the local decl from this function. */3310 the global one, not the local decl from this function. */
3308 asm volatile(".weak override_func3\n.set override_func3, base_func");3311 asm volatile(".weak override_func3\n.set override_func3, base_func");
3309 override_func3();3312 override_func3();
3313 printf("asmstr: %s\n", get_asm_string());
3314#endif
3310 /* Check that we can also load structs of appropriate layout3315 /* Check that we can also load structs of appropriate layout
3311 into registers. */3316 into registers. */
3312 asm volatile("" : "=r" (asmret) : "0"(s2));3317 asm volatile("" : "=r" (asmret) : "0"(s2));
@@ -3319,7 +3324,6 @@ void asm_test(void) · 6 unmodified lines
3319 if (!somebool)3324 if (!somebool)
3320 printf("asmbool: failed\n");3325 printf("asmbool: failed\n");
3321#endif3326#endif
3322 printf("asmstr: %s\n", get_asm_string());
3323 val = 43;3327 val = 43;
3324 fancy_copy (&val, &val2);3328 fancy_copy (&val, &val2);
3325 printf ("fancycpy(%d)=%d\n", val, val2);3329 printf ("fancycpy(%d)=%d\n", val, val2);
@@ -3677,10 +3681,12 @@ typedef struct gate_struct64 gate_desc; · 351 unmodified lines
3677gate_desc a_gate_desc;3681gate_desc a_gate_desc;
3678void attrib_test(void)3682void attrib_test(void)
3679{3683{
3684#ifndef _WIN32
3680 printf("attr: %d %d %d %d\n", sizeof(struct Spacked),3685 printf("attr: %d %d %d %d\n", sizeof(struct Spacked),
3681 sizeof(spacked), sizeof(Spacked2), sizeof(spacked2));3686 sizeof(spacked), sizeof(Spacked2), sizeof(spacked2));
3682 printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3));3687 printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3));
3683 printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc));3688 printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc));
3689#endif
3684}3690}
3685extern __attribute__((__unused__)) char * __attribute__((__unused__)) *3691extern __attribute__((__unused__)) char * __attribute__((__unused__)) *
3686strange_attrib_placement (void);3692strange_attrib_placement (void);
tests/tests2/Makefile+1−1
@@ -63,7 +63,7 @@ all test: $(filter-out $(SKIP),$(TESTS)) · 62 unmodified lines
63 63
64# automatically generate .expect files with gcc:64# automatically generate .expect files with gcc:
65%.expect : %.c65%.expect : %.c
66 (gcc -w $*.c -o a.exe && ./a.exe $(ARGS)) >$*.expect 2>&1; rm -f a.exe66 (gcc -w $*.c -o a.exe && ./a.exe $(ARGS)) $(FILTER) >$*.expect 2>&1; rm -f a.exe
67 67
68# tell make not to delete68# tell make not to delete
69.PRECIOUS: %.expect69.PRECIOUS: %.expect

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t