stddef.h, tccdefs.h, tccgen.c, tests/boundtest.c, tests/tcctest.c: - remove ifdef arround alloca lib/Makefile: - move alloca-bt.o to COMMON_O lib/alloca-bt.S: - add alloca bound check code for arm, arm64, riscv64 lib/alloca.S: - check for leading underscore tcc.h, libtcc.c: - include arm64-asm.c instead of arm-asm.c for arm64 tcctok.h, tccasm.c: - add simple reloc support (only for R_AARCH64_CALL26)
Unified · Split
| @@ -19,9 +19,7 @@ typedef union { long long __ll; long double __ld; } max_align_t; · 18 unmodified lines | |||
| 19 | #undef offsetof | 19 | #undef offsetof |
| 20 | #define offsetof(type, field) __builtin_offsetof(type, field) | 20 | #define offsetof(type, field) __builtin_offsetof(type, field) |
| 21 | 21 | ||
| 22 | #if defined __i386__ || defined __x86_64__ | ||
| 23 | void *alloca(size_t size); | 22 | void *alloca(size_t size); |
| 24 | #endif | ||
| 25 | 23 | ||
| 26 | #endif | 24 | #endif |
| 27 | 25 | ||
| @@ -347,12 +347,8 @@ · 346 unmodified lines | |||
| 347 | __MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__)) | 347 | __MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__)) |
| 348 | __MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__)) | 348 | __MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__)) |
| 349 | __MAYBE_REDIR(void, free, (void*)) | 349 | __MAYBE_REDIR(void, free, (void*)) |
| 350 | #if defined __i386__ || defined __x86_64__ | ||
| 351 | __BOTH(void*, alloca, (__SIZE_TYPE__)) | 350 | __BOTH(void*, alloca, (__SIZE_TYPE__)) |
| 352 | void *alloca(__SIZE_TYPE__); | 351 | void *alloca(__SIZE_TYPE__); |
| 353 | #else | ||
| 354 | __BUILTIN(void*, alloca, (__SIZE_TYPE__)) | ||
| 355 | #endif | ||
| 356 | __BUILTIN(void, abort, (void)) | 352 | __BUILTIN(void, abort, (void)) |
| 357 | __BOUND(void, longjmp, ()) | 353 | __BOUND(void, longjmp, ()) |
| 358 | #if !defined _WIN32 | 354 | #if !defined _WIN32 |
| @@ -35,12 +35,12 @@ endif · 34 unmodified lines | |||
| 35 | 35 | ||
| 36 | XFLAGS += -I$(TOP) | 36 | XFLAGS += -I$(TOP) |
| 37 | 37 | ||
| 38 | I386_O = libtcc1.o alloca-bt.o $(COMMON_O) | 38 | I386_O = libtcc1.o $(COMMON_O) |
| 39 | X86_64_O = libtcc1.o alloca-bt.o $(COMMON_O) | 39 | X86_64_O = libtcc1.o $(COMMON_O) |
| 40 | ARM_O = libtcc1.o armeabi.o armflush.o $(COMMON_O) | 40 | ARM_O = libtcc1.o armeabi.o armflush.o $(COMMON_O) |
| 41 | ARM64_O = lib-arm64.o $(COMMON_O) | 41 | ARM64_O = lib-arm64.o $(COMMON_O) |
| 42 | RISCV64_O = lib-arm64.o $(COMMON_O) | 42 | RISCV64_O = lib-arm64.o $(COMMON_O) |
| 43 | COMMON_O = stdatomic.o atomic.o builtin.o alloca.o | 43 | COMMON_O = stdatomic.o atomic.o builtin.o alloca.o alloca-bt.o |
| 44 | WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o | 44 | WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o |
| 45 | LIN_O = dsohandle.o | 45 | LIN_O = dsohandle.o |
| 46 | OSX_O = | 46 | OSX_O = |
| @@ -92,5 +92,109 @@ p3: · 91 unmodified lines | |||
| 92 | ret | 92 | ret |
| 93 | #endif | 93 | #endif |
| 94 | 94 | ||
| 95 | /* ---------------------------------------------- */ | ||
| 96 | #elif defined __arm__ | ||
| 97 | |||
| 98 | .globl _(__bound_alloca) | ||
| 99 | _(__bound_alloca): | ||
| 100 | mov r1, r0 | ||
| 101 | add r0, r0, #1 | ||
| 102 | rsb sp, r0, sp | ||
| 103 | bic sp, sp, #7 | ||
| 104 | mov r0, sp | ||
| 105 | push { lr } | ||
| 106 | bl _(__bound_new_region) | ||
| 107 | pop { lr } | ||
| 108 | mov r0, sp | ||
| 109 | mov pc, lr | ||
| 110 | |||
| 111 | /* ---------------------------------------------- */ | ||
| 112 | #elif defined __aarch64__ || defined __arm64__ | ||
| 113 | |||
| 114 | .globl _(__bound_alloca) | ||
| 115 | _(__bound_alloca): | ||
| 116 | #ifdef __TINYC__ | ||
| 117 | .int 0xaa0003e1 | ||
| 118 | .int 0x91004000 | ||
| 119 | .int 0x927cec00 | ||
| 120 | #ifdef _WIN32 | ||
| 121 | .int 0xb4000160 | ||
| 122 | .int 0xd2820002 | ||
| 123 | .int 0xeb02001f | ||
| 124 | .int 0x540000c3 | ||
| 125 | .int 0xcb2263e3 | ||
| 126 | .int 0xf940007f | ||
| 127 | .int 0xcb2263ff | ||
| 128 | .int 0xcb020000 | ||
| 129 | .int 0x17fffffa | ||
| 130 | .int 0xb4000040 | ||
| 131 | #endif | ||
| 132 | .int 0xcb2063ff | ||
| 133 | .int 0x910003e0 | ||
| 134 | .int 0xa9bf7bfd | ||
| 135 | .reloc ., R_AARCH64_CALL26, _(__bound_new_region) | ||
| 136 | .int 0x94000000 | ||
| 137 | .int 0xa8c17bfd | ||
| 138 | .int 0x910003e0 | ||
| 139 | .int 0xd65f03c0 | ||
| 140 | #else | ||
| 141 | mov x1, x0 | ||
| 142 | add x0, x0, #16 // Round up to 16-byte boundary | ||
| 143 | and x0, x0, #-16 // Ensure 16-byte alignment | ||
| 144 | #ifdef _WIN32 | ||
| 145 | cbz x0, p100 // If size is 0, skip to return | ||
| 146 | // Windows requires page-wise allocation with stack probing | ||
| 147 | mov x2, #4096 // Page size = 4096 bytes | ||
| 148 | |||
| 149 | p101: | ||
| 150 | cmp x0, x2 // Compare remaining size with page size | ||
| 151 | b.lo p102 // If less than page, jump to remainder | ||
| 152 | |||
| 153 | // Probe first, then allocate | ||
| 154 | sub x3, sp, x2 // Calculate guard page address (sp - 4096) | ||
| 155 | ldr xzr, [x3] // Touch guard page FIRST | ||
| 156 | sub sp, sp, x2 // THEN allocate the page | ||
| 157 | |||
| 158 | sub x0, x0, x2 // Decrement remaining size | ||
| 159 | b p101 // Continue loop | ||
| 160 | |||
| 161 | p102: | ||
| 162 | // Allocate remaining bytes (less than one page) | ||
| 163 | cbz x0, p100 // If no remaining bytes, skip | ||
| 164 | sub sp, sp, x0 // Allocate remaining space | ||
| 165 | #else | ||
| 166 | // Non-Windows: simple one-time allocation | ||
| 167 | sub sp, sp, x0 // Allocate space on stack | ||
| 168 | #endif | ||
| 169 | |||
| 170 | p100: | ||
| 171 | mov x0, sp // Return allocated address | ||
| 172 | stp x29, x30, [sp, #-16]! | ||
| 173 | bl _(__bound_new_region) | ||
| 174 | ldp x29, x30, [sp], #16 | ||
| 175 | mov x0, sp // Return allocated address | ||
| 176 | ret // Return to caller | ||
| 177 | #endif | ||
| 178 | |||
| 179 | /* ---------------------------------------------- */ | ||
| 180 | #elif defined __riscv | ||
| 181 | |||
| 182 | .globl _(__bound_alloca) | ||
| 183 | _(__bound_alloca): | ||
| 184 | mv a1, a0 | ||
| 185 | sub sp, sp, a0 | ||
| 186 | addi sp, sp, -16 | ||
| 187 | andi sp, sp, -16 | ||
| 188 | add a0, sp, zero | ||
| 189 | addi sp,sp,-16 | ||
| 190 | sd s0,0(sp) | ||
| 191 | sd ra,8(sp) | ||
| 192 | jal _(__bound_new_region) | ||
| 193 | ld s0,0(sp) | ||
| 194 | ld ra,8(sp) | ||
| 195 | addi sp,sp,16 | ||
| 196 | add a0, sp, zero | ||
| 197 | ret | ||
| 198 | |||
| 95 | /* ---------------------------------------------- */ | 199 | /* ---------------------------------------------- */ |
| 96 | #endif | 200 | #endif |
| @@ -70,25 +70,18 @@ p3: · 69 unmodified lines | |||
| 70 | /* ---------------------------------------------- */ | 70 | /* ---------------------------------------------- */ |
| 71 | #elif defined __arm__ | 71 | #elif defined __arm__ |
| 72 | 72 | ||
| 73 | .text | 73 | .globl _(alloca) |
| 74 | .align 2 | 74 | _(alloca): |
| 75 | .global alloca | ||
| 76 | .type alloca, %function | ||
| 77 | alloca: | ||
| 78 | rsb sp, r0, sp | 75 | rsb sp, r0, sp |
| 79 | bic sp, sp, #7 | 76 | bic sp, sp, #7 |
| 80 | mov r0, sp | 77 | mov r0, sp |
| 81 | mov pc, lr | 78 | mov pc, lr |
| 82 | .size alloca, .-alloca | ||
| 83 | 79 | ||
| 84 | /* ---------------------------------------------- */ | 80 | /* ---------------------------------------------- */ |
| 85 | #elif defined __aarch64__ || defined __arm64__ | 81 | #elif defined __aarch64__ || defined __arm64__ |
| 86 | 82 | ||
| 87 | .text | 83 | .globl _(alloca) |
| 88 | .align 2 | 84 | _(alloca): |
| 89 | .global alloca | ||
| 90 | .type alloca, %function | ||
| 91 | alloca: | ||
| 92 | #ifdef __TINYC__ | 85 | #ifdef __TINYC__ |
| 93 | .int 0x91003c00 | 86 | .int 0x91003c00 |
| 94 | .int 0x927cec00 | 87 | .int 0x927cec00 |
| @@ -102,16 +95,16 @@ alloca: · 7 unmodified lines | |||
| 102 | .int 0xcb2163ff | 95 | .int 0xcb2163ff |
| 103 | .int 0xcb010000 | 96 | .int 0xcb010000 |
| 104 | .int 0x17fffffa | 97 | .int 0x17fffffa |
| 105 | #endif | ||
| 106 | .int 0xb4000040 | 98 | .int 0xb4000040 |
| 99 | #endif | ||
| 107 | .int 0xcb2063ff | 100 | .int 0xcb2063ff |
| 108 | .int 0x910003e0 | 101 | .int 0x910003e0 |
| 109 | .int 0xd65f03c0 | 102 | .int 0xd65f03c0 |
| 110 | #else | 103 | #else |
| 111 | add x0, x0, #15 // Round up to 16-byte boundary | 104 | add x0, x0, #15 // Round up to 16-byte boundary |
| 112 | and x0, x0, #-16 // Ensure 16-byte alignment | 105 | and x0, x0, #-16 // Ensure 16-byte alignment |
| 113 | cbz x0, p100 // If size is 0, skip to return | ||
| 114 | #ifdef _WIN32 | 106 | #ifdef _WIN32 |
| 107 | cbz x0, p100 // If size is 0, skip to return | ||
| 115 | // Windows requires page-wise allocation with stack probing | 108 | // Windows requires page-wise allocation with stack probing |
| 116 | mov x1, #4096 // Page size = 4096 bytes | 109 | mov x1, #4096 // Page size = 4096 bytes |
| 117 | 110 | ||
| @@ -140,20 +133,16 @@ p100: · 22 unmodified lines | |||
| 140 | mov x0, sp // Return allocated address | 133 | mov x0, sp // Return allocated address |
| 141 | ret // Return to caller | 134 | ret // Return to caller |
| 142 | #endif | 135 | #endif |
| 143 | .size alloca, .-alloca | 136 | |
| 144 | /* ---------------------------------------------- */ | 137 | /* ---------------------------------------------- */ |
| 145 | #elif defined __riscv | 138 | #elif defined __riscv |
| 146 | 139 | ||
| 147 | .text | 140 | .globl _(alloca) |
| 148 | .align 2 | 141 | _(alloca): |
| 149 | .global alloca | 142 | sub sp, sp, a0 |
| 150 | .type alloca, %function | 143 | addi sp, sp, -15 |
| 151 | alloca: | 144 | andi sp, sp, -16 |
| 152 | sub sp, sp, a0 | 145 | add a0, sp, zero |
| 153 | addi sp, sp, -15 | 146 | ret |
| 154 | andi sp, sp, -16 | 147 | |
| 155 | add a0, sp, zero | ||
| 156 | ret | ||
| 157 | .size alloca, .-alloca | ||
| 158 | /* ---------------------------------------------- */ | ||
| 159 | #endif | 148 | #endif |
| @@ -40,7 +40,7 @@ · 39 unmodified lines | |||
| 40 | #elif defined(TCC_TARGET_ARM64) | 40 | #elif defined(TCC_TARGET_ARM64) |
| 41 | #include "arm64-gen.c" | 41 | #include "arm64-gen.c" |
| 42 | #include "arm64-link.c" | 42 | #include "arm64-link.c" |
| 43 | #include "arm-asm.c" | 43 | #include "arm64-asm.c" |
| 44 | #elif defined(TCC_TARGET_C67) | 44 | #elif defined(TCC_TARGET_C67) |
| 45 | #include "c67-gen.c" | 45 | #include "c67-gen.c" |
| 46 | #include "c67-link.c" | 46 | #include "c67-link.c" |
| @@ -385,7 +385,7 @@ extern long double strtold (const char *__nptr, char **__endptr); · 384 unmodified lines | |||
| 385 | #elif defined TCC_TARGET_ARM64 | 385 | #elif defined TCC_TARGET_ARM64 |
| 386 | # include "arm64-gen.c" | 386 | # include "arm64-gen.c" |
| 387 | # include "arm64-link.c" | 387 | # include "arm64-link.c" |
| 388 | # include "arm-asm.c" | 388 | # include "arm64-asm.c" |
| 389 | #elif defined TCC_TARGET_C67 | 389 | #elif defined TCC_TARGET_C67 |
| 390 | # define TCC_TARGET_COFF | 390 | # define TCC_TARGET_COFF |
| 391 | # include "coff.h" | 391 | # include "coff.h" |
| @@ -984,6 +984,23 @@ static void asm_parse_directive(TCCState *s1, int global) · 983 unmodified lines | |||
| 984 | skip('@'); | 984 | skip('@'); |
| 985 | next(); | 985 | next(); |
| 986 | break; | 986 | break; |
| 987 | case TOK_ASMDIR_reloc: | ||
| 988 | { | ||
| 989 | ExprValue e; | ||
| 990 | |||
| 991 | next(); | ||
| 992 | asm_expr(s1, &e); | ||
| 993 | skip(','); | ||
| 994 | #ifdef __aarch64__ | ||
| 995 | if (strcmp(get_tok_str(tok, NULL), "R_AARCH64_CALL26")) | ||
| 996 | #endif | ||
| 997 | tcc_error("unimp: reloc '%s' unknown", get_tok_str(tok, NULL)); | ||
| 998 | next(); | ||
| 999 | skip(','); | ||
| 1000 | greloca(cur_text_section, get_asm_sym(tok, NULL), e.v, R_AARCH64_CALL26, 0); | ||
| 1001 | next(); | ||
| 1002 | } | ||
| 1003 | break; | ||
| 987 | default: | 1004 | default: |
| 988 | tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL)); | 1005 | tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL)); |
| 989 | break; | 1006 | break; |
| @@ -1701,10 +1701,8 @@ ST_FUNC void gbound_args(int nb_args) · 1700 unmodified lines | |||
| 1701 | gfunc_call(1); | 1701 | gfunc_call(1); |
| 1702 | func_bound_add_epilog = 1; | 1702 | func_bound_add_epilog = 1; |
| 1703 | } | 1703 | } |
| 1704 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | ||
| 1705 | if (v == TOK_alloca) | 1704 | if (v == TOK_alloca) |
| 1706 | func_bound_add_epilog = 1; | 1705 | func_bound_add_epilog = 1; |
| 1707 | #endif | ||
| 1708 | #if TARGETOS_NetBSD | 1706 | #if TARGETOS_NetBSD |
| 1709 | if (v == TOK_longjmp) /* undo rename to __longjmp14 */ | 1707 | if (v == TOK_longjmp) /* undo rename to __longjmp14 */ |
| 1710 | sv->sym->asm_label = TOK___bound_longjmp; | 1708 | sv->sym->asm_label = TOK___bound_longjmp; |
| @@ -301,9 +301,7 @@ · 300 unmodified lines | |||
| 301 | DEF(TOK___fixxfdi, "__fixxfdi") | 301 | DEF(TOK___fixxfdi, "__fixxfdi") |
| 302 | #endif | 302 | #endif |
| 303 | 303 | ||
| 304 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | ||
| 305 | DEF(TOK_alloca, "alloca") | 304 | DEF(TOK_alloca, "alloca") |
| 306 | #endif | ||
| 307 | 305 | ||
| 308 | #if defined TCC_TARGET_PE | 306 | #if defined TCC_TARGET_PE |
| 309 | DEF(TOK___chkstk, "__chkstk") | 307 | DEF(TOK___chkstk, "__chkstk") |
| @@ -415,6 +413,7 @@ · 105 unmodified lines | |||
| 415 | DEF_ASMDIR(long) | 413 | DEF_ASMDIR(long) |
| 416 | DEF_ASMDIR(int) | 414 | DEF_ASMDIR(int) |
| 417 | DEF_ASMDIR(symver) | 415 | DEF_ASMDIR(symver) |
| 416 | DEF_ASMDIR(reloc) | ||
| 418 | DEF_ASMDIR(section) /* must be last directive */ | 417 | DEF_ASMDIR(section) /* must be last directive */ |
| 419 | 418 | ||
| 420 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | 419 | #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 |
| @@ -169,14 +169,6 @@ int test13(void) · 168 unmodified lines | |||
| 169 | return strlen(tab); | 169 | return strlen(tab); |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | #if defined __i386__ || defined __x86_64__ | ||
| 173 | #define allocf(x) | ||
| 174 | #else | ||
| 175 | #undef alloca | ||
| 176 | #define alloca(x) malloc(x) | ||
| 177 | #define allocf(x) free(x) | ||
| 178 | #endif | ||
| 179 | |||
| 180 | int test14(void) | 172 | int test14(void) |
| 181 | { | 173 | { |
| 182 | char *p = alloca(TAB_SIZE); | 174 | char *p = alloca(TAB_SIZE); |
| @@ -184,7 +176,6 @@ int test14(void) · 1 unmodified line | |||
| 184 | memset(p, 'a', TAB_SIZE); | 176 | memset(p, 'a', TAB_SIZE); |
| 185 | p[TAB_SIZE-1] = 0; | 177 | p[TAB_SIZE-1] = 0; |
| 186 | ret = strlen(p); | 178 | ret = strlen(p); |
| 187 | allocf(p); | ||
| 188 | return ret; | 179 | return ret; |
| 189 | } | 180 | } |
| 190 | 181 | ||
| @@ -196,7 +187,6 @@ int test15(void) · 5 unmodified lines | |||
| 196 | memset(p, 'a', TAB_SIZE); | 187 | memset(p, 'a', TAB_SIZE); |
| 197 | p[TAB_SIZE-1] = 0; | 188 | p[TAB_SIZE-1] = 0; |
| 198 | ret = strlen(p); | 189 | ret = strlen(p); |
| 199 | allocf(p); | ||
| 200 | return ret; | 190 | return ret; |
| 201 | } | 191 | } |
| 202 | 192 | ||
| @@ -211,8 +201,6 @@ int test16() · 8 unmodified lines | |||
| 211 | 201 | ||
| 212 | /* Test alloca embedded in a larger expression */ | 202 | /* Test alloca embedded in a larger expression */ |
| 213 | printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)+1),demo) ); | 203 | printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)+1),demo) ); |
| 214 | allocf(p); | ||
| 215 | allocf(q); | ||
| 216 | 204 | ||
| 217 | return 0; | 205 | return 0; |
| 218 | } | 206 | } |
| @@ -228,8 +216,6 @@ int test17() · 9 unmodified lines | |||
| 228 | 216 | ||
| 229 | /* Test alloca embedded in a larger expression */ | 217 | /* Test alloca embedded in a larger expression */ |
| 230 | printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)),demo) ); | 218 | printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)),demo) ); |
| 231 | allocf(p); | ||
| 232 | allocf(q); | ||
| 233 | 219 | ||
| 234 | return 0; | 220 | return 0; |
| 235 | } | 221 | } |
| @@ -2941,14 +2941,12 @@ void old_style_function_test(void) · 2940 unmodified lines | |||
| 2941 | 2941 | ||
| 2942 | void alloca_test() | 2942 | void alloca_test() |
| 2943 | { | 2943 | { |
| 2944 | #if defined __i386__ || defined __x86_64__ || defined __arm__ | ||
| 2945 | char *p = alloca(16); | 2944 | char *p = alloca(16); |
| 2946 | strcpy(p,"123456789012345"); | 2945 | strcpy(p,"123456789012345"); |
| 2947 | printf("alloca: p is %s\n", p); | 2946 | printf("alloca: p is %s\n", p); |
| 2948 | char *demo = "This is only a test.\n"; | 2947 | char *demo = "This is only a test.\n"; |
| 2949 | /* Test alloca embedded in a larger expression */ | 2948 | /* Test alloca embedded in a larger expression */ |
| 2950 | printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) ); | 2949 | printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) ); |
| 2951 | #endif | ||
| 2952 | } | 2950 | } |
| 2953 | 2951 | ||
| 2954 | void *bounds_checking_is_enabled() | 2952 | void *bounds_checking_is_enabled() |
| @@ -4208,7 +4206,6 @@ double get100 () { return 100.0; } · 1253 unmodified lines | |||
| 4208 | 4206 | ||
| 4209 | void callsave_test(void) | 4207 | void callsave_test(void) |
| 4210 | { | 4208 | { |
| 4211 | #if defined __i386__ || defined __x86_64__ || defined __arm__ | ||
| 4212 | int i, s; double *d; double t; | 4209 | int i, s; double *d; double t; |
| 4213 | s = sizeof (double); | 4210 | s = sizeof (double); |
| 4214 | printf ("callsavetest: %d\n", s); | 4211 | printf ("callsavetest: %d\n", s); |
| @@ -4221,7 +4218,6 @@ void callsave_test(void) · 6 unmodified lines | |||
| 4221 | generates a segfault. */ | 4218 | generates a segfault. */ |
| 4222 | i = d[0] > get100 (); | 4219 | i = d[0] > get100 (); |
| 4223 | printf ("%d\n", i); | 4220 | printf ("%d\n", i); |
| 4224 | #endif | ||
| 4225 | } | 4221 | } |
| 4226 | 4222 | ||
| 4227 | 4223 | ||