├── .github └── workflows │ └── test.yml ├── .gitignore ├── LICENSE.md ├── Makefile ├── README.md ├── configure ├── demo ├── Makefile ├── README.md └── ccwrap.py ├── doc ├── cfg.png ├── csmith.png └── random.c ├── include └── lacc │ ├── array.h │ ├── context.h │ ├── deque.h │ ├── hash.h │ ├── ir.h │ ├── string.h │ ├── symbol.h │ ├── token.h │ └── type.h ├── lib └── lacc │ └── include │ ├── alloca.h │ ├── float.h │ ├── stdalign.h │ ├── stdarg.h │ ├── stdbool.h │ ├── stddef.h │ └── stdnoreturn.h ├── src ├── backend │ ├── arm64 │ │ └── compile.c │ ├── compile.h │ ├── dot.c │ ├── dot.h │ ├── linker.c │ ├── linker.h │ └── x86_64 │ │ ├── abi.c │ │ ├── abi.h │ │ ├── assemble.c │ │ ├── assemble.h │ │ ├── assembler.c │ │ ├── assembler.h │ │ ├── compile.c │ │ ├── dwarf.c │ │ ├── dwarf.h │ │ ├── elf.c │ │ ├── elf.h │ │ ├── encoding.c │ │ └── encoding.h ├── context.c ├── lacc.c ├── optimizer │ ├── liveness.c │ ├── liveness.h │ ├── optimize.c │ ├── optimize.h │ ├── transform.c │ └── transform.h ├── parser │ ├── builtin.c │ ├── builtin.h │ ├── declaration.c │ ├── declaration.h │ ├── eval.c │ ├── eval.h │ ├── expression.c │ ├── expression.h │ ├── initializer.c │ ├── initializer.h │ ├── parse.c │ ├── parse.h │ ├── statement.c │ ├── statement.h │ ├── symtab.c │ ├── symtab.h │ ├── typetree.c │ └── typetree.h ├── preprocessor │ ├── directive.c │ ├── directive.h │ ├── input.c │ ├── input.h │ ├── macro.c │ ├── macro.h │ ├── preprocess.c │ ├── preprocess.h │ ├── strtab.c │ ├── strtab.h │ ├── tokenize.c │ └── tokenize.h └── util │ ├── argparse.c │ ├── argparse.h │ ├── hash.c │ └── string.c └── test ├── Makefile ├── asm ├── alias.c ├── basic.c ├── call.c ├── goto.c ├── register-constraint.c ├── sse.c ├── symbol-name.c ├── symbol-name.sh ├── variables.c └── x87.c ├── c11 ├── alignof.c ├── noreturn.c └── static-assert.c ├── c89 ├── address-deref-offset.c ├── anonymous-members.c ├── anonymous-struct.c ├── array-decay.c ├── array-nested-init.c ├── array-param.c ├── array-registers.c ├── array-reverse-index.c ├── array-zero-length.c ├── array.c ├── assign-deref-float.c ├── assignment-type.c ├── bitfield-basic.c ├── bitfield-extend.c ├── bitfield-immediate-assign.c ├── bitfield-immediate-bitwise.c ├── bitfield-initialize-zero.c ├── bitfield-load.c ├── bitfield-mask.c ├── bitfield-pack-next.c ├── bitfield-packing.c ├── bitfield-reset-align.c ├── bitfield-trailing-zero.c ├── bitfield-types-init.c ├── bitfield-types.c ├── bitfield-unsigned-promote.c ├── bitfield.c ├── bitwise-complement.c ├── bitwise-constant.c ├── bitwise-expression.c ├── bitwise-sign-extend.c ├── byte-load.c ├── cast-float-union.c ├── cast-float.c ├── cast-function-args.c ├── cast-function.c ├── cast-immediate-truncate.c ├── cast.c ├── comma-side-effects.c ├── comment.c ├── compare.c ├── compound-assignment-basic.c ├── conditional-basic.c ├── conditional-constant.c ├── conditional-void.c ├── conditional.c ├── constant-address-index.c ├── constant-expression.c ├── constant-integer-type.c ├── convert-assign-immediate.c ├── convert-float-double.c ├── convert-float-int.c ├── convert-float-unsigned.c ├── convert-int-float.c ├── convert-unsigned-float.c ├── copy-struct.c ├── declaration-default-int.c ├── declarator-abstract.c ├── declarator-complex.c ├── declarator-parens.c ├── declare-auto-func.c ├── deref-address-offset.c ├── deref-array.c ├── deref-compare-float.c ├── deref-deep.c ├── deref-store.c ├── deref.c ├── dereference-extern.c ├── directive-number.c ├── do-continue.c ├── do-while.c ├── duffs-device.c ├── enum.c ├── exit.c ├── expression-div-mod.c ├── expression.c ├── fact.c ├── field-chain-assign.c ├── float-arithmetic.c ├── float-branch.c ├── float-compare-equal.c ├── float-compare-nan.c ├── float-compare.c ├── float-function.c ├── float-load-deref.c ├── for-empty-expr.c ├── for-side-effects.c ├── for.c ├── function-char-args.c ├── function-implicit-declare.c ├── function-incomplete.c ├── function-pointer-call.c ├── function-pointer.c ├── function.c ├── goto.c ├── header.h ├── hello.c ├── identifier.c ├── immediate-branch.c ├── immediate-expr.c ├── immediate-pointer.c ├── include.c ├── increment.c ├── initialize-address.c ├── initialize-array.c ├── initialize-call.c ├── initialize-float.c ├── initialize-null.c ├── initialize-object.c ├── initialize-string.c ├── initialize-union.c ├── initialize.c ├── integer-suffix.c ├── ldouble-load-direct.c ├── line-continuation.c ├── line-directive.c ├── linebreak.c ├── liveness-deref-assign.c ├── liveness-global.c ├── liveness-loop.c ├── liveness-param-pointer.c ├── liveness-pointer.c ├── logical-and-bitwise-false.c ├── logical-operators-basic.c ├── long-double-arithmetic.c ├── long-double-compare.c ├── long-double-function.c ├── long-double-load.c ├── long-double-struct.c ├── long-double-union.c ├── macro-empty-arg.c ├── macro-function-paren.c ├── macro-keyword-arg.c ├── macro-keyword-define.c ├── macro-name-arg.c ├── macro-param-space.c ├── macro-paste.c ├── macro-predefined.c ├── macro-recursive.c ├── macro-refill-expand.c ├── macro-repeat-expand.c ├── macro-skip-expand.c ├── macro.c ├── main.c ├── negate.c ├── nested-macro.c ├── offsetof.c ├── old-param-decay.c ├── old-style-declaration.c ├── old-style-definition.c ├── padded-initialization.c ├── params-mixed.c ├── params-system-v.c ├── partial-initialization.c ├── pointer-diff.c ├── pointer-immediate.c ├── pointer.c ├── preprocess-expression.c ├── preprocess.c ├── preprocessor-expression.c ├── printstr.c ├── promote-unsigned.c ├── prototype-scope-enum.c ├── ptrdiff.c ├── push-immediate.c ├── qualifier-repeat.c ├── register-param.c ├── return-bitfield.c ├── return-compare-int.c ├── return-float-struct.c ├── return-partial-register.c ├── return-point.c ├── return-struct-basic.c ├── return-struct-integers.c ├── return-struct-mem.c ├── self-referential-struct.c ├── shift-assign.c ├── shift.c ├── short-circuit-comma.c ├── short-circuit.c ├── shortcircuit-loop.c ├── signed-division.c ├── sizeof.c ├── string-addr.c ├── string-concat.c ├── string-conversion.c ├── string-escape.c ├── string-index.c ├── string-length.c ├── stringify.c ├── strings.c ├── struct-alignment.c ├── struct-assign.c ├── struct-comma-call.c ├── struct-eightbyte-write.c ├── struct-init-swap.c ├── struct-padding.c ├── struct.c ├── switch-basic.c ├── switch-nested.c ├── switch-side-effect.c ├── tag.c ├── tail-compare-jump.c ├── token.c ├── tokenize-partial-keyword.c ├── trigraph.c ├── typedef-function.c ├── typedef-initialize.c ├── typedef.c ├── unary-minus-float.c ├── unary-plus.c ├── union-bitfield.c ├── union-float-assign.c ├── union-float-param.c ├── union-zero-init.c ├── union.c ├── unsigned-compare-ge.c ├── unsigned-compare.c ├── unsigned-sign-extend.c ├── vararg-branch.c ├── vararg-complex-1.c ├── vararg-complex-2.c ├── vararg-deref-arg.c ├── vararg-deref.c ├── vararg-float.c ├── vararg-param.c ├── vararg.c ├── void-statement.c ├── whitespace.c └── zero-init.c ├── c99 ├── _Pragma.c ├── __func__.c ├── array-param-qualifier.c ├── array-qualifier-static.c ├── bool-return.c ├── bool.c ├── compund-literal.c ├── designator-array.c ├── designator-struct.c ├── designator-union.c ├── flexible-array-arg.c ├── flexible-array.c ├── flexible-union.c ├── for-declaration.c ├── initialize-bit.c ├── initialize-compound.c ├── initialize-object.c ├── inline-address.c ├── inline-address.sh ├── inline-declare.c ├── inline-extern.c ├── inline-extern.sh ├── inline-unused.c ├── inline-unused.sh ├── line-comment.c ├── main-default-return.c ├── nan-inf.c ├── restrict.c ├── va_copy.c ├── variadic-macro.c ├── vla-arg.c ├── vla-block-declaration.c ├── vla-compatibility.c ├── vla-matrix.c ├── vla-old-param.c ├── vla-pointer.c ├── vla-sizeof.c ├── vla-static-pointer.c ├── vla-ternary-length.c └── vla.c ├── check.sh ├── csmith.sh ├── docker.sh ├── docker └── alpine.Dockerfile ├── extensions ├── __builtin_constant_p.c ├── alloca.c ├── comma-variable-args.c ├── keywords.c └── variadic-macro-alias.c ├── interesting.sh ├── limits └── large-objects.c ├── linker.sh ├── linker ├── bar.c └── foo.c ├── sqlite.sh └── undefined ├── assign-constant-float.c ├── cast-float-overflow.c ├── float-divide-zero.c └── long-double-convert.c /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: push 4 | 5 | jobs: 6 | ubuntu: 7 | name: Ubuntu 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v2 12 | - name: Build and install 13 | run: | 14 | ./configure 15 | make 16 | sudo make install 17 | - name: Test 18 | run: make -C test 19 | alpine: 20 | name: Alpine 21 | runs-on: ubuntu-latest 22 | container: docker://alpine:latest 23 | steps: 24 | - name: Setup 25 | run: apk add gcc libc-dev git make ncurses 26 | - name: Checkout 27 | uses: actions/checkout@v2 28 | - name: Build and install 29 | run: | 30 | ./configure 31 | make 32 | make install 33 | - name: Test 34 | run: make -C test 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | config.h 3 | config.mak 4 | demo/git 5 | demo/ioq3 6 | test/sqlite 7 | test/csmith 8 | test/creduce 9 | 10 | .vscode 11 | *.xcodeproj 12 | 13 | # Mac OS 14 | **/.DS_Store 15 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Lars Kirkholt Melhus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .POSIX: 2 | .SUFFIXES: 3 | 4 | include config.mak 5 | 6 | bin/lacc: $(SOURCES) $(HEADERS) config.h config.mak 7 | mkdir -p $(@D) 8 | $(CC) $(CPPFLAGS) $(CFLAGS) -Iinclude -include config.h -DAMALGAMATION src/lacc.c -o $@ 9 | 10 | install: 11 | install -d -m 755 $(DESTDIR)$(BINDIR) 12 | install -d -m 755 $(DESTDIR)$(LIBDIR)/lacc/include 13 | install -m 755 bin/lacc $(DESTDIR)$(BINDIR) 14 | install -m 644 $(LIBS) $(DESTDIR)$(LIBDIR)/lacc/include 15 | 16 | uninstall: 17 | rm -rf $(DESTDIR)$(LIBDIR)/lacc 18 | rm -f $(DESTDIR)$(BINDIR)/lacc 19 | 20 | clean: 21 | rm -rf bin 22 | 23 | distclean: clean 24 | rm -f config.h config.mak 25 | 26 | .PHONY: install uninstall clean distclean 27 | -------------------------------------------------------------------------------- /demo/Makefile: -------------------------------------------------------------------------------- 1 | .POSIX: 2 | .SUFFIXES: 3 | 4 | CC = ../../bin/lacc 5 | 6 | help: 7 | @echo "Choose one of the following targets to demo lacc:" 8 | @echo "" 9 | @echo " git: Build and run tests on the git source code." 10 | @echo " quake: Compile ioquake3, a fork of the original Quake source code." 11 | @echo "" 12 | 13 | git: git/.git git/ccwrap.py 14 | make -C git clean 15 | make -C git CC="CC=${CC} ./ccwrap.py" COMPUTE_HEADER_DEPENDENCIES=no test 16 | 17 | git/ccwrap.py: ccwrap.py 18 | cp $? $@ 19 | chmod +x $@ 20 | 21 | git/.git: 22 | git clone https://github.com/git/git.git 23 | 24 | quake: ioq3/.git 25 | make -C ioq3 CC='${CC} -DSDL_DISABLE_IMMINTRIN_H -D__inline__=inline' GENERATE_DEPENDENCIES=0 USE_CURL=0 26 | 27 | ioq3/.git: 28 | git clone https://github.com/ioquake/ioq3.git 29 | 30 | clean: 31 | make -C git clean 32 | make -C ioq3 clean 33 | 34 | .PHONY: help git quake clean 35 | -------------------------------------------------------------------------------- /demo/ccwrap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys, os 4 | import subprocess 5 | 6 | if __name__ == "__main__": 7 | args = sys.argv[:] 8 | args[0] = 'cc' 9 | if "-c" in args: 10 | args[0] = os.getenv('CC', 'cc') 11 | print " ".join(args) 12 | 13 | c = subprocess.call(args) 14 | sys.exit(c) 15 | -------------------------------------------------------------------------------- /doc/cfg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larmel/lacc/30839843daaff9d87574b5854854c9ee4610cdcd/doc/cfg.png -------------------------------------------------------------------------------- /doc/csmith.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/larmel/lacc/30839843daaff9d87574b5854854c9ee4610cdcd/doc/csmith.png -------------------------------------------------------------------------------- /include/lacc/context.h: -------------------------------------------------------------------------------- 1 | #ifndef CONTEXT_H 2 | #define CONTEXT_H 3 | #if !defined(INTERNAL) || !defined(EXTERNAL) 4 | # error Missing amalgamation macros 5 | #endif 6 | 7 | #include 8 | 9 | enum target { 10 | TARGET_PREPROCESS, 11 | TARGET_IR_DOT, 12 | TARGET_ASM, 13 | TARGET_OBJ, 14 | TARGET_EXE 15 | }; 16 | 17 | enum cstd { 18 | STD_C89, 19 | STD_C99, 20 | STD_C11 21 | }; 22 | 23 | /* Global information about translation unit. */ 24 | INTERNAL struct context { 25 | int errors; 26 | int verbose; 27 | int suppress_warning; 28 | unsigned int pic : 1; /* position independent code */ 29 | unsigned int debug : 1; /* Generate debug information. */ 30 | unsigned int no_common : 1; /* Don't use COMMON symbols. */ 31 | unsigned int no_sse : 1; /* Don't use SSE instructions. */ 32 | unsigned int pedantic : 1; 33 | unsigned int nostdinc : 1; 34 | enum target target; 35 | enum cstd standard; 36 | } context; 37 | 38 | /* 39 | * Output diagnostics info to stdout. No-op if context.verbose is not 40 | * set. 41 | */ 42 | INTERNAL void verbose(const char *, ...); 43 | 44 | /* 45 | * Output warning to stderr. No-op if context.suppress_warning is set. 46 | */ 47 | INTERNAL void warning(const char *, ...); 48 | 49 | /* Output error to stderr. */ 50 | INTERNAL void error(const char *, ...); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /include/lacc/deque.h: -------------------------------------------------------------------------------- 1 | #ifndef DEQUE_H 2 | #define DEQUE_H 3 | 4 | #include "array.h" 5 | 6 | /* 7 | * Declare a type resembling a deque in C++, which can be efficiently 8 | * pushed and popped from either side. 9 | */ 10 | #define deque_of(T) \ 11 | struct { \ 12 | int cursor; \ 13 | array_of(T) array; \ 14 | } 15 | 16 | #define deque_len(deq) \ 17 | ((deq)->array.length - (deq)->cursor) 18 | 19 | #define deque_push_back(deq, elem) \ 20 | do { \ 21 | if ((deq)->cursor && (deq)->array.length == (deq)->array.capacity) { \ 22 | memmove( \ 23 | (deq)->array.data, \ 24 | (deq)->array.data + (deq)->cursor, \ 25 | deque_len(deq) * sizeof(elem)); \ 26 | (deq)->array.length = deque_len(deq); \ 27 | (deq)->cursor = 0; \ 28 | } \ 29 | array_push_back(&(deq)->array, elem); \ 30 | } while (0) 31 | 32 | #define deque_back(deq) \ 33 | deque_get(deq, deque_len(deq) - 1) 34 | 35 | #define deque_pop_back(deq) \ 36 | array_pop_back(&(deq)->array) 37 | 38 | #define deque_pop_front(deq) \ 39 | array_get(&(deq)->array, (deq)->cursor++) 40 | 41 | #define deque_get(deq, i) \ 42 | array_get(&(deq)->array, (deq)->cursor + i) 43 | 44 | #define deque_empty(deq) \ 45 | do { \ 46 | (deq)->cursor = 0; \ 47 | array_empty(&(deq)->array); \ 48 | } while (0) 49 | 50 | #define deque_destroy(deq) \ 51 | do { \ 52 | (deq)->cursor = 0; \ 53 | array_clear(&(deq)->array); \ 54 | } while (0) 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /include/lacc/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef HASH_H 2 | #define HASH_H 3 | #if !defined(INTERNAL) || !defined(EXTERNAL) 4 | # error Missing amalgamation macros 5 | #endif 6 | 7 | #include "string.h" 8 | 9 | struct hash_table { 10 | int capacity; 11 | int count; 12 | struct hash_entry *entries; 13 | }; 14 | 15 | /* Reset table, clearing all values. Does not deallocate memory. */ 16 | INTERNAL void hash_clear(struct hash_table *tab, void (*del)(void *)); 17 | 18 | /* Free resources owned by table. */ 19 | INTERNAL void hash_destroy(struct hash_table *tab); 20 | 21 | /* 22 | * Insert element, or return existing with the same key. 23 | * 24 | * Initializer, if provided, is invoked when data is added. 25 | */ 26 | INTERNAL void *hash_insert( 27 | struct hash_table *tab, 28 | String key, 29 | void *value, 30 | void *(*add)(void *, String *)); 31 | 32 | /* Retrieve element matching key, or NULL if not found. */ 33 | INTERNAL void *hash_lookup(struct hash_table *tab, String key); 34 | 35 | /* 36 | * Remove element matching key. 37 | * 38 | * Finalizer, if provider, is invoked when data is removed. 39 | */ 40 | INTERNAL void hash_remove( 41 | struct hash_table *tab, 42 | String key, 43 | void (*del)(void *)); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /include/lacc/string.h: -------------------------------------------------------------------------------- 1 | #ifndef STRING_H 2 | #define STRING_H 3 | #if !defined(INTERNAL) || !defined(EXTERNAL) 4 | # error Missing amalgamation macros 5 | #endif 6 | 7 | #include 8 | #include 9 | 10 | #define SHORT_STRING_LEN 15 11 | #define SHORT_STRING_INIT(s) {{s, SHORT_STRING_LEN - (sizeof(s) - 1)}} 12 | #define IS_SHORT_STRING(s) ((s).small.cap >= 0) 13 | #define MAX_STRING_LEN 0x00ffffffffffffff 14 | 15 | /* 16 | * Compact representation of strings, such as identifiers and literals. 17 | * Optimize for short lengths, storing it inline in the object itself. 18 | * This type fits in 2 eightbytes. 19 | * 20 | * Small strings use up to the first 15 bytes as the string value, and 21 | * the last byte is remaining capacity. This is a very clever idea that 22 | * is inspired by FBString. When the string is full, the remaining 23 | * capacity is zero, and works dual purpose as null terminator. This 24 | * also allows storing small strings with embedded null characters. 25 | * 26 | * Large strings (more than 15 chars) are stored as a pointer followed 27 | * by a length of 7 bytes. We rely on little endian for length access to 28 | * work by just masking away the last byte, which contain a negative 29 | * value to signal a large string. 30 | */ 31 | typedef union { 32 | struct { 33 | char buf[SHORT_STRING_LEN]; 34 | signed char cap; 35 | } small; 36 | struct { 37 | const char *ptr; 38 | size_t len; 39 | } large; 40 | } String; 41 | 42 | /* 43 | * Get pointer to plain C string representation. This depends on the 44 | * type of string, whether it is small or large. 45 | * 46 | * Note that this cannot be implemented as a function call, since the 47 | * resulting pointer is only valid for the same duration as the string 48 | * argument. 49 | */ 50 | #define str_raw(s) (IS_SHORT_STRING(s) ? (s).small.buf : (s).large.ptr) 51 | 52 | /* Compute length of string. */ 53 | INTERNAL size_t str_len(String s); 54 | 55 | /* Return an empty string. */ 56 | INTERNAL String str_empty(void); 57 | 58 | /* Compare string length to 0. */ 59 | INTERNAL int str_is_empty(String s); 60 | 61 | /* Compare two strings for equality. */ 62 | INTERNAL int str_eq(String s1, String s2); 63 | 64 | /* Return 1 iff string contains given character. */ 65 | INTERNAL int str_has_chr(String s, char c); 66 | 67 | /* Hash of string. */ 68 | INTERNAL int str_hash(String str); 69 | 70 | /* 71 | * Create string from c string, where length can be determined by 72 | * strlen. 73 | */ 74 | INTERNAL String str_c(const char *s); 75 | 76 | /* 77 | * Output string to stream, in safe encoding for textual assembly or as 78 | * plain C code. 79 | */ 80 | INTERNAL int fprintstr(FILE *stream, String str); 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /lib/lacc/include/alloca.h: -------------------------------------------------------------------------------- 1 | #ifndef _ALLOCA_H 2 | #define _ALLOCA_H 3 | 4 | #define alloca(n) __builtin_alloca(n) 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /lib/lacc/include/float.h: -------------------------------------------------------------------------------- 1 | #ifndef _FLOAT_H 2 | #define _FLOAT_H 3 | 4 | /* 5 | * IEEE float. 6 | */ 7 | #define FLT_RADIX 2 8 | #define FLT_ROUNDS 1 9 | #define FLT_DIG 6 10 | #define FLT_EPSILON 1.19209290e-07f 11 | #define FLT_MANT_DIG 24 12 | #define FLT_MAX 3.40282347e+38f 13 | #define FLT_MAX_EXP 128 14 | #define FLT_MIN 1.17549435e-38f 15 | #define FLT_MIN_EXP (-125) 16 | 17 | /* 18 | * IEEE double. 19 | */ 20 | #define DBL_DIG 15 21 | #define DBL_EPSILON 2.2204460492503131e-16 22 | #define DBL_MANT_DIG 53 23 | #define DBL_MAX 1.7976931348623157e+308 24 | #define DBL_MAX_EXP 1024 25 | #define DBL_MIN 2.2250738585072014e-308 26 | #define DBL_MIN_EXP (-1021) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /lib/lacc/include/stdalign.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDALIGN_H 2 | #define _STDALIGN_H 3 | 4 | #define alignof _Alignof 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /lib/lacc/include/stdarg.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDARG_H 2 | #define _STDARG_H 3 | 4 | /* 5 | * Variable argument list is a builtin type defined by the compiler, 6 | * both for gcc and lacc. Alias magic internal symbol to va_list. 7 | */ 8 | typedef __builtin_va_list va_list; 9 | 10 | /* 11 | * Bug in glibc, requiring this symbol. 12 | */ 13 | typedef __builtin_va_list __gnuc_va_list; 14 | 15 | /* 16 | * va_start and va_arg are handled as compiler builtins, intercepted 17 | * during parsing. va_end is a no-op, no cleanup is required. 18 | */ 19 | #define va_start(list, arg) __builtin_va_start(list, arg) 20 | #define va_arg(list, type) __builtin_va_arg(list, type) 21 | #define va_end(list) 22 | 23 | /* va_copy is introduced with C99. */ 24 | #if __STDC_VERSION__ >= 199901L 25 | # define va_copy(dst, src) (*(dst) = *(src)) 26 | #endif 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /lib/lacc/include/stdbool.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDBOOL_H 2 | #define _STDBOOL_H 3 | 4 | #define bool _Bool 5 | #define true 1 6 | #define false 0 7 | #define __bool_true_false_are_defined 1 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lib/lacc/include/stddef.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDDEF_H 2 | #define _STDDEF_H 3 | 4 | typedef __SIZE_TYPE__ size_t; 5 | typedef __PTRDIFF_TYPE__ ptrdiff_t; 6 | typedef __WCHAR_TYPE__ wchar_t; 7 | 8 | #define NULL ((void *) 0) 9 | #define offsetof(T, field) ((size_t) &((T *) 0)->field) 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /lib/lacc/include/stdnoreturn.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDNORETURN_H 2 | #define _STDNORETURN_H 3 | 4 | #define noreturn _Noreturn 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/backend/arm64/compile.c: -------------------------------------------------------------------------------- 1 | #if !AMALGAMATION 2 | # define INTERNAL 3 | # define EXTERNAL extern 4 | #endif 5 | #include 6 | 7 | #include 8 | 9 | INTERNAL void set_compile_target(FILE *stream, const char *file) 10 | { 11 | printf("Compiling for ARM!\n"); 12 | } 13 | 14 | INTERNAL int compile(struct definition *def) 15 | { 16 | return 0; 17 | } 18 | 19 | INTERNAL int declare(const struct symbol *sym) 20 | { 21 | return 0; 22 | } 23 | 24 | INTERNAL void flush(void) 25 | { 26 | } 27 | 28 | INTERNAL void finalize(void) 29 | { 30 | } 31 | -------------------------------------------------------------------------------- /src/backend/compile.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPILE_H 2 | #define COMPILE_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | /* 9 | * Initialize compile target format and output stream. Must be called 10 | * before any other compile function. 11 | */ 12 | INTERNAL void set_compile_target(FILE *stream, const char *file); 13 | 14 | /* Compile definition, symbols which are assigned some storage. */ 15 | INTERNAL int compile(struct definition *def); 16 | 17 | /* 18 | * Compile tentative definitions and declarations; symbols which have 19 | * not been assigned a value in this translation unit, but must be known 20 | * for linkage. 21 | */ 22 | INTERNAL int declare(const struct symbol *sym); 23 | 24 | /* Flush any buffered output, no more input will follow. */ 25 | INTERNAL void flush(void); 26 | 27 | /* Free resources after all input objects have been processed. */ 28 | INTERNAL void finalize(void); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/backend/dot.h: -------------------------------------------------------------------------------- 1 | #ifndef DOT_H 2 | #define DOT_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | /* 9 | * Output internal control flow graph intermediate representation in dot 10 | * format, which can be compiled for rendering. 11 | */ 12 | INTERNAL void dotgen(FILE *stream, struct definition *def); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/backend/linker.h: -------------------------------------------------------------------------------- 1 | #ifndef LINKER_H 2 | #define LINKER_H 3 | 4 | #include 5 | 6 | /* Add command line argument to be passed to the linker. */ 7 | INTERNAL int add_linker_arg(const char *opt); 8 | 9 | /* Invoke the system linker. */ 10 | INTERNAL int invoke_linker(void); 11 | 12 | /* Free memory used for linker arguments. */ 13 | INTERNAL void clear_linker_args(void); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/backend/x86_64/abi.h: -------------------------------------------------------------------------------- 1 | #ifndef ABI_H 2 | #define ABI_H 3 | 4 | #include 5 | 6 | #define MAX_INTEGER_ARGS 6 7 | #define MAX_SSE_ARGS 8 8 | #define MAX_REGISTER_ARGS (MAX_INTEGER_ARGS + MAX_SSE_ARGS) 9 | #define MAX_INTEGER_RET 2 10 | #define MAX_SSE_RET 2 11 | 12 | /* 13 | * Parameter class of an 8-byte slice of an object. Objects which take 14 | * up more than 4 eightbytes automatically get class PC_MEMORY. 15 | */ 16 | struct param_class { 17 | unsigned char eightbyte[4]; 18 | }; 19 | 20 | #define PC_NO_CLASS 0x00 21 | #define PC_INTEGER 0x01 22 | #define PC_SSE 0x02 23 | #define PC_SSEUP 0x04 24 | #define PC_X87 0x08 25 | #define PC_X87UP 0x10 26 | #define PC_COMPLEX_X87 0x20 27 | #define PC_MEMORY 0x40 28 | 29 | /* 30 | * Calculate how many eightbytes is necessary to pass an object of the 31 | * given type as a parameter or return value. 32 | */ 33 | #define EIGHTBYTES(t) ((size_of(t) + 7) / 8) 34 | 35 | /* 36 | * Parameter classification as described in System V ABI (3.2.3), with 37 | * some simplifications. Classify parameter as a series of eightbytes 38 | * used for parameter passing and return value. 39 | */ 40 | INTERNAL struct param_class classify(Type type); 41 | 42 | /* Alignment of symbol in bytes. */ 43 | INTERNAL int sym_alignment(const struct symbol *sym); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/backend/x86_64/assemble.h: -------------------------------------------------------------------------------- 1 | #ifndef ASSEMBLE_H 2 | #define ASSEMBLE_H 3 | 4 | #include "encoding.h" 5 | 6 | #include 7 | 8 | /* Call once on startup, with output handle and source filename. */ 9 | INTERNAL void asm_init(FILE *output, const char *file); 10 | 11 | /* 12 | * Start processing symbol. If the symbol is static, data will follow. 13 | * If the symbol is of function type, instructions should follow. The 14 | * end of a symbol context is reached when this function is called 15 | * again, or on flush. 16 | */ 17 | INTERNAL int asm_symbol(const struct symbol *sym); 18 | 19 | /* Add instruction to function context. */ 20 | INTERNAL int asm_text(struct instruction instr); 21 | 22 | /* Add data to internal symbol context. */ 23 | INTERNAL int asm_data(struct immediate data); 24 | 25 | /* Write any buffered data to output. */ 26 | INTERNAL int asm_flush(void); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/backend/x86_64/assembler.h: -------------------------------------------------------------------------------- 1 | #ifndef ASSEMBLER_H 2 | #define ASSEMBLER_H 3 | 4 | #include "encoding.h" 5 | #include 6 | 7 | INTERNAL int assemble_inline( 8 | struct asm_statement st, 9 | int (*emit)(struct instruction)); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/backend/x86_64/dwarf.h: -------------------------------------------------------------------------------- 1 | #ifndef DWARF_H 2 | #define DWARF_H 3 | 4 | INTERNAL int dwarf_init(const char *filename); 5 | 6 | INTERNAL int dwarf_flush(void); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/context.c: -------------------------------------------------------------------------------- 1 | #if !AMALGAMATION 2 | # define INTERNAL 3 | # define EXTERNAL extern 4 | #endif 5 | #include "parser/typetree.h" 6 | #include "preprocessor/input.h" 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | INTERNAL struct context context = {0}; 14 | 15 | /* 16 | * Custom implementation of printf, handling a restricted set of 17 | * formatters: %s, %c, %d, %lu, %ld, %%. 18 | * 19 | * In addition, have a custom formatter for objects representing a 20 | * compiler-internal type object. 21 | * 22 | * %t : Type 23 | * 24 | */ 25 | static int vfprintf_cc(FILE *stream, const char *format, va_list ap) 26 | { 27 | int c, n = 0; 28 | if (!format) { 29 | return n; 30 | } 31 | 32 | while ((c = *format++) != 0) { 33 | if (c != '%') { 34 | putc(c, stream); 35 | n += 1; 36 | } else { 37 | c = *format++; 38 | switch (c) { 39 | default: assert(0); 40 | case 's': 41 | n += fputs(va_arg(ap, const char *), stream); 42 | break; 43 | case 'c': 44 | n += fprintf(stream, "%c", va_arg(ap, int)); 45 | break; 46 | case 'd': 47 | n += fprintf(stream, "%d", va_arg(ap, int)); 48 | break; 49 | case 'l': 50 | c = *format++; 51 | switch (c) { 52 | default: assert(0); 53 | case 'u': 54 | n += fprintf(stream, "%lu", va_arg(ap, unsigned long)); 55 | break; 56 | case 'd': 57 | n += fprintf(stream, "%ld", va_arg(ap, long)); 58 | break; 59 | } 60 | break; 61 | case 't': 62 | n += fprinttype(stream, va_arg(ap, Type), NULL); 63 | break; 64 | case '%': 65 | n += fprintf(stream, "%%"); 66 | break; 67 | } 68 | } 69 | } 70 | 71 | return n; 72 | } 73 | 74 | INTERNAL void verbose(const char *format, ...) 75 | { 76 | if (context.verbose) { 77 | va_list args; 78 | va_start(args, format); 79 | vfprintf_cc(stdout, format, args); 80 | fputc('\n', stdout); 81 | va_end(args); 82 | } 83 | } 84 | 85 | INTERNAL void warning(const char *format, ...) 86 | { 87 | va_list args; 88 | if (!context.suppress_warning) { 89 | va_start(args, format); 90 | fprintf( 91 | stderr, 92 | "(%s, %d) warning: ", 93 | str_raw(current_file_path), 94 | current_file_line); 95 | vfprintf_cc(stderr, format, args); 96 | fputc('\n', stderr); 97 | va_end(args); 98 | } 99 | } 100 | 101 | INTERNAL void error(const char *format, ...) 102 | { 103 | va_list args; 104 | 105 | context.errors++; 106 | va_start(args, format); 107 | fprintf( 108 | stderr, 109 | "(%s, %d) error: ", 110 | str_raw(current_file_path), 111 | current_file_line); 112 | vfprintf_cc(stderr, format, args); 113 | fputc('\n', stderr); 114 | va_end(args); 115 | } 116 | -------------------------------------------------------------------------------- /src/optimizer/liveness.h: -------------------------------------------------------------------------------- 1 | #ifndef LIVENESS_H 2 | #define LIVENESS_H 3 | 4 | #include 5 | 6 | /* 7 | * Compute liveness of each variable on every edge, before and after 8 | * every ir operation. 9 | */ 10 | INTERNAL int live_variable_analysis( 11 | struct definition *def, 12 | struct block *block); 13 | 14 | /* 15 | * Determine whether a variable may be read after a given statement. 16 | * Return zero iff it is definitely not accessed after this point. 17 | */ 18 | INTERNAL int is_live_after( 19 | const struct symbol *sym, 20 | const struct statement *st); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/optimizer/optimize.h: -------------------------------------------------------------------------------- 1 | #ifndef OPTIMIZE_H 2 | #define OPTIMIZE_H 3 | 4 | #include "liveness.h" 5 | 6 | #include 7 | 8 | /* Set to non-zero to enable optimization. */ 9 | INTERNAL void push_optimization(int level); 10 | 11 | /* 12 | * Do data flow analysis and perform optimizations on the intermediate 13 | * representation. Leaves the definition in a semantically equivalent, 14 | * and hopefully more consise, state. 15 | */ 16 | INTERNAL void optimize(struct definition *def); 17 | 18 | /* Disable previously set optimization, cleaning up resources. */ 19 | INTERNAL void pop_optimization(void); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/optimizer/transform.h: -------------------------------------------------------------------------------- 1 | #ifndef TRANSFORM_H 2 | #define TRANSFORM_H 3 | 4 | #include 5 | 6 | /* 7 | * Optimization pass which joins together sequential assignments to the 8 | * same variable into a single statement. 9 | * 10 | * .t1 = a + 1 11 | * b = .t1 12 | * 13 | * If .t1 is not live after the second line, the sequence can be 14 | * converted to the following: 15 | * 16 | * b = a + 1 17 | * 18 | */ 19 | INTERNAL int merge_chained_assignment( 20 | struct definition *def, 21 | struct block *block); 22 | 23 | /* 24 | * Remove assignments to variables that are never read, as determined by 25 | * liveness analysis. 26 | */ 27 | INTERNAL int dead_store_elimination( 28 | struct definition *def, 29 | struct block *block); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/parser/builtin.h: -------------------------------------------------------------------------------- 1 | #ifndef BUILTIN_H 2 | #define BUILTIN_H 3 | 4 | #include 5 | 6 | /* 7 | * Register compiler internal builtin symbols, that are assumed to 8 | * exists by standard library headers. 9 | */ 10 | INTERNAL void register_builtins(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/parser/declaration.h: -------------------------------------------------------------------------------- 1 | #ifndef DECLARATION_H 2 | #define DECLARATION_H 3 | 4 | #include 5 | 6 | INTERNAL struct block *declaration( 7 | struct definition *def, 8 | struct block *parent); 9 | 10 | /* 11 | * Parse a declarator. Set name = NULL for abstract declarator, only 12 | * expecting a type. 13 | * 14 | * Declarators can produce evaluation through VLA types. 15 | */ 16 | INTERNAL struct block *declarator( 17 | struct definition *def, 18 | struct block *parent, 19 | Type base, 20 | Type *type, 21 | String *name); 22 | 23 | struct declaration_specifier_info { 24 | enum token_type storage_class; 25 | unsigned int is_inline : 1; 26 | unsigned int is_noreturn : 1; 27 | unsigned int is_register : 1; 28 | unsigned int from_typedef : 1; 29 | }; 30 | 31 | INTERNAL Type declaration_specifiers( 32 | struct declaration_specifier_info *info); 33 | 34 | INTERNAL struct block *declare_vla( 35 | struct definition *def, 36 | struct block *block, 37 | struct symbol *sym); 38 | 39 | #define FIRST_type_qualifier \ 40 | CONST: case VOLATILE 41 | 42 | #define FIRST_type_specifier \ 43 | VOID: case BOOL: case CHAR: case SHORT: case INT: case LONG: case FLOAT: \ 44 | case DOUBLE: case SIGNED: case UNSIGNED: case STRUCT: case UNION: case ENUM 45 | 46 | #define FIRST_type_name \ 47 | FIRST_type_qualifier: \ 48 | case FIRST_type_specifier 49 | 50 | #define FIRST(s) FIRST_ ## s 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/parser/expression.h: -------------------------------------------------------------------------------- 1 | #ifndef EXPRESSION_H 2 | #define EXPRESSION_H 3 | 4 | #include 5 | 6 | INTERNAL struct block *expression(struct definition *def, struct block *block); 7 | 8 | INTERNAL struct var constant_expression(void); 9 | 10 | INTERNAL struct block *assignment_expression( 11 | struct definition *def, 12 | struct block *block); 13 | 14 | INTERNAL struct block *conditional_expression( 15 | struct definition *def, 16 | struct block *block); 17 | 18 | INTERNAL void expression_parse_finalize(void); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/parser/initializer.h: -------------------------------------------------------------------------------- 1 | #ifndef INITIALIZER_H 2 | #define INITIALIZER_H 3 | 4 | #include 5 | 6 | /* 7 | * Parse and emit code for initializer expressions, such as the right 8 | * hand side of the following assignments: 9 | * 10 | * int b[] = {0, 1, 2, 3}; 11 | * floaf f = 3.14f; 12 | * 13 | * Generates a series of assignment operations on references to target 14 | * symbol, with increasing offsets. 15 | * 16 | * An initializer can either be an assignment expression, or a brace- 17 | * enclosed initializer list. 18 | */ 19 | INTERNAL struct block *initializer( 20 | struct definition *def, 21 | struct block *block, 22 | const struct symbol *sym); 23 | 24 | /* Free memory used for internal structures. */ 25 | INTERNAL void initializer_finalize(void); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/parser/parse.h: -------------------------------------------------------------------------------- 1 | #ifndef PARSE_H 2 | #define PARSE_H 3 | 4 | #include 5 | 6 | /* 7 | * Parse input for the next function or object definition, or NULL on 8 | * end of input. 9 | */ 10 | INTERNAL struct definition *parse(void); 11 | 12 | /* Create an empty control flow graph. 13 | * 14 | * This is done in declaration parsing, which needs an empty graph while 15 | * reading declarations. Declarations ending up defining a symbol are 16 | * completed with cfg_define(2), making the struct definition object 17 | * available in later calls to parse(0). 18 | * 19 | * Declarations that only represent a prototype should not generate any 20 | * code, and the graph can be thrown away with cfg_discard(1). 21 | */ 22 | INTERNAL struct definition *cfg_init(void); 23 | 24 | /* Associate symbol with a function or global variable definition. */ 25 | INTERNAL void cfg_define(struct definition *def, const struct symbol *sym); 26 | 27 | /* Release resources associated with control flow graph. */ 28 | INTERNAL void cfg_discard(struct definition *def); 29 | 30 | /* Create a basic block associated with control flow graph. */ 31 | INTERNAL struct block *cfg_block_init(struct definition *def); 32 | 33 | INTERNAL struct block *begin_throwaway_block(struct definition *def); 34 | 35 | INTERNAL void restore_block(struct definition *def); 36 | 37 | /* Free memory after all input files are processed. */ 38 | INTERNAL void parse_finalize(void); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/parser/statement.h: -------------------------------------------------------------------------------- 1 | #ifndef STATEMENT_H 2 | #define STATEMENT_H 3 | 4 | #include 5 | 6 | INTERNAL struct block *statement(struct definition *def, struct block *parent); 7 | 8 | INTERNAL struct block *block(struct definition *def, struct block *parent); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/preprocessor/directive.h: -------------------------------------------------------------------------------- 1 | #ifndef DIRECTIVE_H 2 | #define DIRECTIVE_H 3 | 4 | #include "macro.h" 5 | #include 6 | 7 | EXTERNAL struct token 8 | ident__include, 9 | ident__defined, 10 | ident__define, 11 | ident__ifndef, 12 | ident__ifdef, 13 | ident__undef, 14 | ident__elif, 15 | ident__endif, 16 | ident__error, 17 | ident__pragma, 18 | ident__Pragma; 19 | 20 | /* 21 | * Preprocess a line starting with a '#' directive. Borrows ownership of 22 | * input. Assume input is END terminated. 23 | */ 24 | INTERNAL void preprocess_directive(TokenArray *line); 25 | 26 | /* Non-zero iff currently not inside a false #if directive. */ 27 | INTERNAL int in_active_block(void); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/preprocessor/input.h: -------------------------------------------------------------------------------- 1 | #ifndef INPUT_H 2 | #define INPUT_H 3 | 4 | #include 5 | 6 | /* 7 | * Initialize with root file name, and store relative path to resolve 8 | * later includes. Passing NULL defaults to taking input from stdin. 9 | */ 10 | INTERNAL void set_input_file(const char *); 11 | 12 | /* Free resources used for reading input. */ 13 | INTERNAL void input_finalize(void); 14 | 15 | /* 16 | * Paths specified with -I, append to list of directories to search when 17 | * resolving includes. 18 | */ 19 | INTERNAL int add_include_search_path(const char *); 20 | 21 | /* Push new include file. */ 22 | INTERNAL void include_file(const char *); 23 | INTERNAL void include_system_file(const char *); 24 | 25 | /* Add file to be included before the main source file. */ 26 | INTERNAL int add_include_file(const char *path); 27 | 28 | /* 29 | * Yield next line ready for further preprocessing. Joins continuations, 30 | * and replaces comments with a single space. Line implicitly ends with 31 | * a single newline character ('\n'), but it is not included. 32 | */ 33 | INTERNAL char *getprepline(void); 34 | 35 | /* Path of file and line number that was last read. */ 36 | EXTERNAL String current_file_path; 37 | EXTERNAL int current_file_line; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/preprocessor/macro.h: -------------------------------------------------------------------------------- 1 | #ifndef MACRO_H 2 | #define MACRO_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef array_of(struct token) TokenArray; 9 | 10 | /* Get empty token array, possibly already allocated with capacity. */ 11 | INTERNAL TokenArray get_token_array(void); 12 | 13 | /* Release token array previously aquired by get_token_array. */ 14 | INTERNAL void release_token_array(TokenArray list); 15 | 16 | struct macro { 17 | String name; 18 | 19 | enum { 20 | OBJECT_LIKE, 21 | FUNCTION_LIKE 22 | } type; 23 | 24 | /* Number of parameters required for substitution. */ 25 | int params; 26 | 27 | unsigned int is__line__ : 1; 28 | unsigned int is__file__ : 1; 29 | unsigned int is_vararg : 1; 30 | 31 | /* 32 | * A substitution is either a token or a parameter, and parameters 33 | * are represented by PARAM tokens with an integer index between 34 | * 0 and params. 35 | */ 36 | TokenArray replacement; 37 | }; 38 | 39 | /* 40 | * Initialize hash table used for macro definitions. Recycle buffers 41 | * between input files. 42 | */ 43 | INTERNAL void macro_reset(void); 44 | 45 | /* Free memory used for macro definitions. */ 46 | INTERNAL void macro_finalize(void); 47 | 48 | /* 49 | * Define macros that are intrinsic to the compiler, or mandated by the 50 | * standard. 51 | */ 52 | INTERNAL void register_builtin_definitions(enum cstd version); 53 | 54 | /* Stringify a list of tokens, returning a new token of type STRING. */ 55 | INTERNAL struct token stringify(const TokenArray *list); 56 | 57 | /* 58 | * Add macro definition. Takes ownership of any dynamically allocated 59 | * replacement list. 60 | */ 61 | INTERNAL void define(struct macro macro); 62 | 63 | /* 64 | * Remove macro definition corresponding to identifier. If the name has 65 | * not previously been defined, this is a no-op. 66 | */ 67 | INTERNAL void undef(String name); 68 | 69 | /* Look up definition of identifier, or NULL if not defined. */ 70 | INTERNAL const struct macro *macro_definition(String name); 71 | 72 | /* 73 | * Expand a list of tokens, replacing any macro definitions. Mutates 74 | * input list as necessary. Return non-zero if any macro was expanded. 75 | */ 76 | INTERNAL int expand(TokenArray *list); 77 | 78 | /* 79 | * Compare tokens for equality, returing 0 iff of same type and value. 80 | */ 81 | INTERNAL int tok_cmp(struct token a, struct token b); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/preprocessor/preprocess.h: -------------------------------------------------------------------------------- 1 | #ifndef PREPROCESS_H 2 | #define PREPROCESS_H 3 | 4 | #include 5 | 6 | /* 7 | * Output preprocessed input to provided stream, toggled by -E program 8 | * option. 9 | */ 10 | INTERNAL void preprocess(FILE *output); 11 | 12 | /* 13 | * Preprocess a single line, adding any resulting tokens to the 14 | * lookahead buffer. This should happen before any input file is read. 15 | * 16 | * The string is destructively tokenized. It should contain no newlines, 17 | * comments, or line continuations. 18 | */ 19 | INTERNAL void inject_line(char *line); 20 | 21 | /* Initialize data structures used for preprocessing. */ 22 | INTERNAL void preprocess_reset(void); 23 | 24 | /* Free memory used for preprocessing. */ 25 | INTERNAL void preprocess_finalize(void); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/preprocessor/strtab.h: -------------------------------------------------------------------------------- 1 | #ifndef STRTAB_H 2 | #define STRTAB_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | /* 11 | * Register a string and store it internally as a singleton, allocating 12 | * a copy for each unique string. 13 | * 14 | * This is the only valid way of creating string objects, and it 15 | * guarantees that equality checks can be reduced to checking pointers 16 | * internally. 17 | */ 18 | INTERNAL String str_intern(const char *str, size_t len); 19 | 20 | /* Concatenate two strings together, returning a new interned string. */ 21 | INTERNAL String str_cat(String a, String b); 22 | 23 | /* Free memory used for string table. */ 24 | INTERNAL void strtab_reset(void); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/preprocessor/tokenize.h: -------------------------------------------------------------------------------- 1 | #ifndef TOKENIZE_H 2 | #define TOKENIZE_H 3 | 4 | #include 5 | 6 | /* 7 | * Table is indexed by ASCII value, which is also assigned to 8 | * corresponding token type. To get a token of a particular type, 9 | * access basic_token[type]. 10 | */ 11 | EXTERNAL const struct token basic_token[128]; 12 | 13 | /* 14 | * Transform preprocessing number to numeric literal, parsing the string 15 | * representation to a typed number. 16 | * 17 | * This is done as a last step in preprocessing before handing the token 18 | * over to the parser. 19 | */ 20 | INTERNAL struct token convert_preprocessing_number(struct token t); 21 | 22 | /* 23 | * Transform preprocessing string by substituting all escape sequences 24 | * by the corresponding character. 25 | * 26 | * This is done as a last step in preprocessing before handing the token 27 | * over to the parser. 28 | */ 29 | INTERNAL struct token convert_preprocessing_string(struct token t); 30 | 31 | /* 32 | * Transform preprocessing character to numeric literal, converting the 33 | * string representation to an integer value stored in a NUMBER token. 34 | * 35 | * This is done as a last step in preprocessing before handing the token 36 | * over to the parser. 37 | */ 38 | INTERNAL struct token convert_preprocessing_char(struct token t); 39 | 40 | /* 41 | * Parse and return next preprocessing token from given line. Assume 42 | * comments are removed and line continuations are applied. endptr is 43 | * set to point to one index past the last character producing the 44 | * token. 45 | */ 46 | INTERNAL struct token tokenize(const char *in, const char **endptr); 47 | 48 | /* Free memory used to hold temporary strings during tokenization. */ 49 | INTERNAL void tokenize_reset(void); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/util/argparse.h: -------------------------------------------------------------------------------- 1 | #ifndef ARGPARSE_H 2 | #define ARGPARSE_H 3 | 4 | /* 5 | * Specify command line argument pattern as a rule template with an 6 | * associated callback, which is invoked on match. 7 | * 8 | * "-S" Regular options, which must match exactly as a single 9 | * "--help" token. 10 | * 11 | * "-I:" Option with argument. The next token, or suffix of 12 | * this token, is passed as argument to callback. Matches 13 | * both -Ifoo and -I foo. 14 | * 15 | * "-std=" Option with argument which must not be preceeded by any 16 | * "-W<" whitespace. Matches -std=c89 and -Wall, but not 17 | * -std= c89 or -W all. 18 | * 19 | * "foo.c" Arguments without preceeding dash is matched by NULL 20 | * rule. 21 | */ 22 | struct option { 23 | const char *rule; 24 | int (*callback)(const char *); 25 | }; 26 | 27 | /* 28 | * Parse command line arguments according to option specification, and 29 | * return the number of tokens consumed in the process. 30 | * 31 | * Last element of optv must have NULL as rule, and provides a callback 32 | * for arguments that do not match anything. 33 | * 34 | * Abort if a callback produces a non-zero value, returning that value. 35 | * Return 0 if all arguments were processed successfully. 36 | */ 37 | INTERNAL int parse_args(struct option *optv, int argc, char *argv[]); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/util/string.c: -------------------------------------------------------------------------------- 1 | #if !AMALGAMATION 2 | # define INTERNAL 3 | # define EXTERNAL extern 4 | #endif 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | static int printchar(FILE *stream, char ch) 14 | { 15 | int c = (unsigned char) ch; 16 | if (isprint(c) && c != '"' && c != '\\') { 17 | putc(c, stream); 18 | return 1; 19 | } 20 | 21 | switch (c) { 22 | case '\b': 23 | return fprintf(stream, "\\b"); 24 | case '\t': 25 | return fprintf(stream, "\\t"); 26 | case '\n': 27 | return fprintf(stream, "\\n"); 28 | case '\f': 29 | return fprintf(stream, "\\f"); 30 | case '\r': 31 | return fprintf(stream, "\\r"); 32 | case '\\': 33 | return fprintf(stream, "\\\\"); 34 | case '\"': 35 | return fprintf(stream, "\\\""); 36 | default: 37 | return fprintf(stream, "\\%03o", c); 38 | } 39 | } 40 | 41 | INTERNAL int fprintstr(FILE *stream, String str) 42 | { 43 | int n, i; 44 | size_t len; 45 | const char *raw; 46 | 47 | raw = str_raw(str); 48 | len = str_len(str); 49 | putc('"', stream); 50 | for (n = 0, i = 0; i < len; ++i) { 51 | n += printchar(stream, raw[i]); 52 | } 53 | 54 | putc('"', stream); 55 | return n + 2; 56 | } 57 | 58 | INTERNAL String str_empty(void) 59 | { 60 | String s = SHORT_STRING_INIT(""); 61 | return s; 62 | } 63 | 64 | INTERNAL size_t str_len(String s) 65 | { 66 | if (IS_SHORT_STRING(s)) { 67 | return SHORT_STRING_LEN - s.small.cap; 68 | } 69 | 70 | return s.large.len & MAX_STRING_LEN; 71 | } 72 | 73 | INTERNAL int str_is_empty(String s) 74 | { 75 | return str_len(s) == 0; 76 | } 77 | 78 | INTERNAL int str_eq(String s1, String s2) 79 | { 80 | return s1.large.ptr == s2.large.ptr && s1.large.len == s2.large.len; 81 | } 82 | 83 | INTERNAL int str_has_chr(String s, char c) 84 | { 85 | int i; 86 | size_t len; 87 | const char *str; 88 | 89 | len = str_len(s); 90 | str = str_raw(s); 91 | for (i = 0; i < len; ++i) { 92 | if (str[i] == c) { 93 | return 1; 94 | } 95 | } 96 | 97 | return 0; 98 | } 99 | 100 | INTERNAL int str_hash(String str) 101 | { 102 | int hash, i; 103 | union { 104 | String s; 105 | int d[4]; 106 | } p; 107 | 108 | p.s = str; 109 | assert(sizeof(str) == sizeof(p.d)); 110 | for (hash = 5381, i = 0; i < 4; ++i) { 111 | hash = ((hash << 5) + hash) + p.d[i]; 112 | } 113 | 114 | return hash; 115 | } 116 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | .POSIX: 2 | .SUFFIXES: 3 | 4 | include ../config.mak 5 | 6 | CC = cc 7 | TARGET = ../bin/selfhost/lacc 8 | BIN = ../bin/test 9 | 10 | all: $(TARGET) c89 c99 c11 limits undefined extensions asm linker 11 | 12 | extra: sqlite csmith 13 | 14 | ../bin/bootstrap/lacc: ../bin/lacc 15 | mkdir -p $(@D) 16 | for file in $(SOURCES) ; do \ 17 | target=$(@D)/$$(basename $$file .c).o ; \ 18 | $? -std=c89 -I../include -include ../config.h -c ../$$file -o $$target ; \ 19 | done 20 | $(CC) $(@D)/*.o -o $@ 21 | 22 | ../bin/selfhost/lacc: ../bin/bootstrap/lacc 23 | mkdir -p $(@D) 24 | for file in $(SOURCES) ; do \ 25 | name=$$(basename $$file .c) ; \ 26 | target=$(@D)/$${name}.o ; \ 27 | $? -std=c89 -I../include -include ../config.h -c ../$$file -o $$target ; \ 28 | diff ../bin/bootstrap/$${name}.o $$target ; \ 29 | done 30 | $(CC) $(@D)/*.o -o $@ 31 | 32 | c89 c99 c11: $(TARGET) 33 | mkdir -p $(BIN)/$@ 34 | for file in $$(find $@ -maxdepth 1 -type f -iname '*.c') ; do \ 35 | ./check.sh "$? -std=$@" $$file "$(CC) -std=$@ -w" $(BIN) ; \ 36 | done 37 | 38 | asm extensions: $(TARGET) 39 | mkdir -p $(BIN)/$@ 40 | for file in $$(find $@ -type f -iname '*.c') ; do \ 41 | ./check.sh $? $$file "$(CC) -w" $(BIN) ; \ 42 | done 43 | 44 | limits undefined: $(TARGET) 45 | mkdir -p $(BIN)/$@ 46 | for file in $$(find $@ -type f -iname '*.c') ; do \ 47 | $? $$file -c -o $(BIN)/$$file.o ; \ 48 | $? $(BIN)/$$file.o -o $(BIN)/$$file.out && $(BIN)/$$file.out ; \ 49 | done 50 | 51 | linker: $(TARGET) 52 | ./linker.sh $? 53 | 54 | sqlite: $(TARGET) 55 | ./sqlite.sh $? 56 | 57 | csmith: 58 | ./csmith.sh 59 | 60 | .PHONY: all extra c89 c99 c11 asm extensions limits undefined \ 61 | linker sqlite csmith 62 | -------------------------------------------------------------------------------- /test/asm/alias.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void test1(void) { 4 | int a = 2; 5 | __asm__ ( 6 | "movl $3, %[t] \n" 7 | : [t] "=rm" (a) 8 | : 9 | : 10 | ); 11 | 12 | assert(a == 3); 13 | } 14 | 15 | int main(void) { 16 | test1(); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test/asm/basic.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void test1(int a) { 4 | int b = 0; 5 | __asm__ ( 6 | "mov $5, %%eax \n" 7 | "mov %%eax, %0 \n /* Ignore comment. */" 8 | "mov $3, %%ebx \n" 9 | "add %%ebx, %1 \n" 10 | : "=m" (a), "=m" (b) 11 | : 12 | ); 13 | 14 | assert(a == 5); 15 | assert(b == 3); 16 | } 17 | 18 | void test2(int a) { 19 | int *p = &a; 20 | int b = 2; 21 | __asm ( 22 | "movl $5, %0 \n" 23 | "movl $6, %1 \n" 24 | : "=m" (*p), "=m" (b) 25 | : 26 | ); 27 | 28 | assert(a == 5); 29 | assert(b == 6); 30 | } 31 | 32 | void test3(void) { 33 | int a = 1; 34 | int b = 2; 35 | 36 | __asm__ ( 37 | "add $2, %1 \n\t" 38 | "mov %1, %0 \n\t" 39 | : "=r" (a) 40 | : "r" (b) 41 | ); 42 | 43 | assert(b == 2); 44 | assert(a == 4); 45 | 46 | __asm__ ( 47 | "add $2, %1 \n\t" 48 | "mov %1, %0 \n\t" 49 | : "=r" (a), "+r" (b) 50 | : 51 | ); 52 | 53 | assert(b == 4); 54 | assert(a == 4); 55 | } 56 | 57 | void test4(void) { 58 | int a[] = {1, 2, 3, 4}; 59 | int b = 0; 60 | __asm__ ( 61 | "leaq %1, %%r10 \n\t" 62 | "mov %2, %%r15d \n\t" 63 | "leaq (, %%r15, 4), %%rax \n\t" 64 | "mov (%%r10, %%rax, 1), %0 \n\t" 65 | : "=r" (b) 66 | : "m" (a[0]), "r" (a[1]) 67 | : "rax", "r10", "r15" 68 | ); 69 | 70 | assert(b == a[2]); 71 | } 72 | 73 | void test5(void) { 74 | int a = 1; 75 | __asm__ ( 76 | "add $1, %0 \n" 77 | : "+rm" (a) 78 | ); 79 | 80 | assert(a == 2); 81 | 82 | __asm__ ( 83 | "add $1, %0 \n" 84 | : "+rm" (a) 85 | : 86 | ); 87 | 88 | assert(a == 3); 89 | } 90 | 91 | void test6(void) { 92 | static unsigned char data[4] = { "\xFF\xFF\xFF\xFF" }; 93 | 94 | unsigned int a = 0; 95 | __asm__ volatile ( 96 | "mov (%1), %0 \n" 97 | : "=r" (a) 98 | : "r" (data) 99 | ); 100 | 101 | assert(a == 0xffffffff); 102 | } 103 | 104 | int main(void) { 105 | test1(42); 106 | test2(42); 107 | test3(); 108 | test4(); 109 | test5(); 110 | test6(); 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /test/asm/call.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(int n) { 4 | return n + 1; 5 | } 6 | 7 | int main(void) { 8 | int (*ptr)(int) = foo; 9 | int res = 0; 10 | 11 | __asm__ volatile ( 12 | "mov %1, %%rax \n" 13 | "mov $41, %%edi \n" 14 | "callq *%%rax \n" 15 | "mov %%eax, %0 \n" 16 | : "=rm" (res) 17 | : "rm" (ptr) 18 | : "rax", "edi" 19 | ); 20 | 21 | assert(res == 42); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test/asm/goto.c: -------------------------------------------------------------------------------- 1 | void abort(void); 2 | 3 | void test1(void) { 4 | int a = 2; 5 | __asm__ goto ( 6 | "jmp %l0 \n" 7 | : 8 | : 9 | : 10 | : end 11 | ); 12 | 13 | abort(); 14 | end: 15 | ; 16 | } 17 | 18 | int main(void) { 19 | test1(); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/asm/register-constraint.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int foo(int a, int b, int c, int d) { 4 | int e; 5 | 6 | __asm__ volatile ( 7 | "mov %%ebx, %0 \n" 8 | : "=rm" (e) 9 | ); 10 | 11 | return printf("%d, %d, %d, %d, %d\n", a, b, c, d, e); 12 | } 13 | 14 | int main(void) { 15 | int a = 3, b = 5, c = 9, d = 7, e = 2; 16 | int (*ptr)(int, int, int, int) = foo; 17 | 18 | __asm__ volatile ( 19 | "call *%%rax \n" 20 | "mov $11, %%edi \n" 21 | "mov $12, %%esi \n" 22 | "mov $13, %%ebx \n" 23 | "mov $0, %%eax \n" 24 | "mov $15, %%ecx \n" 25 | "mov $16, %%edx \n" 26 | : "+S" (a), "+D" (b), "+b" (c) 27 | : "a" (ptr), "c" (d), "d" (e) 28 | : "cc", "memory" 29 | ); 30 | 31 | return printf("%d, %d, %d, %d, %d, (%d)\n", a, b, c, d, e, ptr == foo); 32 | } 33 | -------------------------------------------------------------------------------- /test/asm/sse.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | void foo(float *f) { 6 | float p = 0.1f; 7 | 8 | __asm__ volatile ( 9 | "movss (%1), %%xmm1\n" 10 | "movss %%xmm1, %0\n" 11 | : "=m" (p) 12 | : "r" (f) 13 | : "%xmm1" 14 | ); 15 | 16 | assert(p == *f); 17 | } 18 | 19 | void bar(double *d) { 20 | double p = *d * 4.8 + 0.1; 21 | 22 | __asm__ volatile ( 23 | "movsd %0, %%xmm15\n" 24 | "movsd %%xmm15, %%xmm8\n" 25 | "movsd %%xmm8, (%1)\n" 26 | : 27 | : "m" (p), "r" (d) 28 | : "memory", "%xmm8", "%xmm15" 29 | ); 30 | 31 | assert(p == *d); 32 | } 33 | 34 | void sseround(float vec[3]) { 35 | static unsigned char mask[16] = { 36 | 0xFF, 0xFF, 0xFF, 0xFF, 37 | 0xFF, 0xFF, 0xFF, 0xFF, 38 | 0xFF, 0xFF, 0xFF, 0xFF, 39 | 0x00, 0x00, 0x00, 0x00 40 | }; 41 | 42 | __asm__ volatile ( 43 | "movaps (%0), %%xmm1 \n" 44 | "movups (%1), %%xmm0 \n" 45 | "movaps %%xmm0, %%xmm2 \n" 46 | "andps %%xmm1, %%xmm0 \n" 47 | "andnps %%xmm2, %%xmm1 \n" 48 | "cvtps2dq %%xmm0, %%xmm0 \n" 49 | "cvtdq2ps %%xmm0, %%xmm0 \n" 50 | "orps %%xmm1, %%xmm0 \n" 51 | "movups %%xmm0, (%1) \n" 52 | : 53 | : "r" (mask), "r" (vec) 54 | : "memory", "%xmm0", "%xmm1", "%xmm2" 55 | ); 56 | } 57 | 58 | int main(void) { 59 | float f = 3.14f; 60 | double d = 2.71; 61 | float vec[] = {3.14f, 5.66f, 9.61f}; 62 | 63 | foo(&f); 64 | bar(&d); 65 | sseround(vec); 66 | 67 | printf("%f, %f, %f\n", vec[0], vec[1], vec[2]); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /test/asm/symbol-name.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static int a __asm__ ("_A"); 4 | 5 | static int a = 42; 6 | 7 | int b = 2, c __asm__("_C") = 33; 8 | 9 | int foo(int mode) __asm("__" "foo"); 10 | 11 | int foo(int mode) 12 | { 13 | static int d __asm__("__D") = 50; 14 | 15 | return mode + d; 16 | } 17 | 18 | int bar() __asm__("BAR"); 19 | 20 | int bar(mode) 21 | int mode; 22 | { 23 | return mode + c; 24 | }; 25 | 26 | int main(void) { 27 | assert(a == 42); 28 | assert(c == 33); 29 | assert(foo(1) == 51); 30 | assert(bar(2) == 35); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /test/asm/symbol-name.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cc=$1 4 | src=$2 5 | dir=$3 6 | $cc -S ${src}.c -o ${dir}/${src}.s || exit 1 7 | 8 | grep _A: ${dir}/${src}.s > /dev/null || exit 1 9 | grep _C: ${dir}/${src}.s > /dev/null || exit 1 10 | grep __D: ${dir}/${src}.s > /dev/null || exit 1 11 | grep BAR: ${dir}/${src}.s > /dev/null || exit 1 12 | grep __foo: ${dir}/${src}.s > /dev/null || exit 1 13 | 14 | exit 0 15 | -------------------------------------------------------------------------------- /test/asm/variables.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | void foo(void) { 4 | int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6; 5 | 6 | a = b + c * d; 7 | b = (c << 4) + f; 8 | c = e - 2 ^ b; 9 | d = 4 * a - c + c; 10 | 11 | __asm__ ( 12 | "mov %2, %%r13d \n\t" 13 | "add %%r13d, %0 \n\t" 14 | "add %1, %0 \n\t" 15 | : "+r" (d) 16 | : "r" (e), "r" (f) 17 | : "%r13" 18 | ); 19 | 20 | printf("%d, %d, %d, %d, %d, %d\n", a, b, c, d, e, f); 21 | 22 | __asm__ ( 23 | "add %1, %0 \n\t" 24 | : "+r" (a) 25 | : "r" (b) 26 | ); 27 | 28 | printf("%d, %d, %d, %d, %d, %d\n", a, b, c, d, e, f); 29 | } 30 | 31 | int main(void) { 32 | foo(); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /test/asm/x87.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | void foo(float *f) { 4 | __asm__ volatile ( 5 | "flds (%0) \n" 6 | "fistpl (%0) \n" 7 | "fildl (%0) \n" 8 | "fstps (%0) \n" 9 | : 10 | : "r" (f) 11 | : "memory" 12 | ); 13 | 14 | return; 15 | } 16 | 17 | int main(void) { 18 | float f = 3.14f; 19 | float p = f; 20 | foo(&f); 21 | printf("%f, %f\n", f, p); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test/c11/alignof.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | typedef struct { 6 | void *ptr; 7 | unsigned bytes[5]; 8 | } Data; 9 | 10 | int main(void) { 11 | return printf("%lu, %lu, %lu\n", 12 | alignof(int volatile), 13 | _Alignof(void*[5]), 14 | _Alignof(const Data)); 15 | } 16 | -------------------------------------------------------------------------------- /test/c11/noreturn.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void noreturn forever(void); 4 | 5 | _Noreturn void forever(void) { 6 | int i = 0; 7 | while (1) 8 | i++; 9 | } 10 | 11 | int main(void) { 12 | return 0; 13 | forever(); 14 | } 15 | -------------------------------------------------------------------------------- /test/c11/static-assert.c: -------------------------------------------------------------------------------- 1 | #if defined _Static_assert 2 | # error Should not be defined, but valid to ask for it 3 | #endif 4 | 5 | #include 6 | 7 | /* NOT actually on OpenBSD! (This is a bug) */ 8 | #ifdef __OpenBSD__ 9 | #define static_assert _Static_assert 10 | #endif 11 | 12 | _Static_assert('a' < 'b', "Alphabet error"); 13 | 14 | int foo(char a) { 15 | _Static_assert(sizeof(a) == 1, "Hello"); 16 | return 0; 17 | } 18 | 19 | int main(void) { 20 | return foo(42); 21 | } 22 | 23 | static_assert(1, ""); 24 | -------------------------------------------------------------------------------- /test/c89/address-deref-offset.c: -------------------------------------------------------------------------------- 1 | struct { 2 | int x, y; 3 | } wat[] = {{1, 2}, {3, 4}}; 4 | 5 | int main(void) { 6 | int *p = &wat[1].y; 7 | return *p; 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/anonymous-members.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | struct A { 6 | int a; 7 | union { 8 | int b; 9 | char c; 10 | }; 11 | } foo = {0}; 12 | 13 | union B { 14 | int a; 15 | struct { 16 | int b; 17 | char c; 18 | }; 19 | } bar = {42}; 20 | 21 | struct C { 22 | union { 23 | struct { 24 | int i, j; 25 | }; 26 | struct { 27 | long k, l; 28 | } w; 29 | }; 30 | int m; 31 | } v1; 32 | 33 | int main(void) { 34 | printf("struct A: %lu (%lu, %lu, %lu)\n", 35 | sizeof(foo), 36 | offsetof(struct A, a), 37 | offsetof(struct A, b), 38 | offsetof(struct A, c)); 39 | 40 | printf("union B: %lu (%lu, %lu, %lu)\n", 41 | sizeof(bar), 42 | offsetof(union B, a), 43 | offsetof(union B, b), 44 | offsetof(union B, c)); 45 | 46 | printf("struct C: %lu (i:%lu, j:%lu, w.k:%lu, w.l:%lu, m:%lu)\n", 47 | sizeof(v1), 48 | offsetof(struct C, i), 49 | offsetof(struct C, j), 50 | offsetof(struct C, w.k), 51 | offsetof(struct C, w.l), 52 | offsetof(struct C, m)); 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /test/c89/anonymous-struct.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | struct S1 { 6 | int a; 7 | struct { 8 | struct { 9 | char b; 10 | short c; 11 | } x; 12 | char d; 13 | }; 14 | } foo = {1, 2, 3, 4}; 15 | 16 | int main(void) { 17 | return printf("%d, %d (+ %lu), %d (+ %lu), %d (+ %lu)\n", 18 | foo.a, 19 | foo.x.b, offsetof(struct S1, x.b), 20 | foo.x.c, offsetof(struct S1, x.c), 21 | foo.d, offsetof(struct S1, d)); 22 | } 23 | -------------------------------------------------------------------------------- /test/c89/array-decay.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct point { 4 | int x, y; 5 | }; 6 | 7 | struct point p[3] = {{1, 2}, {3, 4}, {5, 6}}; 8 | 9 | int foo(int n, struct point arr[n]) { 10 | return arr->y; 11 | } 12 | 13 | int main(void) { 14 | int a = p->y; 15 | int b = foo(3, p); 16 | return printf("%d, %d\n", a, b); 17 | } 18 | -------------------------------------------------------------------------------- /test/c89/array-nested-init.c: -------------------------------------------------------------------------------- 1 | int foo[4][3][2] = {{{0}}}; 2 | 3 | int main(void) { 4 | return foo[3][2][1] + sizeof(foo); 5 | } 6 | -------------------------------------------------------------------------------- /test/c89/array-param.c: -------------------------------------------------------------------------------- 1 | int printf(const char *s, ...); 2 | 3 | struct obj { 4 | char val[8]; 5 | int len; 6 | }; 7 | 8 | struct obj func(struct obj in) { 9 | struct obj out = {{1, 2, 3}, 3}; 10 | printf("%d, %d, %d (%d)\n", in.val[0], in.val[1], in.val[7], in.len); 11 | return out; 12 | } 13 | 14 | int main(void) { 15 | struct obj foo = {{5, 7, 32, 1, 4, 1, 1, 4}, 13}; 16 | foo = func(foo); 17 | func(foo); 18 | return sizeof(foo); 19 | } 20 | -------------------------------------------------------------------------------- /test/c89/array-registers.c: -------------------------------------------------------------------------------- 1 | static const char *x86_64_registers[][4] = { 2 | { "al", "ax", "eax", "rax" }, 3 | { "bl", "bx", "ebx", "rbx" }, 4 | { "cl", "cx", "ecx", "rcx" }, 5 | { "dl", "dx", "edx", "rdx" }, 6 | { "bpl", "bp", "ebp", "rbp" }, 7 | { "spl", "sp", "esp", "rsp" }, 8 | { "sil", "si", "esi", "rsi" }, 9 | { "dil", "di", "edi", "rdi" }, 10 | { "r8b", "r8w", "r8d", "r8" }, 11 | { "r9b", "r9w", "r9d", "r9" }, 12 | { "r10b", "r10w", "r10d", "r10" }, 13 | { "r11b", "r11w", "r11d", "r11" }, 14 | { "r12b", "r12w", "r12d", "r12" }, 15 | { "r13b", "r13w", "r13d", "r13" }, 16 | { "r14b", "r14w", "r14d", "r14" }, 17 | { "r15b", "r15w", "r15d", "r15" }, 18 | }; 19 | 20 | #define REG(r, w) \ 21 | x86_64_registers[(int) (r)][(w) == 8 ? 3 : (w) == 4 ? 2 : (w) - 1] 22 | 23 | int puts(const char *s); 24 | 25 | int main(void) { 26 | int r = 0, w = 4; 27 | 28 | puts(REG(r, w)); 29 | return r + w; 30 | } 31 | -------------------------------------------------------------------------------- /test/c89/array-reverse-index.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | char c[2] = {1, 2}; 3 | return 1[c]; 4 | } 5 | -------------------------------------------------------------------------------- /test/c89/array-zero-length.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int foo[], bar[0]; 4 | int foo[0]; 5 | 6 | struct S { 7 | char data[0]; 8 | char x, y, z; 9 | } s1; 10 | 11 | int test(struct S s) { 12 | return printf("{%d, %d, %d}\n", s.data[0], s.data[1], s.data[2]); 13 | } 14 | 15 | int main(void) { 16 | s1.x = 3; 17 | s1.y = 2; 18 | s1.z = 1; 19 | 20 | test(s1); 21 | 22 | return printf("size: %lu, %lu\n", sizeof(foo), sizeof(struct S)); 23 | } 24 | -------------------------------------------------------------------------------- /test/c89/array.c: -------------------------------------------------------------------------------- 1 | extern char bytes[4]; 2 | 3 | char bytes[] = {1, 2, 3, 4}; 4 | 5 | char numbers[4] = "1234"; 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | int foo[2]; 10 | int bar[4][2][1]; 11 | 12 | foo[0] = 1; 13 | bar[2][1][0] = 4; 14 | 15 | return foo[0] + bar[2][1][0]; 16 | } 17 | -------------------------------------------------------------------------------- /test/c89/assign-deref-float.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | float v; 4 | double d; 5 | 6 | int main(void) { 7 | float *p = &v, q = 3.14f; 8 | double *r = &d, s = 2.71; 9 | *p = q; 10 | *r = s; 11 | return printf("%f, %f\n", *p, *r); 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/assignment-type.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | char c = 'a'; 5 | int i = -1; 6 | long l; 7 | l = (c = i); 8 | 9 | printf("%ld\n", l); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/bitfield-basic.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | union A { 4 | int:3; 5 | char b; 6 | } m = {'b'}; 7 | 8 | union { 9 | int f0; 10 | unsigned f1 : 25; 11 | signed f2 : 4; 12 | } f[] = {0x35CEB2D7L}; 13 | 14 | struct fields { 15 | signed int foo:7; 16 | unsigned int bar: (1 + 1); 17 | unsigned int:0; 18 | unsigned int baz:4; 19 | int:0; 20 | }; 21 | 22 | int main(void) { 23 | struct fields test = {0}; 24 | struct fields *ref = &test; 25 | 26 | test.foo = 127; 27 | test.baz = ref->foo; 28 | ref->bar = 3; 29 | ref->foo += 1; 30 | test.bar += 1; 31 | 32 | printf("size: %lu\n", sizeof(test)); 33 | printf("%d, %d, %d\n", test.foo, ref->bar, test.baz); 34 | printf("f: %d, %d, %d\n", f[0].f0, f[0].f1, f[0].f2); 35 | printf("union: {%d} :: %lu\n", m.b, sizeof(union A)); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /test/c89/bitfield-extend.c: -------------------------------------------------------------------------------- 1 | struct fields { 2 | signed int foo:5; 3 | unsigned int bar:1; 4 | }; 5 | 6 | int main(void) { 7 | struct fields test = {0}; 8 | 9 | test.foo--; 10 | test.bar = 1; 11 | 12 | return test.foo - test.bar; 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/bitfield-immediate-assign.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct { 4 | unsigned f1 : 2; 5 | } b; 6 | 7 | int foo(void) { 8 | int a, d = -10; 9 | a = (d < (b.f1 = 2)); 10 | return printf("foo: %u, %d\n", b.f1, a); 11 | } 12 | 13 | int h, i; 14 | unsigned j; 15 | 16 | struct { 17 | signed f0 : 20; 18 | unsigned f1 : 20; 19 | } f; 20 | 21 | int bar(void) { 22 | i = (f.f0 = (h = 0x20CF9BFEL)); 23 | j = (f.f1 = (h = 0x20CF9BFEL)); 24 | return printf("bar: (%d, %d), (%u, %u)\n", f.f0, i, f.f1, j); 25 | } 26 | 27 | int main(void) { 28 | return foo() + bar(); 29 | } 30 | -------------------------------------------------------------------------------- /test/c89/bitfield-immediate-bitwise.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct foo { 4 | long f : 50; 5 | }; 6 | 7 | int main(void) { 8 | struct foo p = {0x235709324614}; 9 | 10 | long a = p.f & 7610294871096; 11 | long b = p.f | 7610294871096; 12 | return printf("%ld, %ld\n", a, b); 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/bitfield-initialize-zero.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct fields { 4 | int a : 16; 5 | int b : 4; 6 | int c : 1; 7 | int d : 3; 8 | }; 9 | 10 | struct fields foo(void) { 11 | struct fields t = {5342, 3, 0, 2}; 12 | return t; 13 | } 14 | 15 | struct fields bar(void) { 16 | struct fields t = {87}; 17 | return t; 18 | } 19 | 20 | int main(void) { 21 | struct fields u = foo(), v = bar(); 22 | 23 | return printf("{%d, %d, %d, %d}, {%d, %d, %d, %d}\n", 24 | u.a, u.b, u.c, u.d, v.a, v.b, v.c, v.d); 25 | } 26 | -------------------------------------------------------------------------------- /test/c89/bitfield-load.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | union { 4 | int f1; 5 | signed f0 : 23; 6 | } foo = {0xE2D5F285L}; 7 | 8 | int f = 0; 9 | 10 | union { 11 | int f0 : 3; 12 | unsigned f1 : 2; 13 | } b = {0x04}; 14 | 15 | int out(int n, unsigned long v) { 16 | return printf("%d: %lu\n", n, v); 17 | } 18 | 19 | int cast(void) { 20 | float f = foo.f0; 21 | double d = foo.f0; 22 | return printf("%f, %f\n", f, d); 23 | } 24 | 25 | int main(void) { 26 | if (b.f1) f += 1; 27 | if (b.f0 > 0) f += 2; 28 | 29 | out(1, foo.f1); 30 | out(2, b.f0); 31 | out(3, b.f1); 32 | 33 | cast(); 34 | 35 | return printf("%d\n", f); 36 | } 37 | -------------------------------------------------------------------------------- /test/c89/bitfield-mask.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct { 4 | signed f6 : 1; 5 | } g = {0}; 6 | int f = 42; 7 | 8 | int foo(void) { 9 | g.f6 ^= 4; 10 | if (g.f6) { 11 | (f)--; 12 | } 13 | } 14 | 15 | int main(void) { 16 | foo(); 17 | return printf("%d, %d\n", g.f6, f); 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/bitfield-pack-next.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct id { 4 | unsigned char hash[10]; 5 | }; 6 | 7 | struct obj { 8 | unsigned int a : 4; 9 | unsigned int b : 4; 10 | struct id oid; 11 | }; 12 | 13 | static void foo(struct obj *o) { 14 | char *arr = (char *) o; 15 | int i; 16 | for (i = 0; i < sizeof(*o); ++i) { 17 | printf("%d ", arr[i]); 18 | } 19 | 20 | printf(" (%lu)\n", sizeof(*o)); 21 | } 22 | 23 | static void test1(void) { 24 | struct obj o = {0x3, 0x4, {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}}; 25 | foo(&o); 26 | } 27 | 28 | struct S { 29 | int f : 17; 30 | char b[5]; 31 | } s1 = {1, '2', '3'}; 32 | 33 | static void test2(void) { 34 | int i; 35 | for (i = 0; i < sizeof(struct S); ++i) { 36 | printf("%d ", ((char *) &s1)[i]); 37 | } 38 | 39 | printf(" (%lu)\n", sizeof(struct S)); 40 | } 41 | 42 | int main(void) { 43 | test1(); 44 | test2(); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /test/c89/bitfield-packing.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct fields { 4 | int : 31; 5 | signed int a : 7; 6 | int : 3; 7 | int b : 2; 8 | int : 26; 9 | int : 31; 10 | unsigned int c : (1 + 7); 11 | unsigned int : 0; 12 | unsigned int d : 4; 13 | } f = {-1, 1, 0x56, 3}; 14 | 15 | int print_values(int n) { 16 | return printf("%d: {a = %d, b = %d, c = %d, d = %d}\n", n, 17 | f.a, f.b, f.c, f.d); 18 | } 19 | 20 | int main(void) { 21 | int *ref = (int *) &f; 22 | 23 | print_values(0); 24 | 25 | ref[0] = 0x12345678; 26 | ref[1] = 0xABCDEF01; 27 | ref[2] = 0x98172534; 28 | ref[3] = 0x62738452; 29 | ref[4] = 0x01923475; 30 | ref[5] = 0x49130626; 31 | 32 | print_values(1); 33 | 34 | return sizeof(struct fields); 35 | } 36 | -------------------------------------------------------------------------------- /test/c89/bitfield-reset-align.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct S0 { 4 | unsigned short f0; 5 | float f1; 6 | signed : 0; 7 | unsigned int f2; 8 | short f3; 9 | char f4; 10 | unsigned short f5; 11 | } foo = {1}; 12 | 13 | int print(struct S0 s) { 14 | return printf("(%d, %f, %u, %d, %d, %d)\n", 15 | s.f0, s.f1, s.f2, s.f3, s.f4, s.f5); 16 | } 17 | 18 | int main(void) { 19 | struct S0 bar = {1, 2.0f}; 20 | return print(foo) 21 | + print(bar) 22 | + printf("%lu\n", sizeof(struct S0)); 23 | } 24 | -------------------------------------------------------------------------------- /test/c89/bitfield-trailing-zero.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct S1 { 4 | char c; 5 | int : 0; 6 | int : 0; 7 | int : 0; 8 | }; 9 | 10 | struct S2 { 11 | long l; 12 | const signed : 0; 13 | }; 14 | 15 | union U1 { 16 | int : 0; 17 | int : 0; 18 | char c; 19 | int : 0; 20 | int : 0; 21 | int : 0; 22 | int : 0; 23 | }; 24 | 25 | struct S2 foo(int i) { 26 | struct S2 s = {0}; 27 | s.l = i; 28 | return s; 29 | } 30 | 31 | int main(void) { 32 | struct S2 u = foo(42); 33 | return printf("%ld, %lu, %lu, %lu", 34 | u.l, 35 | sizeof(struct S1), 36 | sizeof(struct S2), 37 | sizeof(union U1)); 38 | } 39 | -------------------------------------------------------------------------------- /test/c89/bitfield-types.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct A { 4 | long a : 40; 5 | } a1 = {187134098732}; 6 | 7 | static int test_a(void) { 8 | long l = a1.a; 9 | return printf("%ld\n", l); 10 | } 11 | 12 | struct B { 13 | struct A a; 14 | short b : 4; 15 | } b1 = {3, -2}; 16 | 17 | static int test_b(void) { 18 | int foo = b1.b; 19 | return printf("%ld, %d\n", (long) b1.a.a, foo); 20 | } 21 | 22 | struct C { 23 | short a : 3; 24 | char b : 5; 25 | char c : 3; 26 | } c1 = {3}; 27 | 28 | static int test_c(void) { 29 | return printf("{%d, %d, %d}\n", c1.a, c1.b, c1.c); 30 | } 31 | 32 | struct D { 33 | unsigned long a : 32; 34 | unsigned long : 4; 35 | unsigned long b : 20; 36 | } d1 = {-1, -1}, 37 | d2 = {0, 1241}, 38 | d3 = {0}; 39 | 40 | static int test_d(struct D d) { 41 | return printf("{%u, %u}\n", d.a, d.b); 42 | } 43 | 44 | int main(void) { 45 | printf("sizeof(struct A) = %lu\n", sizeof(struct A)); 46 | printf("sizeof(struct B) = %lu\n", sizeof(struct B)); 47 | printf("sizeof(struct C) = %lu\n", sizeof(struct C)); 48 | return test_a() 49 | + test_b() 50 | + test_c() 51 | + test_d(d1) + test_d(d2) + test_d(d3); 52 | }; 53 | -------------------------------------------------------------------------------- /test/c89/bitfield-unsigned-promote.c: -------------------------------------------------------------------------------- 1 | static struct { 2 | unsigned f1 : 23; 3 | } f; 4 | 5 | int main() { 6 | int h = (f.f1 > -1); 7 | return h; 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/bitfield.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct { 4 | unsigned f2 : 13; 5 | signed f3 : 19; 6 | int f5; 7 | signed f6 : 17; 8 | signed f7 : 7; 9 | } f = {30, 374, 1UL, -269, -2}; 10 | 11 | int main(void) { 12 | return printf("{%u, %d, %d, %d, %d} size=%lu\n", 13 | f.f2, f.f3, f.f5, f.f6, f.f7, sizeof(f)); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/bitwise-complement.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i = 23; 3 | unsigned char c = 3; 4 | 5 | return ~i + ~c; 6 | } 7 | -------------------------------------------------------------------------------- /test/c89/bitwise-constant.c: -------------------------------------------------------------------------------- 1 | static int 2 | a = 3 << 3, 3 | b = 211 >> 2, 4 | c = 5 | 0, 5 | d = 7 & 3, 6 | e = ~5, 7 | f = !0; 8 | 9 | int main(void) { 10 | return a + b + c + d + e + f; 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/bitwise-expression.c: -------------------------------------------------------------------------------- 1 | int g = 0xEB0647DCL; 2 | 3 | int main(void) { 4 | int i = (0xEB0647DCL < (g | 0x4B54C5F6B4AB19F8LL)); 5 | return i; 6 | } 7 | -------------------------------------------------------------------------------- /test/c89/bitwise-sign-extend.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | char f = -1L; 4 | long g = 0x9D3BBD11537C3E80L; 5 | 6 | int main(void) { 7 | return printf("%ld, %ld, %ld\n", 8 | (g & f), 9 | (g ^ f), 10 | (g | f)); 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/byte-load.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | unsigned char *b = "b2"; 3 | signed char *w = "w3"; 4 | return b[1] + w[1]; 5 | } 6 | -------------------------------------------------------------------------------- /test/c89/cast-float-union.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | union { 4 | long i; 5 | float f; 6 | } wat; 7 | 8 | int main(void) { 9 | wat.i = 0x7FFFEFFEEF; 10 | wat.f = (float) wat.i; 11 | return printf("%f\n", wat.f); 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/cast-float.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | float f1 = 3.14f, f2; 3 | 4 | f2 = (double) f1 - 2; 5 | 6 | return f2; 7 | } 8 | -------------------------------------------------------------------------------- /test/c89/cast-function-args.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int foo(unsigned long a, unsigned char b, float f, double d) { 4 | return printf("%lu, %u, %f, %f\n", a, b, f, d); 5 | } 6 | 7 | int main(void) { 8 | int i = -3; 9 | float f = 3.14f; 10 | double d = 2.71; 11 | return foo(i, i, d, f); 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/cast-function.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int foo(void *ptr) { 4 | return printf("foo\n"); 5 | } 6 | 7 | int main(void) { 8 | void (*bar)(void *) = (void (*)(void *)) foo; 9 | 10 | bar(0); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/cast-immediate-truncate.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | long g = 0xE52DL; 4 | 5 | int main(void) { 6 | int k = (-(unsigned)(2UL)) % g; 7 | unsigned j = (unsigned char) (-2ul); 8 | int i = (char) (-2458658ul); 9 | return printf("%d, %u, %d\n", k, j, i); 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/cast.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | char arr[] = {1, 2, 3, 4}; 3 | char *ptr = (char *) arr; 4 | 5 | return (int) *ptr; 6 | } 7 | -------------------------------------------------------------------------------- /test/c89/comma-side-effects.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int f; 4 | int *g = &f, *h = &f; 5 | char i; 6 | 7 | void fn3(void) { 8 | *g |= 0x1B0231B7L; 9 | } 10 | 11 | int main(void) { 12 | *h = 4L; 13 | (fn3(), i); 14 | 15 | return printf("%d, %d\n", *g, *h); 16 | } 17 | -------------------------------------------------------------------------------- /test/c89/comment.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | /* Hello! 4 | // */ 5 | 6 | char *str = "a\"/*b\"\\\\"; 7 | char c = '"', d = '\''; 8 | 9 | /*\ 10 | foo(); 11 | */ 12 | /\ 13 | * bar(); *\ 14 | / 15 | 16 | int foo/* */(int/**/a, int b) { 17 | int f = a/*\*//b; 18 | int g = a/ /**/b; 19 | return printf("%d, %d, %s, %s, %d, %d\n", f, g, "w ??=*/ /*t?\ 20 | ??", str, c, d); 21 | } 22 | 23 | int main(void) { 24 | return /*//*/ foo(__LINE__ * 2, 2);; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/c89/compare.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int arr[] = {1, 2, 3}; 4 | 5 | void *p = &arr[0]; 6 | void *q = &arr[1]; 7 | const int *r = &arr[2]; 8 | 9 | int main(void) { 10 | return printf("%d, %d, %d, %d\n", p < q, p > q, p == r, r != q); 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/compound-assignment-basic.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1, b = 2, c = 3, d = 4, e = 5; 3 | int f = 0x03, g = 0x03, h = 0x07; 4 | 5 | a += b; 6 | c -= c += d; 7 | e *= 2; 8 | e /= 5; 9 | d %= a - 1; 10 | f &= 0x11; 11 | g |= 0x11; 12 | h ^= 0x11; 13 | 14 | return a + b + c + d + e + f + g + h; 15 | } 16 | -------------------------------------------------------------------------------- /test/c89/conditional-basic.c: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | int a = 1; 4 | int b = 2; 5 | 6 | int c = (a + 1) ? (b - 2) ? b-- : b++ : 42; 7 | int d = 0 ? 1 : 2; 8 | return c + a + b + d; 9 | } 10 | -------------------------------------------------------------------------------- /test/c89/conditional-constant.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a, b = 42; 3 | a = (1) ? (b+1) & ~1 : b; 4 | b = (0) ? (b+1) & ~1 : b; 5 | return a + b; 6 | } 7 | -------------------------------------------------------------------------------- /test/c89/conditional-void.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | void speak(const char *str) { 4 | puts(str); 5 | } 6 | 7 | int main(void) { 8 | int i = 42; 9 | (i) ? speak("Hello") : speak("World"); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/conditional.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | const void *c_vp; 4 | void *vp; 5 | const int *c_ip; 6 | volatile int *v_ip; 7 | int *ip; 8 | const char *c_cp; 9 | 10 | static int a = 1; 11 | 12 | static int foo(void) { 13 | const void *t1 = (a) ? c_vp : c_ip; 14 | volatile int *t2 = (a) ? v_ip : 0; 15 | const volatile int *t3 = (a) ? c_ip : v_ip; 16 | const void *t4 = (a) ? vp : c_cp; 17 | const int *t5 = (a) ? ip : c_ip; 18 | void *t6 = (a) ? vp : ip; 19 | 20 | return printf("%lu, %lu, %lu\n", sizeof(*t2), sizeof(*t3), sizeof(*t5)); 21 | } 22 | 23 | int main(void) { 24 | int t1 = ((1 ? -1 : 1u) < 0), 25 | t2 = ((0 ? 0u : -1) < 0); 26 | 27 | return foo() + printf("%d, %d\n", t1, t2); 28 | } 29 | -------------------------------------------------------------------------------- /test/c89/constant-address-index.c: -------------------------------------------------------------------------------- 1 | static void 2 | *p = (void*) &((char*)50)[2], 3 | *q = (void*) &((char*)50)[-2]; 4 | 5 | int main(void) { 6 | unsigned long v = (unsigned long) p + (unsigned long) q; 7 | return v; 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/constant-expression.c: -------------------------------------------------------------------------------- 1 | #define isbit(b) ((b) < 8 ? ((1 << (b)) << 8) : ((1 << (b)) >> 8)) 2 | 3 | static int a = (2 >= 5); 4 | 5 | enum wat { 6 | CAT = isbit(1) 7 | }; 8 | 9 | int main(void) { 10 | return a + CAT; 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/constant-integer-type.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int main(void) { 4 | return printf("%lu, %ld, %ld, %u, %ld\n", 5 | 0xF2C889DD98AE1F63, 6 | 0xFFD2086BDu, 7 | 0xFFD2086BD, 8 | 0xFFFFFFFF, 9 | 4294967295); 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/convert-assign-immediate.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int main(void) { 4 | int x; 5 | x = 2.2f; 6 | return printf("%d\n", x); 7 | } 8 | -------------------------------------------------------------------------------- /test/c89/convert-float-double.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | float f = 3.14; 3 | double d = 2.71f; 4 | 5 | d = f; 6 | 7 | return d; 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/convert-float-int.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int main(void) { 4 | float f1 = 5312.4f, f2 = -12312.14f; 5 | double d1 = 431235311.92340; 6 | 7 | char c = f2; 8 | unsigned char u = f2; 9 | short s = d1; 10 | int i = f1; 11 | long l = d1; 12 | 13 | return printf("c = %d, u = %u, s = %d, i = %d, l = %ld\n", c, u, s, i, l); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/convert-float-unsigned.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | #define LONG_SIGN_BIT (1ul << 63) 4 | #define ULONG_MAX (0xFFFFFFFFFFFFFFFFul) 5 | #define LONG_MAX (0x7FFFFFFFFFFFFFFFl) 6 | 7 | int float_to_ushort(void) { 8 | float g = 0x92F9E84EL; 9 | unsigned short s = g; 10 | return printf("(float) unsigned short: %d\n", s); 11 | } 12 | 13 | int float_to_uint(void) { 14 | float f1 = 1.5678e30f, f2 = LONG_SIGN_BIT, f3 = ULONG_MAX; 15 | unsigned int a = f1, b = f2, c = f3; 16 | return printf("(float) unsigned int: %u, %u, %u\n", a, b, c); 17 | } 18 | 19 | int float_to_ulong(void) { 20 | float f1 = 1.5678e30f, f2 = LONG_SIGN_BIT, f3 = ULONG_MAX, f4 = LONG_MAX; 21 | unsigned long a = f1, b = f2, c = f3, d = f4; 22 | return printf("(float) unsigned long: %lu, %lu, %lu, %lu\n", a, b, c, d); 23 | } 24 | 25 | int double_to_uint(void) { 26 | double d1 = 1.67890e20, d2 = LONG_SIGN_BIT, d3 = ULONG_MAX; 27 | unsigned int a = d1, b = d2, c = d3; 28 | return printf("(double) unsigned int %u, %u, %u\n", a, b, c); 29 | } 30 | 31 | int double_to_ulong(void) { 32 | double d1 = 1.67890e20, d2 = LONG_SIGN_BIT, d3 = ULONG_MAX; 33 | unsigned long a = d1, b = d2, c = d3; 34 | return printf("(double) unsigned long: %lu, %lu, %lu\n", a, b, c); 35 | } 36 | 37 | int main(void) { 38 | return float_to_ushort() 39 | + float_to_uint() 40 | + float_to_ulong() 41 | + double_to_uint() 42 | + double_to_ulong(); 43 | } 44 | -------------------------------------------------------------------------------- /test/c89/convert-int-float.c: -------------------------------------------------------------------------------- 1 | int cvtfloat(void) { 2 | float f; 3 | unsigned char c = 0xff; 4 | f = c; 5 | return f; 6 | } 7 | 8 | int cvtdouble(void) { 9 | double d; 10 | d = 32; 11 | return d; 12 | } 13 | 14 | int main(void) { 15 | return cvtfloat() - cvtdouble(); 16 | } 17 | -------------------------------------------------------------------------------- /test/c89/convert-unsigned-float.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | unsigned char a = 0xF1u, b = 0x89; 4 | unsigned c = 0xC2E0CF57u, d = 0x678; 5 | unsigned long e = 0xC2E0CF57C2E0CF57UL, f = 0x456789L; 6 | 7 | int main(void) { 8 | float f1 = a, f2 = b, f3 = c, f4 = d, f5 = e, f6 = f; 9 | double d1 = a, d2 = b, d3 = c, d4 = d, d5 = e, d6 = f; 10 | 11 | return printf("(%f, %f, %f, %f, %f, %f), (%f, %f, %f, %f, %f, %f)\n", 12 | f1, f2, f3, f4, f5, f6, d1, d2, d3, d4, d5, d6); 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/copy-struct.c: -------------------------------------------------------------------------------- 1 | struct point { 2 | long x, y; 3 | }; 4 | 5 | struct point p; 6 | 7 | int main() { 8 | struct point q = {1, 2}; 9 | 10 | p = q; 11 | return p.y; 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/declaration-default-int.c: -------------------------------------------------------------------------------- 1 | static baz = 42; 2 | 3 | bar(a, b) { 4 | return a + b + baz; 5 | } 6 | 7 | static foo(a, b) 8 | long b; 9 | { 10 | auto c = a + b; 11 | return bar(c, a * a); 12 | } 13 | 14 | main() { 15 | register m; 16 | m = foo(2, 3); 17 | return m; 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/declarator-abstract.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | typedef int x; 4 | 5 | void f1(int(x)); /* void f(int (*)(int)) */ 6 | int f2(int(y)); /* int f(int) */ 7 | void f3(int((*))); /* void f(int *) */ 8 | void f4(int((*x))); /* void f(int *) */ 9 | void f5(int((x))); /* void f(int (*)(int)) */ 10 | void f6(int(int)); /* void f(int (*)(int)) */ 11 | 12 | int id(int a) { 13 | return a; 14 | } 15 | 16 | int main(void) { 17 | int a = 42; 18 | void (*c1)(int(x)) = f6; 19 | int (*c2)(int(y)) = id; 20 | void (*c3)(int((*))) = f4; 21 | void (*c4)(int((*x))) = f3; 22 | void (*c5)(int((x))) = f1; 23 | void (*c6)(int(int)) = f5; 24 | 25 | c1(id); 26 | c3(&a); 27 | c4(&a); 28 | c5(c2); 29 | c6(id); 30 | 31 | return 0; 32 | } 33 | 34 | void f1(int (*f)(int)) { 35 | printf("f1: %d\n", f(1)); 36 | } 37 | 38 | void f3(int *a) { 39 | printf("f3: %d\n", *a); 40 | } 41 | 42 | void f4(int *a) { 43 | printf("f4: %d\n", *a); 44 | } 45 | 46 | void f5(int (*f)(int)) { 47 | printf("f5: %d\n", f(5)); 48 | } 49 | 50 | void f6(int (*f)(int)) { 51 | printf("f6: %d\n", f(6)); 52 | } 53 | -------------------------------------------------------------------------------- /test/c89/declarator-complex.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | static char *str; 4 | 5 | static void func(void) { 6 | puts(str); 7 | } 8 | 9 | static void (*getfunc(char *s))(void) { 10 | str = s; 11 | return func; 12 | } 13 | 14 | int arr[] = {1, 2}; 15 | 16 | int bar(void) { 17 | int *(a[2]); 18 | 19 | a[0] = &arr[0]; 20 | a[1] = &arr[1]; 21 | return *a[0] + *a[1]; 22 | } 23 | 24 | int main(void) { 25 | void (*foo)(void) = getfunc("Hello World!"); 26 | foo(); 27 | return bar(); 28 | } 29 | -------------------------------------------------------------------------------- /test/c89/declarator-parens.c: -------------------------------------------------------------------------------- 1 | static int ((foo))(int wat) { 2 | return wat; 3 | } 4 | 5 | int main(void) { 6 | return foo(42); 7 | } 8 | -------------------------------------------------------------------------------- /test/c89/declare-auto-func.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 42, foo(int a), b = 2; 3 | return foo(a + b); 4 | } 5 | 6 | int bar(void) { 7 | int foo(int b); 8 | return foo(4); 9 | } 10 | 11 | int foo(int n) { 12 | int baz(int); 13 | return baz(n); 14 | } 15 | 16 | int baz(int a) { 17 | return a + a; 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/deref-address-offset.c: -------------------------------------------------------------------------------- 1 | struct { 2 | int x, y; 3 | } wat = {1, 2}; 4 | 5 | int main(void) { 6 | int p = *(&wat.y); 7 | return p; 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/deref-array.c: -------------------------------------------------------------------------------- 1 | char foo[] = "Foo"; 2 | char *bar = "Bar"; 3 | 4 | int main() { 5 | char c = *foo; 6 | char d = *bar; 7 | 8 | return c + d; 9 | } 10 | -------------------------------------------------------------------------------- /test/c89/deref-compare-float.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int g; 4 | int *i = &g; 5 | float j; 6 | 7 | int main(void) { 8 | (*i) = 0xCFBCE008L; 9 | j = (0x0p1 > (*i)); 10 | return printf("%d, %f\n", *i, j); 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/deref-deep.c: -------------------------------------------------------------------------------- 1 | struct typetree { 2 | int type; 3 | struct typetree *next; 4 | }; 5 | 6 | struct var { 7 | struct typetree *type; 8 | }; 9 | 10 | int main() { 11 | struct typetree p = {1}; 12 | struct typetree q = {3}; 13 | struct var root; 14 | 15 | p.next = &q; 16 | root.type = &p; 17 | 18 | return root.type->next->type; 19 | } 20 | -------------------------------------------------------------------------------- /test/c89/deref-store.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | char *name; 4 | 5 | int main(void) { 6 | char text[] = "ab"; 7 | 8 | printf("%s\n", text); 9 | name = text; 10 | 11 | *name = '4'; 12 | printf("%s\n", name); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/deref.c: -------------------------------------------------------------------------------- 1 | struct point { 2 | int x, y; 3 | }; 4 | 5 | struct object { 6 | int ival; 7 | char cval; 8 | struct point *pt; 9 | }; 10 | 11 | int main() { 12 | struct point pt = {4, 5}; 13 | struct object obj = {1, 'a'}; 14 | 15 | obj.pt = &pt; 16 | obj.pt->x = 3; 17 | obj.pt->y = 4; 18 | 19 | return pt.x + pt.y; 20 | } 21 | -------------------------------------------------------------------------------- /test/c89/dereference-extern.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | char *text; 3 | }; 4 | 5 | struct s *var; 6 | 7 | int main() { 8 | struct s foo = {"Hello"}; 9 | var = &foo; 10 | return var->text[0]; 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/directive-number.c: -------------------------------------------------------------------------------- 1 | #if 'A' == '\301' 2 | #error Wrong 3 | #endif 4 | 5 | int main(void) { 6 | return '\301'; 7 | } 8 | -------------------------------------------------------------------------------- /test/c89/do-continue.c: -------------------------------------------------------------------------------- 1 | int printf(const char *s, ...); 2 | 3 | int main(void) { 4 | int i = 10; 5 | 6 | do { 7 | if (i % 3 == 0) 8 | continue; 9 | if (i == 2) 10 | break; 11 | printf("%d\n", i); 12 | } while (i--); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/do-while.c: -------------------------------------------------------------------------------- 1 | static int foo(int n) { 2 | int i = 0; 3 | 4 | if (n > 0) 5 | do { 6 | i++; 7 | } while (i < n); 8 | else 9 | i = 42; 10 | return i; 11 | } 12 | 13 | int main(void) { 14 | return foo(0) + foo(1) + foo(13); 15 | } 16 | -------------------------------------------------------------------------------- /test/c89/duffs-device.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | /* "Duff's Device", adapted from 4 | * https://groups.google.com/forum/#!msg/net.lang.c/3KFq-67DzdQ/TKl64DiBAGYJ 5 | */ 6 | void send(short *to, short *from, int count) { 7 | int n = (count + 7)/8; 8 | switch (count % 8) { 9 | case 0: do { *to += *from++; 10 | case 7: *to += *from++; 11 | case 6: *to += *from++; 12 | case 5: *to += *from++; 13 | case 4: *to += *from++; 14 | case 3: *to += *from++; 15 | case 2: *to += *from++; 16 | case 1: *to += *from++; 17 | } while (--n > 0); 18 | } 19 | } 20 | 21 | static int result(short *to, short *from, int count) { 22 | int i; 23 | for (i = 0; i < count; ++i) { 24 | printf("(%d, %d)", to[i], from[i]); 25 | if (i < count - 1) { 26 | printf(", "); 27 | } 28 | } 29 | printf("\n"); 30 | return 0; 31 | } 32 | 33 | static short p[16] = {1, 2, 3, 4, 5, 6, 7, 8, 3, 8, 5, 1, 0, 0, 9, 2}; 34 | static short q[16] = {4, 2, 7, 2, 1, 2, 5, 7, 2, 6, 8, 0, 4, 2, 6, 3}; 35 | 36 | int main(void) { 37 | send(p + 2, q, 16); 38 | send(p + 5, q, 13); 39 | send(p + 7, p, 5); 40 | 41 | return result(p, q, 16); 42 | } 43 | -------------------------------------------------------------------------------- /test/c89/enum.c: -------------------------------------------------------------------------------- 1 | enum token { 2 | FOO, 3 | BAR = 23, 4 | BAZ = BAR + 4 5 | }; 6 | 7 | int foo(enum token tok) 8 | { 9 | return tok; 10 | } 11 | 12 | static int tokens[] = {FOO, BAR, BAZ}; 13 | 14 | int main() { 15 | enum BOOL { TRUE, FALSE } truth = FALSE; 16 | enum token { FOO = 1 } shadow = 0; 17 | enum token t = FOO; 18 | int a; 19 | 20 | t = 3 + truth; 21 | a = t; 22 | 23 | return BAZ - a + tokens[1]; 24 | } 25 | -------------------------------------------------------------------------------- /test/c89/exit.c: -------------------------------------------------------------------------------- 1 | void exit(int status); 2 | 3 | int main() { 4 | int i = 2; 5 | switch (i) { 6 | case 1: 7 | return 1; 8 | case 2: 9 | return 2; 10 | default: 11 | exit(3); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/expression-div-mod.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 3, b = 2; 3 | long c = 6; 4 | 5 | int d = a / b; 6 | int e = a % b; 7 | int f = a / c; 8 | 9 | return d + e + f; 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/expression.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int main(void) { 4 | int a = -1; 5 | int b = 2; 6 | 7 | int c = a == b == 2; 8 | int d = c < 2 > c >= 1; 9 | int e = d && c || 1; 10 | int f = (1, 2); 11 | 12 | int g[2]; 13 | 14 | c = !c + +a != -7; 15 | (g)[b - 1] = 1; 16 | 17 | printf("%lu\n", sizeof(+(char) a)); 18 | 19 | return - -c + d + e + f; 20 | } 21 | -------------------------------------------------------------------------------- /test/c89/fact.c: -------------------------------------------------------------------------------- 1 | 2 | int fact(int n) 3 | { 4 | if (n) 5 | return n * fact(n - 1); 6 | return 1; 7 | } 8 | 9 | int main() 10 | { 11 | return fact(5); 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/field-chain-assign.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct a { 4 | signed b : 3; 5 | }; 6 | 7 | int c = 3680314112; 8 | int *d = &c; 9 | 10 | int main(void) { 11 | struct a e; 12 | *d = e.b = c; 13 | printf("{%d}\n", c); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/c89/float-arithmetic.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int main(void) { 4 | float f1 = 3.14f, f2, f3; 5 | double d1 = 2.71, d2, d3; 6 | 7 | f2 = f1 - (d1 - 4.2f); 8 | d2 = f2 + f1 + 3.63123; 9 | f3 = f2 / (d1 / 0.44f); 10 | d3 = d2 * f1 * 3.1; 11 | 12 | printf("f1 = %f, f2 = %f, f3 = %f\n", f1, f2, f3); 13 | printf("d1 = %f, d2 = %f, d3 = %f\n", d1, d2, d3); 14 | 15 | return f1 * d1; 16 | } 17 | -------------------------------------------------------------------------------- /test/c89/float-branch.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int main(void) { 4 | int i = 0; 5 | double d = 0.0; 6 | float f = 1.2f; 7 | 8 | if (d) { 9 | i = 42; 10 | } else if (f) { 11 | i = 32; 12 | } 13 | 14 | return i; 15 | } 16 | -------------------------------------------------------------------------------- /test/c89/float-compare-equal.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int g = -4L, i = 0; 4 | float *f; 5 | 6 | void foo(int *p1) { 7 | f = (void *) p1; 8 | *f = (i == *f); 9 | } 10 | 11 | int main(void) { 12 | foo(&g); 13 | return printf("%d\n", g); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/float-compare-nan.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | typedef unsigned long long u64; 6 | 7 | int nan_ne_assign(double x) { 8 | volatile double y = x; 9 | volatile double z = y; 10 | int rc; 11 | rc = (y != z); 12 | return rc; 13 | } 14 | 15 | int nan_eq_assign(double x) { 16 | volatile double y = x; 17 | volatile double z = y; 18 | int rc; 19 | rc = (y == z); 20 | return rc; 21 | } 22 | 23 | int nan_ne_jump(double x) { 24 | volatile double y = x; 25 | volatile double z = y; 26 | 27 | if (y != z) { 28 | return 1; 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | int nan_eq_jump(double x) { 35 | volatile double y = x; 36 | volatile double z = y; 37 | 38 | if (y == z) { 39 | return 1; 40 | } 41 | 42 | return 0; 43 | } 44 | 45 | int nan_ne_return(double x) { 46 | volatile double y = x; 47 | volatile double z = y; 48 | 49 | return y != z; 50 | } 51 | 52 | int nan_eq_return(double x) { 53 | volatile double y = x; 54 | volatile double z = y; 55 | 56 | return y == z; 57 | } 58 | 59 | int main(void) { 60 | u64 x = (((u64)1)<<63)-1; 61 | double y; 62 | 63 | memcpy(&y, &x, 8); 64 | return printf("%d, %d, %d, %d, %d, %d\n", 65 | nan_ne_assign(y), 66 | nan_eq_assign(y), 67 | nan_ne_jump(y), 68 | nan_eq_jump(y), 69 | nan_ne_return(y), 70 | nan_eq_return(y)); 71 | } 72 | -------------------------------------------------------------------------------- /test/c89/float-compare.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | float f = 5.67f, g = 5.97f; 5 | double d = 3.87, p = 12.9; 6 | 7 | do { 8 | assert(f < g); 9 | assert(p > f); 10 | assert(f == f); 11 | assert(p >= d); 12 | } while (p < f); 13 | 14 | return p >= d; 15 | } 16 | -------------------------------------------------------------------------------- /test/c89/float-function.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | float foo(double n) { 4 | return n * 2.0; 5 | } 6 | 7 | double bar(float n) { 8 | return n + foo((double) n); 9 | } 10 | 11 | int main(void) { 12 | return printf("r = %f\n", bar(3.14f)); 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/float-load-deref.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int main(void) { 4 | int foo = 4; 5 | int *bar = &foo; 6 | float f = *bar; 7 | 8 | return printf("%f\n", f); 9 | } 10 | -------------------------------------------------------------------------------- /test/c89/for-empty-expr.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int n = 10; 4 | 5 | int main(void) { 6 | int i = 1; 7 | for (; n;) { 8 | if (n == 7) { 9 | n--; 10 | continue; 11 | } 12 | if (n == 1) 13 | break; 14 | i += n--; 15 | } 16 | 17 | return printf("%d, %d\n", i, n); 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/for-side-effects.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int foo(int i) { 4 | return printf("%d\n", i); 5 | } 6 | 7 | int main(void) { 8 | int i; 9 | 10 | for (i = 0, foo(1); i < 5; i++, foo(3)) 11 | ; 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/for.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char *argv[]) 2 | { 3 | int i, j; 4 | for (i = 1; i & 7; i = i + 1) { 5 | if (i & 2) 6 | continue; 7 | for (j = 1; j & 3; j = j + 1) { 8 | if ((j + i) ^ 3) 9 | break; 10 | } 11 | } 12 | return i + j; 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/function-char-args.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(unsigned char c, char s) 4 | { 5 | return c + s + 1; 6 | } 7 | 8 | int main() { 9 | char c = -1; 10 | short s = -2; 11 | 12 | printf("%d\n", foo(c, s)); 13 | return 1; 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/function-implicit-declare.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return bar(); 3 | } 4 | 5 | extern int bar(void); 6 | 7 | int bar(void) { 8 | return 42; 9 | } 10 | -------------------------------------------------------------------------------- /test/c89/function-incomplete.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int foo(); 4 | 5 | int bar(void) { 6 | return foo() + 1; 7 | } 8 | 9 | int foo(char *n) { 10 | return 42; 11 | } 12 | 13 | int (*baz)() = &foo; 14 | 15 | int main(void) { 16 | int a = bar(); 17 | return printf("%d\n", a); 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/function-pointer-call.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | int (*foo)(const char *); 3 | 4 | void danger(void) { 5 | ((void (*)(void))0xdeadbeef)(); 6 | } 7 | 8 | int main(void) { 9 | int (*bar)(const char *); 10 | foo = puts; 11 | bar = puts; 12 | foo("Hello"); 13 | bar("How are you?"); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/c89/function-pointer.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | int (*g1)(const char *) = puts; 4 | int (*g2)(const char *) = &puts; 5 | int (*g3)(const char *) = *puts; 6 | 7 | static void foo(void) { 8 | puts("Foo to you too!"); 9 | } 10 | 11 | int main(void) { 12 | void (*p1_foo)() = foo; 13 | void (*p2_foo)() = *foo; 14 | void (*p3_foo)() = &foo; 15 | void (*p4_foo)() = *&foo; 16 | void (*p5_foo)() = &*foo; 17 | void (*p6_foo)() = **foo; 18 | void (*p7_foo)() = **********************foo; 19 | 20 | (*p1_foo)(); 21 | (*p2_foo)(); 22 | (*p3_foo)(); 23 | (*p4_foo)(); 24 | (*p5_foo)(); 25 | (*p6_foo)(); 26 | (*p7_foo)(); 27 | 28 | g1("1"); 29 | g2("2"); 30 | g3("3"); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /test/c89/function.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | int noop(void); 4 | 5 | static int foo(char *list[5]) { 6 | puts(list[0]); 7 | puts(list[1]); 8 | return sizeof(list[6]); 9 | } 10 | 11 | int prints(int n, ...) { 12 | return n; 13 | } 14 | 15 | static int foo(char *list[]); 16 | 17 | char s1[] = "Hello"; 18 | char *s2 = "World"; 19 | 20 | int main() { 21 | int size = 0; 22 | char *words[2]; 23 | words[0] = s1; 24 | words[1] = s2; 25 | 26 | size = foo(words); 27 | size = size + sizeof(words); 28 | size = size + prints(2, "hei", "hoi"); 29 | 30 | return size; 31 | } 32 | -------------------------------------------------------------------------------- /test/c89/goto.c: -------------------------------------------------------------------------------- 1 | void abort(void); 2 | 3 | int foo(int n) { 4 | int i; 5 | 6 | for (i = 0; i < 5; ++i) { 7 | if (i == n) 8 | goto error; 9 | } 10 | 11 | if (i == 1) 12 | quit: 13 | error: 14 | abort(); 15 | 16 | while (i == 0) 17 | regret: abort(); 18 | 19 | return 0; 20 | } 21 | 22 | int main(void) { 23 | int i = 0; 24 | 25 | start: 26 | while (i < 100) { 27 | if (i == 42) goto end; 28 | i++; 29 | goto start; 30 | i++; 31 | } 32 | 33 | end: 34 | return i + foo(i); 35 | } 36 | -------------------------------------------------------------------------------- /test/c89/header.h: -------------------------------------------------------------------------------- 1 | #ifndef HEADER_H 2 | #define HEADER_H 3 | 4 | #ifndef FOO 5 | #define FOO 1 6 | #endif 7 | 8 | #undef FOO 9 | 10 | #if !defined(FOO) && !(2 * FOO + 1 != 1) 11 | #define FOO 0 12 | #endif 13 | 14 | #define _BAR 500 15 | 16 | #if _BAR < 500 17 | # define _BAZ 2 18 | #elif _BAR < 600 19 | # define _BAZ 3 20 | #elif _BAR < 700 21 | # define _BAZ 4 22 | #else 23 | # define _BAZ 5 24 | #endif 25 | 26 | #if _BAZ != 3 27 | # error Wrong! 28 | #endif 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /test/c89/hello.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | char hello[] = "Hello World!"; 4 | 5 | char *how = "How are you?"; 6 | 7 | long demo, ret = 42; 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | puts(hello); 12 | puts(how); 13 | return ret; 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/identifier.c: -------------------------------------------------------------------------------- 1 | static int a; 2 | extern int c; 3 | 4 | int foo() { 5 | static int b; 6 | b = 1; 7 | return b; 8 | } 9 | 10 | int c; 11 | 12 | int main(void) { 13 | extern int a; 14 | static int b; 15 | { 16 | static int a = 2; 17 | b = a; 18 | } 19 | c = 1; 20 | return a + b + c + foo(); 21 | } 22 | 23 | 24 | int c; 25 | 26 | static int a = 3; 27 | 28 | extern int u; 29 | int u; 30 | 31 | int v; 32 | extern int v; 33 | 34 | static int w(void); 35 | int w(void); 36 | 37 | static int x(void); 38 | extern int x(void); 39 | -------------------------------------------------------------------------------- /test/c89/immediate-branch.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 42, 3 | b = (!0xDD8FB8CEL) ? 7 : 14, 4 | c = (0xDD8FB8CEL || 0), 5 | d = (0xDD8FB8CEL && 1); 6 | if (1) { 7 | a = 4; 8 | } else { 9 | a = 14; 10 | } 11 | 12 | return a + b + c + d; 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/immediate-expr.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | int h = 0xC3F30B91L; 3 | 4 | int main(void) { 5 | int f = (0x47C1471CL > (0x7DL ^ h)); 6 | printf("%d\n", f); 7 | return printf("%d, %d, %d, %f, %f, %d\n", 8 | (0xF2C889DD98AE1F63LL >= 0xAD2086BDL), 9 | (0x000010001D2086BDLL == 0x1D2086BDL), 10 | (0xF2C889DD98AE1F63LL > 0xAD2086BDL), 11 | 8.5867834283 * 3.14f, 12 | 8.5867834283 / 3.14f, 13 | 3.14 == 3.14f); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/immediate-pointer.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct point { 4 | long x, y; 5 | } p; 6 | 7 | static long offset = (long) &((struct point *) 0x8)->y; 8 | 9 | int main(void) { 10 | int *ptr = &*((int *) 0x601044); 11 | return printf("%p, %ld\n", ptr, offset); 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/include.c: -------------------------------------------------------------------------------- 1 | #define include do not include 2 | 3 | #define HEADER 4 | #define HELLO(str) #str 5 | 6 | #include HEADER 7 | 8 | static size_t something = 0; 9 | 10 | #include HELLO(hello.c) 11 | -------------------------------------------------------------------------------- /test/c89/increment.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a = 1; 3 | int b = a++; 4 | int c = --b; 5 | ++a; 6 | --a; 7 | return a-- + b-- - ++c; 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/initialize-address.c: -------------------------------------------------------------------------------- 1 | static int a = 42, *b = &a; 2 | 3 | int *foo[] = {&a, &a, (int *) &b}; 4 | int **bar[] = {&foo[1], foo + 2}; 5 | 6 | int main(void) { 7 | static int f = 3, *p = &f; 8 | 9 | return *b + *foo[1] + *p; 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/initialize-array.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int foo[2][3] = {{1, 2,}, 3, 4, 5}; 4 | 5 | long bar[3][2] = {{1, 2}, {3, 4,}, {5, 6}}; 6 | 7 | struct { 8 | int a[3], b; 9 | } baz[] = {{{1}}, {{2, 7, 4}, 4,}}; 10 | 11 | struct { 12 | unsigned char e[4]; 13 | } pc = {{31, 2, 3, 4,}}; 14 | 15 | struct { 16 | char v[4]; 17 | int k; 18 | } obj = {1, 2, 3,}; 19 | 20 | struct { 21 | long a[4]; 22 | long b; 23 | } s6[] = { 1, 2, 3, -1L, 5, 6, }; 24 | 25 | void verify(void) { 26 | int i, j; 27 | for (i = 0; i < 2; ++i) 28 | for (j = 0; j < 3; ++j) 29 | printf("foo[%d][%d] = %d\n", i, j, foo[i][j]); 30 | for (i = 0; i < 3; ++i) 31 | for (j = 0; j < 2; ++j) 32 | printf("bar[%d][%d] = %ld\n", i, j, bar[i][j]); 33 | for (i = 0; i < 2; ++i) 34 | printf("baz[%d] = {{%d, %d, %d}, %d}\n", 35 | i, baz[i].a[0], baz[i].a[1], baz[i].a[2], baz[i].b); 36 | printf("pc = {{%d, %d, %d, %d}}\n", pc.e[0], pc.e[1], pc.e[2], pc.e[3]); 37 | printf("obj = {{%d, %d, %d, %d}, %d}, size = %lu\n", 38 | obj.v[0], obj.v[1], obj.v[2], obj.v[3], obj.k, sizeof(obj)); 39 | for (i = 0; i < 2; ++i) { 40 | printf("s6[%d]: {{%ld, %ld, %ld, %ld}, %ld}\n", i, 41 | s6[i].a[0], s6[i].a[0], s6[i].a[0], s6[i].a[0], s6[i].b); 42 | } 43 | } 44 | 45 | int arr[] = {1, 2, 3, 4, 5}; 46 | int *a = arr, 47 | *b = &arr[1], 48 | *c = arr + 2, 49 | *d = ((int *)&arr[2]) + 2; 50 | 51 | int main(void) { 52 | verify(); 53 | return printf("%d, %d, %d, %d\n", *a, *b, *c, *d); 54 | } 55 | -------------------------------------------------------------------------------- /test/c89/initialize-call.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int id(int x) { 5 | return x; 6 | } 7 | 8 | void test1(int a, int b) { 9 | char x[] = {id(a), id(b + a)}; 10 | printf("{%d, %d}\n", x[0], x[1]); 11 | } 12 | 13 | struct obj { 14 | short s[3]; 15 | }; 16 | 17 | static struct obj getobj(int a, int b, int c) { 18 | struct obj x = {id(a), (char) id(b) + id(1), id(c)}; 19 | return x; 20 | } 21 | 22 | void test2(void) { 23 | struct { 24 | struct obj t; 25 | } x = {getobj(2, 8, 1)}; 26 | printf("{%d, %d, %d}\n", x.t.s[0], x.t.s[1], x.t.s[2]); 27 | } 28 | 29 | void test3(int n, ...) { 30 | va_list args; 31 | 32 | va_start(args, n); 33 | { 34 | struct { 35 | char c; 36 | char x[3]; 37 | } s = {'a', va_arg(args, int), va_arg(args, int), va_arg(args, int)}; 38 | printf("{%c, {%c, %c, %c}}\n", s.c, s.x[0], s.x[1], s.x[2]); 39 | } 40 | va_end(args); 41 | } 42 | 43 | int main(void) { 44 | test1(4, 3); 45 | test2(); 46 | test3(3, 'w', 'a', 't'); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /test/c89/initialize-float.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | float f = 3.5f; 4 | double d = 42.3; 5 | 6 | struct { 7 | double x; 8 | float y, z; 9 | } p = {4.2f, 9.90}; 10 | 11 | int main(void) { 12 | static double q; 13 | return printf("%f, %f, (%f, %f, %f), %f\n", f, d, p.x, p.y, p.z, q); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/initialize-null.c: -------------------------------------------------------------------------------- 1 | #define NULL (void *) 0 2 | 3 | char *str = NULL; 4 | 5 | int main(void) { 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/c89/initialize-object.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | int a = 42; 5 | short b = {a + 1}; 6 | 7 | return printf("%d\n", b); 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/initialize-string.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | char foo[5] = "Hei"; 4 | char bar[][6] = {"Hello", '\0'}; 5 | char *baz = {"Hello" + 1}; 6 | 7 | void check(void) { 8 | printf("foo: %s, %lu\n", foo, sizeof(foo)); 9 | printf("bar[0]: %s, bar[1]: %s, size: %lu\n", bar[0], bar[1], sizeof(bar)); 10 | printf("baz: %s, %lu\n", baz, sizeof(baz)); 11 | } 12 | 13 | void func(void) { 14 | char a[7] = ("wat"); 15 | char b[3] = {"Hello"[1], 46}; 16 | char c[] = {"World" "hello"}; 17 | 18 | printf("b = {%c, %c, %c}, size = %lu\n", b[0], b[1], b[2], sizeof(b)); 19 | printf("a = %s, size = %lu\n", a, sizeof(a)); 20 | printf("c = %s, size = %lu\n", c, sizeof(c)); 21 | } 22 | 23 | int main(void) { 24 | check(); 25 | func(); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /test/c89/initialize-union.c: -------------------------------------------------------------------------------- 1 | union value { 2 | char v; 3 | long l; 4 | struct { 5 | long x, y; 6 | } point; 7 | }; 8 | 9 | int main() { 10 | union value v = {1}; 11 | return v.point.x; 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/initialize.c: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | int x; 3 | int y; 4 | char *name; 5 | char tag[3]; 6 | } point_t; 7 | 8 | char s[] = "Hello"; 9 | 10 | point_t p = {1, 2, "Hello", {'a', 'b', 'c'}}; 11 | 12 | char tull[] = {'t', 'u', 'l', 'l', '\0'}; 13 | 14 | static char chr; 15 | static char *str; 16 | static char **ptrs; 17 | 18 | int main() { 19 | point_t q = {1, 2, "Hello", {0, 'b', 'c'}}; 20 | 21 | char t[] = {'h', 'e', 'l', 0, 'o', '\0'}; 22 | 23 | int ch = (ptrs == 0) && (str == 0) && (chr == 0); 24 | 25 | return sizeof(p.name) + p.tag[1] + s[5] + t[0] + q.x + ch; 26 | } 27 | -------------------------------------------------------------------------------- /test/c89/integer-suffix.c: -------------------------------------------------------------------------------- 1 | int printf(const char *str, ...); 2 | 3 | int main(void) { 4 | return printf("%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu\n", 5 | sizeof(42), 6 | sizeof(42l), 7 | sizeof(42L), 8 | sizeof(42u), 9 | sizeof(42U), 10 | sizeof(42ul), 11 | sizeof(42uLL), 12 | sizeof(42ULL), 13 | sizeof(42llU), 14 | sizeof(42LLu), 15 | sizeof(42LLU)); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /test/c89/ldouble-load-direct.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | float f = 3.14f; 4 | double g = 2.71; 5 | 6 | int main(void) { 7 | long double d = f; 8 | long double e = g; 9 | return printf("%Lf, %Lf\n", d, e); 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/line-continuation.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | char foo[] = "a\\ 4 | \"; 5 | 6 | char c1 = '\ 7 | \ 8 | a\ 9 | '; 10 | 11 | char c2 = '\ 12 | \\\ 13 | '; 14 | 15 | /* Trigraph backslash */ 16 | char c3 = '??/ 17 | a??/ 18 | '; 19 | 20 | int main(void) { 21 | printf("%s", foo); 22 | printf("%c, %c, %c\n", c1, c2, c3); 23 | return sizeof(foo); 24 | } 25 | -------------------------------------------------------------------------------- /test/c89/line-directive.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | #line __LINE__ 4 | int i = __LINE__; 5 | char *s = __FILE__; 6 | # line 10 "bar.c" 7 | int j = __LINE__; 8 | 9 | int main(void) { 10 | return printf("%d, %d, %d, %s, %s\n", 11 | __LINE__, i, j, s, __FILE__); 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/linebreak.c: -------------------------------------------------------------------------------- 1 | /\ 2 | * 3 | */ # /* 4 | *\ 5 | / defi\ 6 | ne FO\ 7 | O 1\ 8 | 2 9 | 10 | int main() { 11 | return FOO; 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/liveness-deref-assign.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int l; 4 | int wat[] = {3, 4, 5}; 5 | 6 | const int *g; 7 | const int **h = &g; 8 | 9 | int main(void) { 10 | int *p; 11 | p = &wat[1]; 12 | *h = (p = &l); 13 | *p = 1; 14 | 15 | return printf("%d\n", wat[1]); 16 | } 17 | -------------------------------------------------------------------------------- /test/c89/liveness-global.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | float a = 42.42, b; 4 | int c = 1L; 5 | float *d = &b; 6 | 7 | void fn1(void) { 8 | *d = (a = c); 9 | } 10 | 11 | int main(void) { 12 | fn1(); 13 | return printf("%f\n", a); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/liveness-loop.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | float h, g = 1.1; 4 | int i = 2, j = 0; 5 | 6 | int main(void) { 7 | h = (g = i); 8 | for (; j < 5; j++) { } 9 | 10 | return printf("%f\n", g); 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/liveness-param-pointer.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct point { 4 | int x, y; 5 | }; 6 | 7 | struct data { 8 | int *c; 9 | struct point *p; 10 | }; 11 | 12 | static int foo(struct point *p) { 13 | return printf("(%d, %d)\n", p->x, p->y); 14 | } 15 | 16 | static int bar(int *ptr) { 17 | return printf("%d\n", *ptr); 18 | } 19 | 20 | int main(void) { 21 | int i = 42; 22 | struct point p = {2, 4}; 23 | struct data d = {0}; 24 | d.c = &i; 25 | d.p = &p; 26 | p.x = 5; 27 | p.y = 9; 28 | i = 2; 29 | return foo(d.p) + bar(d.c); 30 | } 31 | -------------------------------------------------------------------------------- /test/c89/liveness-pointer.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int k; 4 | long g; 5 | long *l = &g; 6 | 7 | float h[] = {1.1f, 2.2f, 3.3f}; 8 | 9 | float *i = &h[1]; 10 | short j = 0; 11 | 12 | int main(void) { 13 | int n = 5L; 14 | k = (n = (j)); 15 | (*l) = (0x841EC489769724D4LL); 16 | (*i) = n; 17 | return printf("%f\n", h[1]); 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/logical-and-bitwise-false.c: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | int a = 0x01, b = 0x02; 4 | 5 | return a && b; 6 | } 7 | -------------------------------------------------------------------------------- /test/c89/logical-operators-basic.c: -------------------------------------------------------------------------------- 1 | int main() 2 | { 3 | int a = 2; 4 | int b = 1; 5 | 6 | int c = a++ || 1; 7 | int d = b-- && (b = 10) && b-- && 0; 8 | return a + b + c + d; 9 | } 10 | -------------------------------------------------------------------------------- /test/c89/long-double-arithmetic.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int main(void) { 4 | double c1 = -15.3L; 5 | long double c2 = 22.5f; 6 | 7 | long double 8 | a = (long double) c1 + c2, 9 | b = c1 - c2, 10 | c = c1 * c2, 11 | d = c1 / c2; 12 | 13 | return printf("(%f, %Lf), %Lf, %Lf, %Lf, %Lf\n", c1, c2, a, b, c, d); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/long-double-compare.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int test(long double d) { 4 | int i, j; 5 | long double e = 3.14L, f = 0; 6 | 7 | i = d == 1.0L; 8 | j = d != e; 9 | 10 | if (d < 3) f += 1; 11 | if (d <= e) f += 2; 12 | if (d > e) f += 3L; 13 | if (d >= e) f += 4u; 14 | 15 | return printf("%Lf, %Lf, %Lf, %d, %d\n", d, e, f, i, j); 16 | } 17 | 18 | int main(void) { 19 | double a = -3.3; 20 | long double b = 22.5f; 21 | 22 | if (b) { 23 | return test(a) + test(b) + test(1.0L) + test(3.14L); 24 | } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /test/c89/long-double-function.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | struct S1 { 6 | long l; 7 | long double ld; 8 | }; 9 | 10 | struct S1 pack(long l, long double ld) { 11 | struct S1 s = {0}, *r; 12 | s.l = l; 13 | s.ld = ld; 14 | r = &s; 15 | return *r; 16 | } 17 | 18 | long double sum(long double g, long double f) { 19 | return g + f; 20 | } 21 | 22 | long double diff(int n, ...) { 23 | int i; 24 | long double ld = 0; 25 | va_list args; 26 | va_start(args, n); 27 | for (i = 0; i < n; ++i) { 28 | ld = ld - va_arg(args, long double); 29 | } 30 | va_end(args); 31 | return ld; 32 | } 33 | 34 | int main(void) { 35 | struct S1 s1; 36 | double c1 = -15.3; 37 | long double c2 = 22.5f, c3; 38 | 39 | c2 = sum(c1, c2); 40 | s1 = pack(42L, c2); 41 | c3 = diff(2, c2, s1.ld, 2.89L); 42 | 43 | return printf("%Lf, {%ld, %Lf}, %Lf\n", c2, s1.l, s1.ld, c3); 44 | } 45 | -------------------------------------------------------------------------------- /test/c89/long-double-load.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static long double arr[] = {2.9L, 3.14L, 3, 2.1, 4.8f}; 4 | static long double *ref = &arr[3]; 5 | 6 | int test_array(void) { 7 | int i; 8 | long double *ptr = ref; 9 | 10 | printf("%Lf\n", *ptr); 11 | *ptr = arr[3]; 12 | printf("%Lf\n", *ptr); 13 | for (i = 0; i < 4; ++i) { 14 | arr[i] += arr[i + 1]; 15 | printf("%d: %Lf\n", i, arr[i]); 16 | } 17 | 18 | return printf("%Lf\n", *ref); 19 | } 20 | 21 | int test_cast_signed(void) { 22 | char c1 = 'a'; 23 | short c2 = 0x5768; 24 | int c3 = 0x76959876; 25 | long c4 = 0x0976589757652309; 26 | long double d1 = c1, d2 = c2, d3 = c3, d4 = c4; 27 | return printf("signed: %Lf, %Lf, %Lf, %Lf\n", d1, d2, d3, d4); 28 | } 29 | 30 | int test_cast_unsigned(void) { 31 | unsigned char c1 = 'a'; 32 | unsigned short c2 = 0xF768u; 33 | unsigned int c3 = 0xF6959876u; 34 | unsigned long c4 = 0xF976589757652309ul; 35 | long double d1 = c1, d2 = c2, d3 = c3, d4 = c4; 36 | return printf("unsigned: %Lf, %Lf, %Lf, %Lf\n", d1, d2, d3, d4); 37 | } 38 | 39 | int main(void) { 40 | test_array(); 41 | test_cast_signed(); 42 | test_cast_unsigned(); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /test/c89/long-double-struct.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct S1 { 4 | long double a; 5 | } foo = {23.689896L}; 6 | 7 | struct S2 { 8 | long b; 9 | long double a; 10 | char c; 11 | } bar = {2, 123.235, 'a'}; 12 | 13 | struct S1 s1_ret(long double d) { 14 | struct S1 r = {0}; 15 | r.a = d + 2.3L; 16 | printf("s1_ret: %Lf, %Lf\n", d, r.a); 17 | return r; 18 | } 19 | 20 | int s1_arg(struct S1 u) { 21 | long double d = u.a; 22 | struct S1 v; 23 | v = s1_ret(d + 54.789); 24 | return printf("s1_arg: %Lf, %Lf\n", u.a, v.a); 25 | } 26 | 27 | struct S2 s2_ret(long double d) { 28 | struct S2 r = {0}; 29 | r.b = 32; 30 | r.c = 'b'; 31 | r.a = d + 3; 32 | printf("s2_ret: %Lf, (%Lf, %ld, %d)\n", d, r.a, r.b, r.c); 33 | return r; 34 | } 35 | 36 | int s2_arg(struct S2 u) { 37 | long double d = u.a; 38 | struct S2 v; 39 | v = s2_ret(d + 235.80); 40 | return printf("s2_arg: (%Lf, %ld, %d), (%Lf, %ld, %d)\n", 41 | u.a, u.b, u.c, v.a, v.b, v.c); 42 | } 43 | 44 | int main(void) { 45 | return s1_arg(foo) + s2_arg(bar); 46 | } 47 | -------------------------------------------------------------------------------- /test/c89/long-double-union.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | union U1 { 4 | long double a; 5 | } foo = {23.689896L}; 6 | 7 | union U2 { 8 | long double a; 9 | long b; 10 | } bar = {123.235}; 11 | 12 | union U1 u1_ret(long double d) { 13 | union U1 r = {0}; 14 | r.a = d + 2.3L; 15 | printf("u1_ret: %Lf, %Lf\n", d, r.a); 16 | return r; 17 | } 18 | 19 | int u1_arg(union U1 u) { 20 | long double d = u.a; 21 | union U1 v; 22 | v = u1_ret(d + 54.789); 23 | return printf("u1_arg: %Lf, %Lf\n", u.a, v.a); 24 | } 25 | 26 | union U2 u2_ret(long double d) { 27 | union U2 r = {0}; 28 | r.a = d + 3; 29 | printf("u2_ret: %Lf, %Lf\n", d, r.a); 30 | return r; 31 | } 32 | 33 | int u2_arg(union U2 u) { 34 | long double d = u.a; 35 | union U2 v; 36 | v = u2_ret(d + 235.80); 37 | return printf("u2_arg: %Lf, %Lf\n", u.a, v.a); 38 | } 39 | 40 | int main(void) { 41 | return u1_arg(foo) + u2_arg(bar); 42 | } 43 | -------------------------------------------------------------------------------- /test/c89/macro-empty-arg.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | #define FOO(a, b, c) (a) 4 | #define CONCAT(x, y, z) x z ## y + 1 5 | #define STR(i, j) #i "hello" #j "world" 6 | 7 | #define GLUE(a, b) a ## b 8 | #define JOIN(a, b, c) GLUE(a, b c) 9 | 10 | static int n = JOIN(1,,1); 11 | 12 | int main(void) { 13 | int a = CONCAT(2,,); 14 | int b = CONCAT(,2,); 15 | int c = FOO(0 + a, ,); 16 | return printf(STR(,c)) + printf("%d, %d, %d, %d\n", a, b, c, n); 17 | } 18 | -------------------------------------------------------------------------------- /test/c89/macro-function-paren.c: -------------------------------------------------------------------------------- 1 | #define foo(s) s + 1 2 | 3 | int main(void) { 4 | int foo = 4; 5 | return foo(1) + foo; 6 | } 7 | -------------------------------------------------------------------------------- /test/c89/macro-keyword-arg.c: -------------------------------------------------------------------------------- 1 | #define X(v, const) ((v) * (const)) 2 | 3 | int main(void) { 4 | int a = 2; 5 | return X(a, 4); 6 | } 7 | -------------------------------------------------------------------------------- /test/c89/macro-keyword-define.c: -------------------------------------------------------------------------------- 1 | #define double int 2 | 3 | #ifndef double 4 | #error no way 5 | #endif 6 | 7 | #if double + int != defined(int) 8 | #error this should be false 9 | #endif 10 | 11 | int main(void) { 12 | double d = 42; 13 | return sizeof(d); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/macro-name-arg.c: -------------------------------------------------------------------------------- 1 | #define ADD(a, b) a + b 2 | #define APPLY(func, a, b) func(a, b) 3 | #define N APPLY(ADD, 3, 5) 4 | 5 | int main(void) { 6 | return N; 7 | } 8 | -------------------------------------------------------------------------------- /test/c89/macro-param-space.c: -------------------------------------------------------------------------------- 1 | #define declare(name) extern int name (int) 2 | 3 | declare(foo); 4 | 5 | int main(void) { 6 | return foo(2); 7 | } 8 | 9 | int foo(int n) { 10 | return n + 1; 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/macro-paste.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | #define FOO(s) s ## _f ## u ## nc 4 | #define STR(s) #s 5 | #define CAT(a, b) STR(a ## b) 6 | 7 | int foo_func(void) { 8 | return puts(CAT(foo, 5)); 9 | } 10 | 11 | #define glue(a, b) a ## b 12 | #define cat(a, b) glue(a, b) 13 | #define HELLOWORLD "hello" 14 | #define WORLD WORLD ", world" 15 | 16 | int test(void) { 17 | return puts(glue(HELLO, WORLD)) + puts(cat(HELLO, WORLD)); 18 | } 19 | 20 | int main(void) { 21 | return FOO(foo)() + test(); 22 | } 23 | -------------------------------------------------------------------------------- /test/c89/macro-predefined.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char *date = __DATE__; 4 | char *time = __TIME__; 5 | 6 | int main(void) { 7 | return strlen(date) + strlen(time); 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/macro-recursive.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int foo; 4 | 5 | static int max(int a, int b) { 6 | return a + b; 7 | } 8 | 9 | #define SUM(a, b) (a + b) 10 | #define foo SUM(1, foo) 11 | 12 | #define max(x, y) SUM(x, max(1, y)) 13 | 14 | int main(void) { 15 | int b = foo; 16 | int c = max(1, foo); 17 | int d = max(1, max(2, foo)); 18 | int e = max( 19 | foo + 3, 20 | max(foo, 21 | foo - 2)) 22 | + foo; 23 | return printf("%d, %d, %d, %d\n", b, c, d, e); 24 | } 25 | -------------------------------------------------------------------------------- /test/c89/macro-refill-expand.c: -------------------------------------------------------------------------------- 1 | #define FOO PRINT 2 | #define PRINT(m) printf("%s\n", m) 3 | #define BAR printf("hello: "); PRINT 4 | 5 | int printf(const char *, ...); 6 | 7 | int main(void) 8 | { 9 | FOO( 10 | 11 | 12 | "hi" 13 | 14 | "ho" 15 | 16 | ); 17 | 18 | FOO("Hello"); 19 | #if 1 20 | BAR 21 | ( 22 | "to you"); 23 | #endif 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /test/c89/macro-repeat-expand.c: -------------------------------------------------------------------------------- 1 | #define __STD_TYPE 2 | #define __UQUAD_TYPE unsigned long int 3 | #define __DEV_T_TYPE __UQUAD_TYPE 4 | 5 | __STD_TYPE __UQUAD_TYPE __dev_t; 6 | 7 | int main(void) { 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/c89/macro-skip-expand.c: -------------------------------------------------------------------------------- 1 | #ifdef FOO 2 | # if FOO(1, 2) 3 | # error This should not happen 4 | # elif FOO(2, 3) 5 | # error Not this either 6 | # endif 7 | #endif 8 | 9 | int printf(const char *, ...); 10 | 11 | int square(int x) { 12 | return x * x; 13 | } 14 | 15 | #define square(x) x 16 | 17 | int main(void) { 18 | return printf("square=%d, %d, %d\n", square(square)(2), square(square 19 | (square( 20 | square))) 21 | (2), 22 | square(2)); 23 | } 24 | -------------------------------------------------------------------------------- /test/c89/macro.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | int printf(const char *, ...); 3 | 4 | #define FOO(a, b) (a b - 1) 5 | 6 | #define BAR(x) __FILE__, *d = #x, e = x ; 7 | #define max(a, b) ((a) > (b) ? (a) : (b)) 8 | 9 | /* 10 | * Some comments to confuse line counting. 11 | */ 12 | 13 | int main(void) { 14 | int a = 42, b; /* Single line comment. */ 15 | char *c = BAR( 16 | __LINE__) 17 | 18 | printf("max=%d\n", max(max(2, -1), 1)); 19 | puts(c); 20 | puts(d); 21 | 22 | puts(__FILE__); 23 | #if (__STDC_VERSION__ >= 199901) 24 | puts(__func__); 25 | #endif 26 | b = __LINE__ + FOO ( 1 + a *, 2 ) + e; 27 | return printf("%d\n", b); 28 | } 29 | -------------------------------------------------------------------------------- /test/c89/main.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int a; 3 | a = 42; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /test/c89/negate.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int a = 2, b = 3, c = 4; 4 | 5 | int main(void) { 6 | int d = !(a == b); 7 | int e = !(c - 1 != b); 8 | int f = !(a > e); 9 | int g = !(f <= c); 10 | 11 | return printf("%d, %d, %d, %d\n", d, e, f, g); 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/nested-macro.c: -------------------------------------------------------------------------------- 1 | #define foo(v) bar(v, a + 2) 2 | #define bar(v, i) v = 42 + i; 3 | 4 | int main() { 5 | int a = 1; 6 | foo(a); 7 | return a; 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/offsetof.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | struct point { 6 | int x; 7 | long y; 8 | }; 9 | 10 | int main(void) { 11 | return printf("%lu\n", offsetof(struct point, y)); 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/old-param-decay.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | #define N 42 4 | 5 | int foo(n, a) 6 | int a[31][N]; 7 | int n; 8 | { 9 | return sizeof(a) + sizeof(a[14]) + n; 10 | } 11 | 12 | int main(void) { 13 | int a[2][N] = {0}; 14 | return printf("%d\n", foo(N, a)); 15 | } 16 | -------------------------------------------------------------------------------- /test/c89/old-style-declaration.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int foo(int n, const char *str); 4 | 5 | int foo(n, str) 6 | int n; 7 | const char *str; 8 | { 9 | return printf("%d, %s\n", n, str); 10 | } 11 | 12 | int main(void) { 13 | return foo(42, "Hello World"); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/old-style-definition.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int max(a, b) 4 | register int a, b; 5 | { 6 | return (a > b) ? a : b; 7 | } 8 | 9 | int print(line, message) 10 | int line; 11 | const char *message; 12 | { 13 | return printf("(%d): %s\n", line, message); 14 | } 15 | 16 | int main(void) { 17 | return print(max(3, -5), "Hello world"); 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/padded-initialization.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static struct point { 4 | char c; 5 | int d; 6 | } obj = {'a', 0xaabbccdd}; 7 | static char sc; 8 | 9 | int main() { 10 | sc = 'a'; 11 | printf("%c\n%d\n%c\n", obj.c, obj.d, sc); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/params-mixed.c: -------------------------------------------------------------------------------- 1 | struct point { 2 | char x; 3 | int y; 4 | void *next; 5 | }; 6 | 7 | struct mem { 8 | int arr[255]; 9 | }; 10 | 11 | int func(struct point p, struct mem m, long a, long b, long c, long d, int e) { 12 | p.x = 1; 13 | m.arr[0] = 1; 14 | return p.y + m.arr[0] + a + b + c + d + e; 15 | } 16 | 17 | int main () { 18 | struct point p = {1, 2, 0}; 19 | struct mem arr; 20 | return func(p, arr, 1, 2, 3, 4, 5); 21 | } 22 | -------------------------------------------------------------------------------- /test/c89/params-system-v.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Example adapted from System V ABI, Figure 3.6. 3 | */ 4 | 5 | typedef struct { 6 | int a, b; 7 | } structparm; 8 | 9 | int func(int e, int f, structparm s, int g, int h, int i, int j, int k) 10 | { 11 | return e + f + s.a + s.b + g + h + i + j + k; 12 | } 13 | 14 | int main () { 15 | structparm s = {8, 9}; 16 | int e = 1, f = 2, g = 3, h = 4, i = 5, j = 6, k = 7; 17 | return func(e, f, s, g, h, i, j, k); 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/partial-initialization.c: -------------------------------------------------------------------------------- 1 | struct point { 2 | char c; 3 | struct { 4 | int a, b; 5 | } inner; 6 | int x, y, z, w; 7 | }; 8 | 9 | int main() 10 | { 11 | int z[][2] = { 12 | { 1 }, { 2 }, { 3 }, { 4 } 13 | }; 14 | struct point p = { 'a', { 1 }, 2 }; 15 | return 16 | z[0][0] + z[0][1] + z[2][0] + 17 | p.c + p.inner.a + p.inner.b + p.x + p.w; 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/pointer-diff.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int diff(char **first, char **last) { 4 | return printf("%ld\n", last - first); 5 | } 6 | 7 | int main(void) { 8 | char *DataList[4]; 9 | return diff(DataList, DataList + 4); 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/pointer-immediate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef float vec_t[3]; 5 | 6 | typedef struct { 7 | vec_t loc; 8 | } point_t; 9 | 10 | static int offsets[] = { 11 | (unsigned long)&((point_t*)0)->loc[0], 12 | (unsigned long)&((point_t*)0)->loc[2], 13 | (unsigned long)&((vec_t*)0)[1] 14 | }; 15 | 16 | int main(void) { 17 | int *a = (((int*) 0x10) - 2); 18 | int *b = (((int*) 0x10) + 2); 19 | 20 | assert(a == (int *) 0x08); 21 | assert(b == (int *) 0x18); 22 | 23 | return printf("%d, %d, %d\n", offsets[0], offsets[1], offsets[2]); 24 | } 25 | -------------------------------------------------------------------------------- /test/c89/pointer.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int *p, *q; 4 | 5 | /* Based on TCC test suite. */ 6 | int compare(void) { 7 | int i = -1; 8 | 9 | q += i; 10 | printf("a: %d %d %d %d %d %d\n", 11 | p == q, p != q, p < q, p <= q, p >= q, p > q); 12 | 13 | i = 0xf0000000; 14 | p += i; 15 | printf("b: %p %p %ld\n", q, p, p-q); 16 | 17 | p = (int *)((char *)p + 0xf0000000); 18 | printf("c: %d %d %d %d %d %d\n", 19 | p == q, p != q, p < q, p <= q, p >= q, p > q); 20 | 21 | p += 0xf0000000; 22 | printf("d: %p %p %ld\n", q, p, p-q); 23 | printf("e: %d %d %d %d %d %d\n", 24 | p == q, p != q, p < q, p <= q, p >= q, p > q); 25 | return 0; 26 | } 27 | 28 | int basic(void) { 29 | int a; 30 | int *b = &a; 31 | 32 | *b = 2; 33 | a = *b; 34 | return a + *b; 35 | } 36 | 37 | int main(void) { 38 | return basic() + compare(); 39 | } 40 | -------------------------------------------------------------------------------- /test/c89/preprocess-expression.c: -------------------------------------------------------------------------------- 1 | #define triple(a) (3 * (a)) 2 | #define FOO 2 3 | 4 | #if (FOO ? 0 : 1) 5 | # error wrong 6 | #endif 7 | #if BAR == 0 && defined FOO && triple(1) == 3 8 | 9 | int main() { 10 | return 1; 11 | } 12 | 13 | #elif triple(0) 14 | #error Not possible 15 | #endif 16 | 17 | #define T1 ((1 ? -1 : (0, 0u)) < 0) 18 | 19 | #if T1 20 | # error Should be false 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /test/c89/preprocess.c: -------------------------------------------------------------------------------- 1 | #ifdef NO 2 | # error not supposed to happen 3 | #elif 0 4 | # error "not this either" 5 | # 6 | #else 7 | # include "header.h" 8 | # define triple(a) (3 * (a)) 9 | #endif 10 | 11 | #pragma 12 | 13 | #if 1 14 | # pragma = This should be ignored 15 | #endif 16 | 17 | # 18 | # 19 | # 20 | 21 | #define iscool() 1; 22 | # 23 | #include "header.h" 24 | 25 | int main() { 26 | return FOO + triple(3) + iscool ( ); 27 | } 28 | -------------------------------------------------------------------------------- /test/c89/preprocessor-expression.c: -------------------------------------------------------------------------------- 1 | #define A 9223372036854775807L 2 | #define B 2147483647 3 | 4 | int a = 5 | #if (A >= B) 6 | 1 7 | #else 8 | 2 9 | #endif 10 | ; 11 | 12 | #if (0xFFFFFFFFFFFFFFFF <= 42) 13 | # error Unsigned compare failed! 14 | #endif 15 | 16 | int main(void) { 17 | return a; 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/printstr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static void 5 | printstr(FILE *stream, const char *str) 6 | { 7 | char c; 8 | 9 | while ((c = *str++) != '\0') { 10 | putc(c, stream); 11 | if (isprint(c) && c != '"' && c != '\\') 12 | putc(c, stream); 13 | else 14 | fprintf(stream, "\\x%x", (int) c); 15 | } 16 | } 17 | 18 | int main() { 19 | printstr(stdout, "heisann!\n"); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/c89/promote-unsigned.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | unsigned int ui = 12; 3 | unsigned long ul = 34; 4 | 5 | return ui + ul; 6 | } 7 | -------------------------------------------------------------------------------- /test/c89/prototype-scope-enum.c: -------------------------------------------------------------------------------- 1 | enum { 2 | FOO = 1, 3 | BAR = 2 4 | }; 5 | 6 | extern int foo(enum { FOO = 4, BAR = 5 } pp, int arr[][FOO]); 7 | 8 | int main(void) { 9 | return FOO; 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/ptrdiff.c: -------------------------------------------------------------------------------- 1 | struct point { 2 | int x, y; 3 | } points[5]; 4 | 5 | char *str = "Hello world"; 6 | 7 | int main() { 8 | char *send = str + 8; 9 | struct point *pend = points + 3; 10 | 11 | unsigned long sdiff = send - str; 12 | unsigned long pdiff = pend - points; 13 | 14 | return sdiff + pdiff; 15 | } 16 | -------------------------------------------------------------------------------- /test/c89/push-immediate.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int foo(int a, int b, int c, int d, int e, int f, unsigned int g) { 4 | return printf("%d, %d, %d, %d, %d, %d, %u\n", a, b, c, d, e, f, g); 5 | } 6 | 7 | int main(void) { 8 | return foo(1, 2, 3, 4, 5, 6, 0xFF000000u); 9 | } 10 | -------------------------------------------------------------------------------- /test/c89/qualifier-repeat.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | const const int a = 42; 4 | static volatile volatile int b; 5 | 6 | int main(void) { 7 | return a + b; 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/register-param.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int foo(register char const *str, register int i) { 4 | char c = str[0]; 5 | return printf("%s, %d, %c\n", str, i, c); 6 | } 7 | 8 | int main(void) { 9 | int i = 42; 10 | return foo("Hello", i); 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/return-bitfield.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | union U3 { 4 | int f0; 5 | signed f1 : 8; 6 | } g = {0xB37CF3EAL}; 7 | 8 | int fn3(union U3 p1) { return p1.f1; } 9 | 10 | int main(void) { 11 | int i = fn3(g); 12 | return printf("%d\n", i); 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/return-compare-int.c: -------------------------------------------------------------------------------- 1 | int printf(char *, ...); 2 | 3 | static int g; 4 | 5 | long fn8(void) { 6 | return 0x800000000; 7 | } 8 | 9 | short fn2(void) { 10 | return (short)0x70000; 11 | } 12 | 13 | char fn1(void) { 14 | return (char)0x600; 15 | } 16 | 17 | int main(void) { 18 | if (fn8()) { 19 | g += 8; 20 | } 21 | 22 | if (fn2()) { 23 | g += 2; 24 | } 25 | 26 | if (fn1()) { 27 | g += 1; 28 | } 29 | 30 | return printf("%d\n", g); 31 | } 32 | -------------------------------------------------------------------------------- /test/c89/return-float-struct.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct s { 4 | float f; 5 | } wat = {3.14f}; 6 | 7 | struct s foo(void) { 8 | return wat; 9 | } 10 | 11 | int main(void) { 12 | struct s bar = foo(); 13 | return printf("%f\n", bar.f); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/return-partial-register.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct point { 4 | char a; 5 | char b; 6 | char c; 7 | }; 8 | 9 | struct point foo(int a) { 10 | struct point p = {0}; 11 | p.a = a; 12 | return p; 13 | } 14 | 15 | struct point bar(struct point p) { 16 | struct point q;; 17 | q.a = p.a; 18 | q.b = p.b; 19 | q.c = p.c; 20 | return q; 21 | } 22 | 23 | int main(void) { 24 | struct point 25 | p = foo(42), 26 | q = bar(p); 27 | return printf("(%d, %d, %d), (%d, %d, %d)\n", 28 | p.a, p.b, p.c, q.a, q.b, q.c); 29 | } 30 | -------------------------------------------------------------------------------- /test/c89/return-point.c: -------------------------------------------------------------------------------- 1 | /* Takes up more than two eightbytes, thus must be returned by memory and not 2 | * registers. 3 | */ 4 | struct point { 5 | long x, y, z; 6 | } points[] = { 7 | {1, 2, 3}, 8 | {4, 5, 6} 9 | }; 10 | 11 | struct point getPoint(int i) { 12 | return points[i]; 13 | } 14 | 15 | int main() { 16 | struct point p = getPoint(1); 17 | return p.y; 18 | } 19 | -------------------------------------------------------------------------------- /test/c89/return-struct-basic.c: -------------------------------------------------------------------------------- 1 | struct point { 2 | int x, y; /* Both fit in %rax */ 3 | }; 4 | 5 | struct point func(void) 6 | { 7 | struct point p = {1, 2}; 8 | return p; 9 | } 10 | 11 | int main () { 12 | struct point p; 13 | 14 | p = func(); 15 | return p.x + p.y; 16 | } 17 | -------------------------------------------------------------------------------- /test/c89/return-struct-integers.c: -------------------------------------------------------------------------------- 1 | struct point { 2 | int x, y; /* %rax */ 3 | long l; /* %rdx */ 4 | }; 5 | 6 | struct point func(void) 7 | { 8 | struct point p = {1, 2, 3}; 9 | return p; 10 | } 11 | 12 | int main() { 13 | struct point p; 14 | 15 | p = func(); 16 | return p.x + p.y + p.l; 17 | } 18 | -------------------------------------------------------------------------------- /test/c89/return-struct-mem.c: -------------------------------------------------------------------------------- 1 | /* Too large to fit in two registers, pass address of result object in %rdi. */ 2 | struct mem { 3 | int x, y; 4 | char c; 5 | long l; 6 | }; 7 | 8 | struct mem func(void) 9 | { 10 | struct mem p = {1, 2, 'a', 3}; 11 | return p; 12 | } 13 | 14 | int main() { 15 | struct mem p; 16 | 17 | p = func(); 18 | return p.x + p.y + p.c + p.l; 19 | } 20 | -------------------------------------------------------------------------------- /test/c89/self-referential-struct.c: -------------------------------------------------------------------------------- 1 | struct node { 2 | int value; 3 | const struct node *next; 4 | }; 5 | 6 | int main() { 7 | struct node n; 8 | n.value = 42; 9 | n.next = &n; 10 | return n.next->value; 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/shift-assign.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 5; 3 | int b = 0x10030; 4 | 5 | a <<= 1; 6 | b >>= a; 7 | return a + b; 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/shift.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int unsigned_char(void) { 4 | unsigned char a = 0xE8u; 5 | char b = 2; 6 | 7 | return printf("%lu, %d, %d\n", sizeof(a << b), a << b, a >> b); 8 | } 9 | 10 | static int signed_char(void) { 11 | signed char a = 0x65; 12 | int b = 3; 13 | 14 | return printf("%lu, %d, %d\n", sizeof(a << b), a << b, a >> b); 15 | } 16 | 17 | static int signed_long(void) { 18 | long a = 0x7E00FF0F; 19 | short b = 33; 20 | 21 | return printf("%lu, %ld, %ld\n", sizeof(a << b), a << b, a >> 4); 22 | } 23 | 24 | static int chained(void) 25 | { 26 | unsigned a = 0x7EABCDF4; 27 | return printf("%u\n", a << 3 >> 1); 28 | } 29 | 30 | static int overflow(void) { 31 | long a, b = 0x567895; 32 | a = 0x567895 << 10; 33 | b = b << 10; 34 | return printf("%ld, %ld\n", a, b); 35 | } 36 | 37 | int main(void) { 38 | return unsigned_char() 39 | + signed_char() 40 | + signed_long() 41 | + chained() 42 | + overflow(); 43 | } 44 | -------------------------------------------------------------------------------- /test/c89/short-circuit-comma.c: -------------------------------------------------------------------------------- 1 | int f = 1; 2 | 3 | int main(void) { 4 | 1 && (f++, 1); 5 | 0 || (f++, 1); 6 | return f; 7 | } 8 | -------------------------------------------------------------------------------- /test/c89/short-circuit.c: -------------------------------------------------------------------------------- 1 | int foo(void) { 2 | int f = 2, g = 0; 3 | int h = (g < 7) ^ (1 || (f = 1)); 4 | int j = (g < 7) ^ (0 && (f = 1)); 5 | return f + h + j; 6 | } 7 | 8 | int bar(void) { 9 | int i = 1, j = 1; 10 | if (13L && i) { 11 | i = 4; 12 | } 13 | if (0 || j) { 14 | j = 7; 15 | } 16 | return i + j; 17 | } 18 | 19 | int baz() { 20 | int i = 1, j = 1; 21 | j = (0 || (j + 1)); 22 | return i + j; 23 | } 24 | 25 | int main(void) { 26 | char a = 1, b = 2; 27 | 28 | int t1 = (a == 0 && (b = 0)); 29 | int t2 = a || 1 || (b = 1); 30 | 31 | return b + foo() + bar() + baz(); 32 | } 33 | -------------------------------------------------------------------------------- /test/c89/shortcircuit-loop.c: -------------------------------------------------------------------------------- 1 | int foo(void) { 2 | while (1) { 3 | return 1; 4 | } 5 | } 6 | 7 | int bar(void) { 8 | int i = 0; 9 | do { 10 | if (i++) 11 | return 1; 12 | } while (1); 13 | } 14 | 15 | int baz(void) { 16 | int i; 17 | for (i = 0; 1; i++) { 18 | return 3; 19 | } 20 | } 21 | 22 | int main() { 23 | if (1) 24 | return foo() + bar() + baz(); 25 | } 26 | -------------------------------------------------------------------------------- /test/c89/signed-division.c: -------------------------------------------------------------------------------- 1 | int foo() { 2 | short k = (0xDFB2L); 3 | long i = (((0x5405EA32 / (k)))); 4 | return i; 5 | } 6 | 7 | long baz(void) { 8 | char s = 'a'; 9 | return s / 3L; 10 | } 11 | 12 | int main() { 13 | short k = (0xDFB2L); 14 | int i = (((0x5405EA32L / (k)))); 15 | return i + foo() + baz(); 16 | } 17 | -------------------------------------------------------------------------------- /test/c89/sizeof.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | typedef struct Foo Bar; 4 | 5 | int main(void) { 6 | int bar[5]; 7 | long a = sizeof(volatile char) + sizeof(bar); 8 | long b = sizeof (a = a + 2); 9 | unsigned long c = sizeof(Bar *); 10 | unsigned long d = sizeof(int (*)(char)) + sizeof(struct {char a;}); 11 | 12 | printf("sizeof(sizeof(int)) = %lu\n", sizeof(sizeof(int))); 13 | printf("sizeof a = %lu", sizeof a); 14 | printf("a = %ld, b = %ld, c = %lu, d = %lu\n", a, b, c, d); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /test/c89/string-addr.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | /* Note that *c is still incomplete after this assignment. */ 4 | char (*c)[] = &"Hello"; 5 | 6 | int main(void) 7 | { 8 | puts(*c); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/string-concat.c: -------------------------------------------------------------------------------- 1 | int puts(const char *s); 2 | 3 | char str[] = 4 | "Hel" \ 5 | "lo" 6 | " " 7 | "wo" "rld" "!"; 8 | 9 | int main(void) { 10 | puts(str); 11 | return sizeof(str); 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/string-conversion.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static long foo = 43 + (long) "What" - 1; 5 | 6 | int main(void) { 7 | int a = "abc" == (void *)0; 8 | 9 | assert(a == 0 && "Hello"); 10 | assert(a == 1 || "Hello"); 11 | 12 | if ("foo" || "bar") { 13 | printf("if\n"); 14 | } 15 | 16 | while ("bar") { 17 | printf("while\n"); 18 | break; 19 | } 20 | 21 | printf("%s\n", ((char *) foo) - 42); 22 | 23 | return printf("a = %d\n", a); 24 | } 25 | -------------------------------------------------------------------------------- /test/c89/string-escape.c: -------------------------------------------------------------------------------- 1 | int puts(const char *s); 2 | 3 | const char str[] = "\tconst \af \but \vat \fak \x64 \\? \? \' \" ' \r\n"; 4 | 5 | int main(void) { 6 | puts(str); 7 | puts("\1412\142\145"); 8 | return sizeof(str); 9 | } 10 | -------------------------------------------------------------------------------- /test/c89/string-index.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | char a = "Hello"[2]; 3 | char b = 2["World"]; 4 | return a + b; 5 | } 6 | -------------------------------------------------------------------------------- /test/c89/string-length.c: -------------------------------------------------------------------------------- 1 | static const char str[] = 2 | "Hello\0" " world," 3 | "\0 this is dog!"; 4 | 5 | int main(void) { 6 | return sizeof(str) + sizeof(""); 7 | } 8 | -------------------------------------------------------------------------------- /test/c89/stringify.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | int puts(const char *); 3 | 4 | #define STR(x) #x 5 | 6 | static char *c[] = { 7 | STR( 8 | ) 9 | STR( ) 10 | STR(\n) 11 | STR($), 12 | STR(*\\\a\t\\vv) 13 | STR(@ #), 14 | STR(`), 15 | STR(\a\b\f\n\r\t\v\\\?) 16 | STR(\001 17 | \77 18 | \x1A 19 | \xAt 20 | \0a), 21 | STR( 2.34 ), 22 | STR(while), 23 | STR(==), 24 | STR(#), 25 | STR("\\ \" \t"), 26 | STR(""), 27 | STR(' ') 28 | }; 29 | 30 | static int foo(void) { 31 | int n = 0; 32 | n += puts(STR( this is some string )); 33 | n += puts(STR(this -= '8' 2u '\a' "i\ns\t" 34 | '\n' a "te\0st")); 35 | return n; 36 | } 37 | 38 | int main(void) { 39 | int i; 40 | long n = 0; 41 | for (i = 0; i < sizeof(c) / sizeof(*c); ++i) { 42 | n += puts(c[i]); 43 | } 44 | 45 | n += foo(); 46 | n += '\302'; 47 | n += '\x98'; 48 | n += '\xA'; 49 | return printf("%ld\n", n); 50 | } 51 | -------------------------------------------------------------------------------- /test/c89/strings.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | char hello[] = "Hello World!"; 4 | 5 | char *how = ("How are you?" - 1) + 3; 6 | 7 | char *foo(void) 8 | { 9 | return "From foo with love"; 10 | } 11 | 12 | int main(void) 13 | { 14 | char arr[] = "How are you?"; 15 | char *offst = "How are you?" + 5; 16 | puts(hello); 17 | puts(how); 18 | puts(arr); 19 | puts(foo()); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/c89/struct-alignment.c: -------------------------------------------------------------------------------- 1 | struct point { 2 | long a, b; 3 | short d; 4 | int c; 5 | char e; 6 | }; 7 | 8 | struct foo { 9 | struct point point; 10 | char c[7]; 11 | union { 12 | char c; 13 | void *p; 14 | struct { 15 | int i; 16 | } s; 17 | } val; 18 | }; 19 | 20 | int main() { 21 | return sizeof(struct foo); 22 | } 23 | -------------------------------------------------------------------------------- /test/c89/struct-assign.c: -------------------------------------------------------------------------------- 1 | struct { 2 | short s; 3 | } p1 = {1}, p2 = {2}; 4 | 5 | struct { 6 | char a; 7 | short b, c; 8 | } q1 = {3}, q2 = {4}; 9 | 10 | int main(void) { 11 | p1 = p2; 12 | q1 = q2; 13 | return p1.s + q1.a + q1.b + q1.c; 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/struct-comma-call.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct S3 { 4 | unsigned f0; 5 | int f1; 6 | float f2; 7 | }; 8 | 9 | char f = 41; 10 | int h = 0; 11 | 12 | void fn2(char p1, long p2) { 13 | h |= p1; 14 | } 15 | 16 | struct S3 fn3(void) { 17 | struct S3 foo = {0}; 18 | return foo; 19 | } 20 | 21 | int main(void) { 22 | fn2((0x11 & f), (fn3(), 379)); 23 | return printf("%d\n", h); 24 | } 25 | -------------------------------------------------------------------------------- /test/c89/struct-eightbyte-write.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct S0 { 4 | float f0; 5 | int f1; 6 | float f2; 7 | } c = {1.0f}; 8 | 9 | struct S0 *d = &c; 10 | float e = 0xBEA32D2AL; 11 | struct S0 f = {34.4f}; 12 | 13 | long g = 1L; 14 | struct S0 *j = &f; 15 | long *m = &g; 16 | 17 | struct S0 foo(void) { 18 | return *d; 19 | } 20 | 21 | int main(void) { 22 | *m = 42; 23 | (*j) = foo(); 24 | return printf("%ld, (%f, %d, %f)\n", g, f.f0, f.f1, f.f2); 25 | } 26 | -------------------------------------------------------------------------------- /test/c89/struct-init-swap.c: -------------------------------------------------------------------------------- 1 | /* From Listing 3 in "Test-Case Reduction for C Compiler Bugs" paper, available 2 | * at http://www.cs.utah.edu/~regehr/papers/pldi12-preprint.pdf. 3 | */ 4 | 5 | int printf (const char *, ...); 6 | struct { 7 | int f0; 8 | int f1; 9 | int f2; 10 | } a, b = { 0, 0, 1 }; 11 | 12 | void fn1 () { 13 | a = b; 14 | a = a; 15 | } 16 | 17 | int main () { 18 | fn1 (); 19 | printf ("%d\n", a.f2); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/c89/struct-padding.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct foo { 4 | char c; 5 | int y; 6 | long x; 7 | }; 8 | 9 | struct s2 { 10 | int foo, bar; 11 | int b; 12 | }; 13 | 14 | struct s3 { 15 | char *c; 16 | int i; 17 | }; 18 | 19 | struct s4 { 20 | char foo[7]; 21 | int l; 22 | }; 23 | 24 | struct s5 { 25 | char c; 26 | }; 27 | 28 | struct s6 { 29 | char c[9]; 30 | }; 31 | 32 | struct s7 { 33 | int x; 34 | int y; 35 | char *name; 36 | char tag[3]; 37 | }; 38 | 39 | struct s8 { 40 | char s[3]; 41 | char c[5]; 42 | }; 43 | 44 | struct s9 { 45 | short s; 46 | char c[3]; 47 | }; 48 | 49 | struct s10 { 50 | short s; 51 | int i[2]; 52 | }; 53 | 54 | int main() { 55 | 56 | assert(sizeof(struct foo) == 16); 57 | assert(sizeof(struct s2) == 12); 58 | assert(sizeof(struct s3) == 16); 59 | assert(sizeof(struct s4) == 12); 60 | assert(sizeof(struct s5) == 1); 61 | assert(sizeof(struct s6) == 9); 62 | assert(sizeof(struct s7) == 24); 63 | assert(sizeof(struct s8) == 8); 64 | assert(sizeof(struct s9) == 6); 65 | assert(sizeof(struct s10) == 12); 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /test/c89/struct.c: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | int x; 3 | int y; 4 | struct { 5 | int val; 6 | } z; 7 | } point_t; 8 | 9 | int main() { 10 | point_t point; 11 | point_t *foo; 12 | 13 | point.x = 1; 14 | point.y = 3; 15 | 16 | foo = &point; 17 | foo->x = 17; 18 | foo->z.val = 5; 19 | 20 | return point.y * point.z.val - point.x; 21 | } 22 | -------------------------------------------------------------------------------- /test/c89/switch-basic.c: -------------------------------------------------------------------------------- 1 | int test(int a) { 2 | int b = 0; 3 | 4 | switch (a) { 5 | case 1: b = 2; 6 | break; 7 | case 2: b = 3; 8 | case 3: b = 0; 9 | default: 10 | b = 6; 11 | break; 12 | } 13 | 14 | return b; 15 | } 16 | 17 | int main() 18 | { 19 | return test(1) + test(2) + test(3) + test(4); 20 | } 21 | -------------------------------------------------------------------------------- /test/c89/switch-nested.c: -------------------------------------------------------------------------------- 1 | int test(int a) { 2 | int b = 0; 3 | 4 | switch (a) { 5 | case 1: b = 2; 6 | break; 7 | default: 8 | switch (a - 2) { 9 | default: 10 | break; 11 | case 0: 12 | return 1; 13 | } 14 | break; 15 | case 3: b = 6; 16 | } 17 | 18 | return b; 19 | } 20 | 21 | int main() 22 | { 23 | return test(1) + test(2) + test(3) + test(4); 24 | } 25 | -------------------------------------------------------------------------------- /test/c89/switch-side-effect.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int c; 4 | 5 | int foo(int n) { 6 | c += n; 7 | return 3; 8 | } 9 | 10 | int main(void) { 11 | switch (foo(42)) { 12 | case 1: 13 | return 1; 14 | case 2: 15 | return 6; 16 | default: 17 | break; 18 | } 19 | 20 | return printf("%d\n", c); 21 | } 22 | -------------------------------------------------------------------------------- /test/c89/tag.c: -------------------------------------------------------------------------------- 1 | typedef struct _IO_FILE FILE; 2 | 3 | struct token { 4 | int x; 5 | int y; 6 | } wat = {0, 2}; 7 | 8 | int main() { 9 | struct token t = {5, 7}; 10 | 11 | wat.y = 3; 12 | 13 | return t.x + wat.y; 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/tail-compare-jump.c: -------------------------------------------------------------------------------- 1 | int f = 0, g; 2 | long h = 42l; 3 | 4 | int main(void) { 5 | f < 0L; 6 | if (h) { 7 | g = 2; 8 | } else { 9 | g = 1; 10 | } 11 | return g; 12 | } 13 | -------------------------------------------------------------------------------- /test/c89/token.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | int putchar(int); 3 | 4 | const char foo[] = "\041\042 \043\052 The answer to everything is \x34\x32 (\?)"; 5 | 6 | char bar[] = "\"The End\"\0 Nothing to see here."; 7 | 8 | char t1 = '\056'; 9 | char t2 = '\x53'; 10 | char t3 = '\n'; 11 | char t4 = '`'; 12 | char t5 = 'a'; 13 | char t6 = '\0'; 14 | 15 | int _printstuff__() { 16 | puts(foo); 17 | puts(bar); 18 | 19 | putchar(t1); 20 | t1 = '9'; 21 | putchar(t1); 22 | putchar(t2); 23 | putchar(t3); 24 | putchar(t4); 25 | putchar(t5); 26 | putchar(t6); 27 | 28 | return t5; 29 | } 30 | 31 | int main() { 32 | return _printstuff__(); 33 | } 34 | -------------------------------------------------------------------------------- /test/c89/tokenize-partial-keyword.c: -------------------------------------------------------------------------------- 1 | int reg(int a) { 2 | return a; 3 | } 4 | 5 | int main(void) { 6 | int t = 1; 7 | return reg(t); 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/trigraph.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | ??= define FOO 42 4 | 5 | int main(void) ??< 6 | int bar??(??) = {??-1, '??/n', 3 ??' 7??>; 7 | printf("What??!, %d, %d, %d\n", 8 | bar[0], bar[1], bar[2]); 9 | return FOO ??! 3; 10 | ??> 11 | -------------------------------------------------------------------------------- /test/c89/typedef-function.c: -------------------------------------------------------------------------------- 1 | int atoi(const char *nptr); 2 | int isalnum(int c); 3 | 4 | typedef int foo_fn(const char *); 5 | 6 | int foo(foo_fn fn) { 7 | int (*p)(const char *) = fn; 8 | return p("10"); 9 | } 10 | 11 | typedef int bar_fn(int); 12 | 13 | int bar(bar_fn fn) { 14 | return fn('a'); 15 | } 16 | 17 | int main(void) { 18 | return foo(atoi) + bar(isalnum); 19 | } 20 | -------------------------------------------------------------------------------- /test/c89/typedef-initialize.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | static void test1(void) 6 | { 7 | typedef int A[]; 8 | A a = { 1, 2 }; 9 | A b = { 3, 4, 5 }; 10 | 11 | assert(sizeof(a) / sizeof(*a) == 2); 12 | assert(sizeof(b) / sizeof(*b) == 3); 13 | } 14 | 15 | static void test2(void) 16 | { 17 | typedef int A[]; 18 | A a = { 1, 2 }, b = { 3, 4, 5 }; 19 | 20 | assert(sizeof(a) / sizeof(*a) == 2); 21 | assert(sizeof(b) / sizeof(*b) == 3); 22 | } 23 | 24 | typedef char T[][2]; 25 | 26 | static T const g1 = {{'a', 'b'}, {'c'}}; 27 | T g2 = {'1', '2', 'a', 'b', '8', '0', '='}; 28 | 29 | static void test3(void) 30 | { 31 | int i; 32 | 33 | printf("g1: "); 34 | for (i = 0; i < sizeof(g1) / sizeof(*g1); ++i) { 35 | printf("{%c, %c} ", g1[i][0], g1[i][1]); 36 | } 37 | 38 | printf("\n"); 39 | printf("g2: "); 40 | for (i = 0; i < sizeof(g2) / sizeof(*g2); ++i) { 41 | printf("{%c, %c} ", g2[i][0], g2[i][1]); 42 | } 43 | 44 | printf("\n"); 45 | } 46 | 47 | typedef const char S[]; 48 | 49 | static void test4(void) 50 | { 51 | S s1 = "Hello world", s2 = {'h', 'i', '\0'}; 52 | 53 | printf("%s, %lu\n", s1, sizeof(s1)); 54 | printf("%s, %lu\n", s2, sizeof(s2)); 55 | } 56 | 57 | int main(void) 58 | { 59 | test1(); 60 | test2(); 61 | test3(); 62 | test4(); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /test/c89/typedef.c: -------------------------------------------------------------------------------- 1 | int puts(const char *s); 2 | int printf(const char *, ...); 3 | 4 | typedef unsigned int foo_t; 5 | 6 | const char typedef *strptr; 7 | 8 | const char *string = "Hello world!"; 9 | 10 | typedef void eat_function_t (int n); 11 | 12 | typedef eat_function_t cookie_eat_function_t; 13 | 14 | static void eat_cookie(int n) { 15 | while (n-->0) { 16 | printf("nom"); 17 | } 18 | } 19 | 20 | static int eat_cookies(void) { 21 | eat_function_t *f1 = eat_cookie; 22 | cookie_eat_function_t *f2 = eat_cookie; 23 | 24 | eat_cookie(1); 25 | f1(2); 26 | f2(3); 27 | 28 | return 0; 29 | } 30 | 31 | int main(void) { 32 | foo_t retcode; 33 | strptr sp; 34 | 35 | sp = string; 36 | puts(sp); 37 | 38 | eat_cookies(); 39 | 40 | retcode = 0; 41 | return retcode; 42 | } 43 | -------------------------------------------------------------------------------- /test/c89/unary-minus-float.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | float g, i = 0; 4 | double h, j = 0; 5 | 6 | int main(void) { 7 | g = (-i); 8 | h = (-j); 9 | return printf("%f, %f\n", g, h); 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/unary-plus.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | float g; 4 | long h = 18446744073709551615UL; 5 | char c = 'H'; 6 | 7 | int main(void) { 8 | g = +(0 * (float) h); 9 | return printf("%f, %lu\n", g, sizeof(+c)); 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/union-bitfield.c: -------------------------------------------------------------------------------- 1 | union flags { 2 | signed a : 13; 3 | const signed b : 1; 4 | unsigned long c; 5 | }; 6 | 7 | union { 8 | long f0; 9 | signed f1 : 9; 10 | } g = {1L}; 11 | 12 | int main(void) { 13 | union flags f = {2}; 14 | return f.b + f.c + g.f1; 15 | } 16 | -------------------------------------------------------------------------------- /test/c89/union-float-assign.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | union U { 4 | float f0; 5 | } foo; 6 | 7 | static union U *bar = &foo; 8 | 9 | int main(void) { 10 | union U w = {3.14f}; 11 | *bar = w; 12 | return printf("%f\n", foo.f0); 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/union-float-param.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | union obj { 4 | float f; 5 | } g = {42.5678f}; 6 | 7 | int foo(union obj v) { 8 | float *p = &v.f; 9 | return printf("%f\n", *p); 10 | } 11 | 12 | int main(void) { 13 | return foo(g); 14 | } 15 | -------------------------------------------------------------------------------- /test/c89/union-zero-init.c: -------------------------------------------------------------------------------- 1 | struct obj { 2 | int mem; 3 | union either { 4 | signed char i; 5 | unsigned int u; 6 | } d; 7 | }; 8 | 9 | struct obj data = {1}; 10 | 11 | int main(void) { 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/c89/union.c: -------------------------------------------------------------------------------- 1 | union foo { 2 | int a; 3 | long b; 4 | }; 5 | 6 | int main() { 7 | union foo bar; 8 | bar.a = 1; 9 | bar.b = 8; 10 | return sizeof(bar) + sizeof(union foo) + bar.a + bar.b; 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/unsigned-compare-ge.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | char c = 0xff; 3 | unsigned int d = 4; 4 | 5 | return c >= d; 6 | } 7 | -------------------------------------------------------------------------------- /test/c89/unsigned-compare.c: -------------------------------------------------------------------------------- 1 | int g = -1L; 2 | unsigned char i = 0; 3 | 4 | int main () { 5 | unsigned char c = 0xff; 6 | int d = -1; 7 | return (c == d) + (i >= g); 8 | } 9 | -------------------------------------------------------------------------------- /test/c89/unsigned-sign-extend.c: -------------------------------------------------------------------------------- 1 | int putchar(int c); 2 | 3 | int main(void) { 4 | char *data = "Hello World!", *ptr; 5 | int offset = 4; 6 | int diff = -2; 7 | 8 | ptr = data + offset + diff - diff; 9 | 10 | return putchar(*ptr); 11 | } 12 | -------------------------------------------------------------------------------- /test/c89/vararg-branch.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static void check(const char *start, ...) 5 | { 6 | const char *key; 7 | va_list ap; 8 | 9 | va_start(ap, start); 10 | while ((key = va_arg(ap, const char *))) { 11 | if (va_arg(ap, int)) { 12 | printf("%s\n", key); 13 | } else { 14 | printf("not %s\n", key); 15 | } 16 | } 17 | 18 | va_end(ap); 19 | } 20 | 21 | int main(void) { 22 | check("foo", "a", 1, "b", 0, NULL); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /test/c89/vararg-complex-1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Complex enough to be passed on stack. */ 4 | struct object { 5 | char u; 6 | long a, b, c, d; 7 | short v; 8 | }; 9 | 10 | /* Take n integer arguments, except that the third is of type struct object. */ 11 | struct object sum(int n, struct object obj, ...) 12 | { 13 | int value = 0, i; 14 | va_list args; 15 | 16 | obj.u = 'g'; 17 | obj.a = 12; 18 | 19 | va_start(args, obj); 20 | for (i = 0; i < n; ++i) { 21 | if (i == 2) { 22 | struct object u = va_arg(args, struct object); 23 | obj.c = u.u + u.a + u.b + u.c + u.d + u.v; 24 | } else { 25 | value += va_arg(args, int); 26 | } 27 | } 28 | va_end(args); 29 | 30 | obj.d = value + obj.d; 31 | return obj; 32 | } 33 | 34 | int main() { 35 | struct object obj = {'a', 1, 2, 3, 4, 5}; 36 | struct object arg = {'b', 6, 5, 8, 9, 3}; 37 | obj = sum(7, obj, 10, 8, arg, 42, 2, 3, 4); 38 | return obj.u + obj.a + obj.b + obj.c + obj.d + obj.v; 39 | } 40 | -------------------------------------------------------------------------------- /test/c89/vararg-complex-2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Passed on stack. */ 4 | struct object { 5 | long a, b, c, d; 6 | }; 7 | 8 | /* Needs two registers. */ 9 | struct point { 10 | char tag; 11 | int x, y; 12 | }; 13 | 14 | struct object sum(int n, struct object obj, ...) 15 | { 16 | int value = 0, i; 17 | va_list args; 18 | 19 | va_start(args, obj); 20 | for (i = 0; i < n; ++i) { 21 | if (i < 3) { 22 | value += va_arg(args, int); 23 | } else { 24 | struct point p = va_arg(args, struct point); 25 | value += p.x + p.y; 26 | } 27 | } 28 | va_end(args); 29 | 30 | obj.a = value; 31 | return obj; 32 | } 33 | 34 | int main() { 35 | struct point u = {'u', 2, 3}; 36 | struct point v = {'v', 5, 6}; 37 | struct object obj = {0}; 38 | obj = sum(5, obj, 8, 9, 8, u, v); 39 | return obj.a + obj.b + obj.c + obj.d; 40 | } 41 | -------------------------------------------------------------------------------- /test/c89/vararg-deref-arg.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | struct point { 6 | int y[2]; 7 | } p; 8 | 9 | static void test(struct point *p, ...) 10 | { 11 | va_list args; 12 | va_start(args, p); 13 | 14 | p->y[0] = va_arg(args, int); 15 | p->y[1] = va_arg(args, int); 16 | 17 | va_end(args); 18 | } 19 | 20 | int main(void) { 21 | test(&p, 1, 2); 22 | return printf("%d, %d\n", p.y[0], p.y[1]); 23 | } 24 | -------------------------------------------------------------------------------- /test/c89/vararg-deref.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static int sum(int n, va_list *args) { 6 | int k = 0; 7 | while (n--) { 8 | k += va_arg(*args, double); 9 | } 10 | 11 | return k; 12 | } 13 | 14 | static int test(int n, ...) { 15 | va_list *args; 16 | args = malloc(sizeof(*args)); 17 | va_start(*args, n); 18 | n = sum(n, args); 19 | va_end(*args); 20 | return n; 21 | } 22 | 23 | int main(void) { 24 | return printf("%d, %d, %d\n", 25 | test(1, 4.0), 26 | test(3, 4567.0f, 124.6f, 5368.5f), 27 | test(4, 123.5, 2356.4, 5678.6, 2769.1)); 28 | } 29 | -------------------------------------------------------------------------------- /test/c89/vararg-float.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | int foo(float a, double b, ...) { 6 | double c, d, e; 7 | va_list args; 8 | va_start(args, b); 9 | 10 | c = va_arg(args, double); 11 | d = va_arg(args, double); 12 | e = va_arg(args, double); 13 | 14 | printf("a = %f, b = %f, c = %f, d = %f, e = %f\n", a, b, c, d, e); 15 | 16 | va_end(args); 17 | return d; 18 | } 19 | 20 | int main(void) { 21 | float f = 3.14f; 22 | double d = 2.71; 23 | return foo(f, d, 4.9f, 90.0, f); 24 | } 25 | -------------------------------------------------------------------------------- /test/c89/vararg-param.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int print(const char *format, va_list ap) 5 | { 6 | int n = 0, c; 7 | 8 | while ((c = *format++) != '\0') { 9 | if (c == '#') { 10 | c = va_arg(ap, int); 11 | } 12 | 13 | putchar(c); 14 | n++; 15 | } 16 | 17 | return n; 18 | } 19 | 20 | static int warning(const char *format, ...) 21 | { 22 | int n; 23 | va_list args; 24 | va_start(args, format); 25 | n = print(format, args); 26 | putchar('\n'); 27 | va_end(args); 28 | return n; 29 | } 30 | 31 | int main(void) { 32 | return warning("This # not #", 'A', 'C'); 33 | } 34 | -------------------------------------------------------------------------------- /test/c89/vararg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int sum(int n, ...) { 5 | int value = 0, i; 6 | va_list args; 7 | 8 | va_start(args, n); 9 | for (i = 0; i < n; ++i) 10 | value += va_arg(args, int); 11 | 12 | va_end(args); 13 | 14 | return value; 15 | } 16 | 17 | struct car { 18 | char a, b, c; 19 | }; 20 | 21 | int foo(int n, ...) { 22 | struct car c; 23 | va_list args; 24 | 25 | va_start(args, n); 26 | c = va_arg(args, struct car); 27 | n = c.a + c.b + c.c; 28 | va_end(args); 29 | return n; 30 | } 31 | 32 | int main(void) { 33 | struct car c = {1, 2, 3}; 34 | printf("sum: %d\n", sum(7, 10, 8, 42, 1, 2, 3, 4)); 35 | printf("car: %d\n", foo(1, c)); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /test/c89/void-statement.c: -------------------------------------------------------------------------------- 1 | static int i; 2 | 3 | int foo(void) { 4 | return i = 42; 5 | } 6 | 7 | int main(void) { 8 | (void) foo(); 9 | return i; 10 | } 11 | -------------------------------------------------------------------------------- /test/c89/whitespace.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | /* form feed, 0x0c */ 4 | 5 | int main(void) { 6 | return puts("Hello"); 7 | } 8 | -------------------------------------------------------------------------------- /test/c89/zero-init.c: -------------------------------------------------------------------------------- 1 | struct point { 2 | int x, y; 3 | }; 4 | 5 | int main(void) 6 | { 7 | static int arr[16]; 8 | static struct point p; 9 | 10 | char foo[6] = {'a', 'b', 'c'}; 11 | struct point q = {3}; 12 | 13 | return p.x + arr[2] + foo[3] + q.y; 14 | } 15 | -------------------------------------------------------------------------------- /test/c99/_Pragma.c: -------------------------------------------------------------------------------- 1 | #define INCLUDE(x) PRAGMA(include #x) 2 | #define PRAGMA(x) _Pragma(#x) 3 | 4 | _Pragma("$") 5 | _Pragma( 6 | "\t" /* 7 | Something */ 8 | ) 9 | _Pragma 10 | ("" 11 | ) 12 | 13 | int _Pragma ( "lacc \"..\\file.c\"" ) i = 42; 14 | 15 | INCLUDE ( ..\file.c ) 16 | 17 | int main(void) { 18 | return i; 19 | } 20 | -------------------------------------------------------------------------------- /test/c99/__func__.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | const char *s; 4 | 5 | int foo(void) { 6 | s = __func__; 7 | return printf("%lu\n", sizeof(__func__)); 8 | } 9 | 10 | int main(void) { 11 | const char *t = __func__; 12 | foo(); 13 | return printf("%s, %s\n", t, s); 14 | } 15 | -------------------------------------------------------------------------------- /test/c99/array-param-qualifier.c: -------------------------------------------------------------------------------- 1 | 2 | int foo(int a[restrict], int b[const], int c[restrict const]) { 3 | return *a + *b + *c; 4 | } 5 | 6 | int main(void) { 7 | int arr[] = {1, 2, 3}; 8 | return foo(arr, arr + 1, arr + 2); 9 | } 10 | -------------------------------------------------------------------------------- /test/c99/array-qualifier-static.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int foo(int a[static const 1][2]) { 4 | int bar(int b[restrict volatile static 2]); 5 | return bar(a[0]); 6 | } 7 | 8 | int bar(int * volatile a) { 9 | return printf("[%d, %d]\n", a[0], a[1]); 10 | } 11 | 12 | static int arr[][2] = { 13 | {1, 2}, 14 | {3, 4}, 15 | {5, 6} 16 | }; 17 | 18 | int main(void) { 19 | return foo(arr); 20 | } 21 | -------------------------------------------------------------------------------- /test/c99/bool-return.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | bool is_interesting(char c) { 5 | switch (c) { 6 | case 'a': 7 | return false; 8 | case 'b': 9 | return true; 10 | default: 11 | return 1; 12 | } 13 | } 14 | 15 | int main(void) { 16 | assert(!is_interesting('a')); 17 | assert(is_interesting('b')); 18 | } 19 | -------------------------------------------------------------------------------- /test/c99/bool.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | _Bool f = (bool)127; 6 | 7 | struct A { 8 | _Bool a : 1; 9 | bool b : 1; 10 | } a1 = {2, 1}; 11 | 12 | struct B { 13 | _Bool a : 1; 14 | unsigned b : 4; 15 | _Bool c : 1; 16 | } b1 = {12341L}; 17 | 18 | struct C { 19 | _Bool a : 1; 20 | unsigned b : 20; 21 | bool c : 1; 22 | } c1 = {0, 0, 2.31f}; 23 | 24 | static void values(_Bool arr[]) { 25 | printf("arr: %d\n", arr[0]); 26 | printf("a1: {%d, %d}\n", a1.a, a1.b); 27 | printf("b1: {%d, %d, %d}\n", b1.a, b1.b, b1.c); 28 | printf("c1: {%d, %d, %d}\n", c1.a, c1.b, c1.c); 29 | } 30 | 31 | static void sizes(_Bool b) { 32 | printf("sizes: %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu\n", 33 | sizeof(b), 34 | sizeof(b + 1), 35 | sizeof(_Bool), 36 | sizeof(struct {_Bool a;}), 37 | sizeof(struct {_Bool a : 1;}), 38 | sizeof(union { bool a : 1; bool b : 1;}), 39 | sizeof(struct A), 40 | sizeof(struct B), 41 | sizeof(struct C)); 42 | } 43 | 44 | static void branches(void) { 45 | const _Bool b = true; 46 | bool c = false; 47 | 48 | if (b && c) { 49 | printf("1\n"); 50 | } 51 | if (b == 2) { 52 | printf("2\n"); 53 | } 54 | if (!!b) { 55 | printf("3\n"); 56 | } 57 | } 58 | 59 | int main(void) { 60 | values(&f); 61 | sizes(f); 62 | branches(); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /test/c99/compund-literal.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int *a = (int []) {1, 2, 3, 4, 5}, 4 | *b = &(&((int []) {1, 2, 3, 4, 5}[2]))[1]; 5 | 6 | struct point { 7 | int x, y; 8 | }; 9 | 10 | int draw(struct point p) { 11 | return printf("(%d, %d)\n", p.x, p.y); 12 | } 13 | 14 | int main(void) { 15 | struct point 16 | p = (struct point) {5, 7}, 17 | *q = &(struct point) {3, 14}; 18 | 19 | (((struct point) {.y = 3})) = (struct point) {.x = 2} = *q; 20 | ((struct point) {0}).y = 42; 21 | 22 | draw(p); 23 | draw(*q); 24 | draw((struct point) {.y = 1}); 25 | draw((const struct point) { 0 }); 26 | draw((const struct point[]) {[1] = {.y = 5, .x = 42}}[1]); 27 | 28 | return printf("%d, %d\n", *a, *b); 29 | } 30 | -------------------------------------------------------------------------------- /test/c99/designator-array.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int a[2][3] = {[1] = {1, 2, 3}, [0][1] = 1}, 4 | b[2][3] = {[1][0] = 4, 3, 2}, 5 | c[2][3] = {4, [1] = 7, 9}, 6 | d[2][3] = {{1, 2, 3}, [0] = 2, [1][1] = 7}; 7 | 8 | int p1(int a[][3]) { 9 | return printf("{{%d, %d, %d}, {%d, %d, %d}}\n", 10 | a[0][0], a[0][1], a[0][2], a[1][0], a[1][1], a[1][2]); 11 | } 12 | 13 | void p2(char a[], int n) { 14 | int i; 15 | printf("{"); 16 | for (i = 0; i < n; ++i) { 17 | printf("%d", a[i]); 18 | if (i < n - 1) { 19 | printf(", "); 20 | } 21 | } 22 | printf("}\n"); 23 | } 24 | 25 | struct { 26 | char c[4]; 27 | int d; 28 | } s1 = { {1, [0] = 3, 2, 3, 4, [3] = 7}, 42 }; 29 | 30 | char s2[] = {[1] = 2, [42] = 3, [6] = 2}; 31 | 32 | int main(void) { 33 | int i; 34 | char 35 | foo[] = {'1', '8', [9] = '5', '-'}, 36 | bar[] = {[42] = 1}; 37 | 38 | p2(foo, sizeof(foo) - 1); 39 | p2(bar, sizeof(bar) - 1); 40 | 41 | printf("s1[0]: {[%d, %d, %d, %d], %d}\n", 42 | s1.c[0], s1.c[1], s1.c[2], s1.c[3], s1.d); 43 | 44 | printf("sizeof(s2) = %lu, [", sizeof(s2)); 45 | for (i = 0; i < sizeof(s2); ++i) { 46 | printf("%d", s2[i]); 47 | if (i > 0) { 48 | printf(", "); 49 | } 50 | } 51 | printf("]\n"); 52 | 53 | return p1(a) + p1(b) + p1(c) + p1(d); 54 | } 55 | -------------------------------------------------------------------------------- /test/c99/designator-struct.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct obj { 4 | int x; 5 | int y[3]; 6 | int z; 7 | } a = {.y = 4, 5, .x = 1}, 8 | b = {.y[1] = 3, 6}, 9 | c = {.z = 3, .x = 2, 5, 6, 7}; 10 | 11 | int p1(struct obj o) { 12 | return printf("{%d, {%d, %d, %d}, %d}\n", 13 | o.x, o.y[0], o.y[1], o.y[2], o.z); 14 | } 15 | 16 | struct S1 { 17 | int i; 18 | union { 19 | char c; 20 | float f; 21 | long l; 22 | }; 23 | short j; 24 | } t1 = {5, 1, 2}, 25 | t2 = {.f = 3.2f, 7,}, 26 | t3 = {0, {0}, .c = 'a', 5}; 27 | 28 | static int p2(struct S1 s) { 29 | return printf("{%d, {%d, %f, %ld}, %d}\n", s.i, s.c, s.f, s.l, s.j); 30 | } 31 | 32 | int main(void) { 33 | return p1(a) + p1(b) + p1(c) 34 | + p2(t1) + p2(t2) + p2(t3); 35 | } 36 | -------------------------------------------------------------------------------- /test/c99/designator-union.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | union value { 4 | int i; 5 | float f; 6 | } a = {.f = 3.14}, 7 | b = {8, .f = 2.71, }, 8 | c = {.i = 6}, 9 | d = {.i = 6, .i = 4, .f = 5.13}, 10 | e = {3,}; 11 | 12 | int p1(union value u) { 13 | return printf("(%d, %f)\n", u.i, u.f); 14 | } 15 | 16 | union U1 { 17 | struct S1 { 18 | int x; 19 | char y[2]; 20 | } u; 21 | union value v; 22 | } t1 = {.u = {1, 2}}, 23 | t2 = {.v = {3}}, 24 | t3 = {.v = {.f = 2.71}}, 25 | t4 = {42, 1, .v.f = 2.71}; 26 | 27 | int p2(union U1 u) { 28 | return printf("{{%d, {%d, %d}}, ", u.u.x, u.u.y[0], u.u.y[1]) + p1(u.v); 29 | } 30 | 31 | int main(void) { 32 | union value f = {.f = 0.2f}; 33 | union U1 34 | t5 = {1, .v.i = 3,}, 35 | t6 = {42, {13, 19}}, 36 | t7 = {.v.f = 4.44, .u.y[1] = 3,}; 37 | 38 | return p1(a) + p1(b) + p1(c) + p1(d) + p1(e) + p1(f) 39 | + p2(t1) + p2(t2) + p2(t3) + p2(t4) + p2(t5) + p2(t6) + p2(t7); 40 | } 41 | -------------------------------------------------------------------------------- /test/c99/flexible-array-arg.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | struct flex { 4 | int a; 5 | char b; 6 | char s[]; 7 | } foo = {1}; 8 | 9 | struct flex ret(void) { 10 | struct flex p = {3, 2}; 11 | return p; 12 | } 13 | 14 | int arg(struct flex p) { 15 | return printf("%d, %d\n", p.a, p.b); 16 | } 17 | 18 | int main(void) { 19 | struct flex p = ret(); 20 | return arg(p) + arg(foo); 21 | } 22 | -------------------------------------------------------------------------------- /test/c99/flexible-array.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct S1 { 6 | int n; 7 | double d[]; 8 | }; 9 | 10 | struct S1 *alloc(int n) { 11 | struct S1 *p = malloc(sizeof(struct S1) + sizeof(double) * n); 12 | p->n = n; 13 | return p; 14 | } 15 | 16 | int main(void) { 17 | struct S1 *s = alloc(3); 18 | 19 | s->d[0] = 41.4; 20 | s->d[1] = 3.14; 21 | s->d[2] = 2.71; 22 | 23 | return printf("%lu, %ld, (%f, %f, %f)\n", 24 | sizeof(struct S1), 25 | offsetof(struct S1, d), 26 | s->d[0], s->d[1], (*s).d[2]); 27 | } 28 | -------------------------------------------------------------------------------- /test/c99/flexible-union.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | union U1 { 4 | struct { 5 | char c; 6 | char s[]; 7 | } foo; 8 | int a; 9 | }; 10 | 11 | union U2 { 12 | int b; 13 | union U1 bar; 14 | }; 15 | 16 | union U1 test(void) { 17 | union U1 p = {3}; 18 | p.foo.s[0] = 1; 19 | p.foo.s[1] = 2; 20 | p.foo.s[2] = 3; 21 | return p; 22 | } 23 | 24 | int main(void) { 25 | union U1 p = test(); 26 | union U2 q = {0}; 27 | 28 | q.bar = p; 29 | return printf("%lu, %lu (%d, %d, %d)\n", 30 | sizeof(union U1), 31 | sizeof(union U2), 32 | q.bar.foo.s[0], q.bar.foo.s[1], q.bar.foo.s[2]); 33 | } 34 | -------------------------------------------------------------------------------- /test/c99/for-declaration.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int i = 42; 4 | 5 | int main(void) { 6 | typedef char T; 7 | T c = 'a'; 8 | printf("i = %d\n", i); 9 | for (volatile int i = 0, *j; i < 5; ++i) 10 | printf("%d ", i); 11 | 12 | for (T c;;) { 13 | c = 'b'; 14 | break; 15 | } 16 | 17 | printf("c = %d\n", c); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /test/c99/initialize-bit.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static void test1(void) { 4 | int i; 5 | struct T { 6 | const int *ptr; 7 | unsigned int 8 | foo:1, 9 | bar:1; 10 | } foo = { .bar = 1 }; 11 | 12 | for (i = 0; i < sizeof(struct T); ++i) { 13 | printf("%d ", ((char *) &foo)[i]); 14 | } 15 | 16 | printf(" (%lu)\n", sizeof(struct T)); 17 | } 18 | 19 | int main(void) { 20 | test1(); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /test/c99/initialize-compound.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int test1(void) { 4 | int a[] = {5, (int){2}}; 5 | return printf("%d, %d\n", a[0], a[1]); 6 | } 7 | 8 | static int test2(float x) { 9 | struct S { 10 | char c; 11 | float fs[3]; 12 | } s1 = (struct S) { 'a', .fs[0] = (float) { 1.4f } }; 13 | 14 | return printf("%c, {%f, %f, %f}\n", s1.c, s1.fs[0], s1.fs[1], s1.fs[2]); 15 | } 16 | 17 | int main(void) { 18 | test1(); 19 | test2(3.14f); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/c99/initialize-object.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | static int test1(void) { 4 | struct A { char text[4]; } a = {"Hei"}; 5 | struct B { int i; } b = {42}; 6 | union U { 7 | struct A a; 8 | struct B b; 9 | } u1 = {a}, 10 | u2 = {.b = b}; 11 | struct C { 12 | union U u; 13 | } s1 = {u1}, 14 | s2 = {a}, 15 | s3 = {"Oi"}; 16 | 17 | printf("%s\n", u1.a.text); 18 | printf("%d\n", u2.b.i); 19 | 20 | printf("%s\n", s1.u.a.text); 21 | printf("%s\n", s2.u.a.text); 22 | printf("%s\n", s3.u.a.text); 23 | return 0; 24 | } 25 | 26 | static int test2(void) { 27 | struct A { unsigned char data; } a = {'c'}; 28 | struct B { 29 | struct A a; 30 | int i; 31 | } b = {a, 42}; 32 | struct C { 33 | struct B b; 34 | } c = {b}; 35 | 36 | return printf("{{{%c}, %d}}\n", c.b.a.data, c.b.i); 37 | } 38 | 39 | int main(void) { 40 | return test1() + test2(); 41 | } 42 | -------------------------------------------------------------------------------- /test/c99/inline-address.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | static inline int foo(int a) { 4 | return puts("Hello"); 5 | } 6 | 7 | static inline int bar(void) { 8 | foo(42); 9 | } 10 | 11 | /* Declaring a pointer has same effect as calling, now inlines are defined. */ 12 | int (*f)(void) = &bar; 13 | 14 | static inline int baz(int a) { 15 | return a + 1; 16 | } 17 | 18 | int main(void) { 19 | return baz(2); 20 | } 21 | -------------------------------------------------------------------------------- /test/c99/inline-address.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cc=$1 4 | src=$2 5 | dir=$3 6 | $cc -c ${src}.c -o ${dir}/${src}.o || exit 1 7 | 8 | readelf -s ${dir}/${src}.o | awk ' 9 | BEGIN { missing=4; } 10 | $8 ~ /(foo|bar|baz|puts)/ { missing -= 1; } 11 | END { exit missing }'; 12 | 13 | exit $? 14 | -------------------------------------------------------------------------------- /test/c99/inline-declare.c: -------------------------------------------------------------------------------- 1 | static inline int bar(int); 2 | 3 | int foo(void) { 4 | return bar(42); 5 | } 6 | 7 | static inline int bar(int n) { 8 | return n + 1; 9 | } 10 | 11 | int main(void) { 12 | return foo(); 13 | } 14 | -------------------------------------------------------------------------------- /test/c99/inline-extern.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | /* Extern inline should produce a symbol. */ 4 | extern inline int foo(int a) { 5 | return puts("Hello"); 6 | } 7 | 8 | int main(void) { 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /test/c99/inline-extern.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cc=$1 4 | src=$2 5 | dir=$3 6 | $cc -c ${src}.c -o ${dir}/${src}.o || exit 1 7 | 8 | readelf -s ${dir}/${src}.o | awk ' 9 | BEGIN { missing=2; } 10 | $8 ~ /(foo|puts)/ { missing -= 1; } 11 | END { exit missing }'; 12 | 13 | exit $? 14 | -------------------------------------------------------------------------------- /test/c99/inline-unused.c: -------------------------------------------------------------------------------- 1 | int puts(const char *); 2 | 3 | inline int foo(int a) { 4 | /* puts should not be added to ELF symtab if foo is not called, even 5 | when foo is called from another inline function not called! 6 | */ 7 | return puts("Hello"); 8 | } 9 | 10 | static inline int bar(void) { 11 | foo(42); 12 | } 13 | 14 | int baz(int a) { 15 | return a + 1; 16 | } 17 | 18 | int main(void) { 19 | baz(2); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/c99/inline-unused.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cc=$1 4 | src=$2 5 | dir=$3 6 | $cc -c ${src}.c -o ${dir}/${src}.o || exit 1 7 | 8 | readelf -s ${dir}/${src}.o | awk ' 9 | BEGIN { wrong=0; } 10 | $8 ~ /(foo|bar|puts)/ { 11 | print "Unexpected symbol", $8; 12 | wrong += 1; 13 | } 14 | END { exit wrong }'; 15 | 16 | exit $? 17 | -------------------------------------------------------------------------------- /test/c99/line-comment.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | // Hello! 4 | // */ 5 | 6 | char *str = "a\"/*b"; 7 | char c = '"'; 8 | 9 | //\ 10 | foo(); 11 | 12 | /\ 13 | / bar(); 14 | 15 | int foo(int a, int b) { 16 | // 17 | int f = a/**//b; 18 | int g = a//**/o 19 | + b; 20 | return printf("%d, %d, %s, %s, %d\n", f, g, "w // t", str, c); 21 | } 22 | 23 | int main(void) {// \ to\do 24 | return /*//*/ foo(__LINE__ * 2, 2);; 25 | } 26 | -------------------------------------------------------------------------------- /test/c99/main-default-return.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int i = 42; 3 | } 4 | -------------------------------------------------------------------------------- /test/c99/nan-inf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int test_nan(void) { 5 | int c = 0; 6 | float fnan = strtof("NAN()", NULL); 7 | double dnan = strtod("NAN()", NULL); 8 | long double ldnan = strtold("NAN()", NULL); 9 | 10 | assert(fnan != 0); 11 | if (fnan) { 12 | c++; 13 | } else if (!fnan) { 14 | assert(0); 15 | } 16 | 17 | assert(dnan != 0); 18 | if (dnan) { 19 | c++; 20 | } else if (!dnan) { 21 | assert(0); 22 | } 23 | 24 | assert(ldnan != 0); 25 | if (ldnan) { 26 | c++; 27 | } else if (!ldnan) { 28 | assert(0); 29 | } 30 | 31 | return c == 3; 32 | } 33 | 34 | static int test_inf(void) { 35 | int c = 0; 36 | float finf = strtof("INF()", NULL); 37 | double dinf = strtod("INF()", NULL); 38 | long double ldinf = strtold("INF()", NULL); 39 | 40 | assert(finf != 0); 41 | if (finf) { 42 | c++; 43 | } else if (!finf) { 44 | assert(0); 45 | } 46 | 47 | assert(dinf != 0); 48 | if (dinf) { 49 | c++; 50 | } else if (!dinf) { 51 | assert(0); 52 | } 53 | 54 | assert(ldinf != 0); 55 | if (ldinf) { 56 | c++; 57 | } else if (!ldinf) { 58 | assert(0); 59 | } 60 | 61 | return c == 3; 62 | } 63 | 64 | int main(void) { 65 | assert(test_nan()); 66 | assert(test_inf()); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /test/c99/restrict.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | #ifdef restrict 4 | # error This is wrong 5 | #endif 6 | 7 | static int * restrict restrict restricted; 8 | 9 | int bar(int *restrict * const restrict p) { 10 | return **p; 11 | } 12 | 13 | int foo(int * restrict p) { 14 | return *p; 15 | } 16 | 17 | int main(void) { 18 | auto int n = 42; 19 | return foo(&n); 20 | } 21 | -------------------------------------------------------------------------------- /test/c99/va_copy.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int printf(const char *, ...); 4 | 5 | static int foo(int n, ...) { 6 | int i; 7 | va_list args, copy; 8 | 9 | va_start(args, n); 10 | printf("%d\n", va_arg(args, int)); 11 | va_copy(copy, args); 12 | for (i = 0; i < n - 1; ++i) { 13 | printf("%d\n", va_arg(copy, int)); 14 | } 15 | 16 | printf("%d\n", va_arg(args, int)); 17 | va_end(args); 18 | va_end(copy); 19 | return 0; 20 | } 21 | 22 | int main(void) { 23 | return foo(2, 1, 4) 24 | + foo(3, 9, 8, 6) 25 | + foo(8, 4, 5, 2, 89, 0, 71, 99, 4); 26 | } 27 | -------------------------------------------------------------------------------- /test/c99/variadic-macro.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Example adapted from C11 standard specification. */ 4 | #define debug(...) fprintf(stdout, __VA_ARGS__) 5 | #define showlist(...) puts(#__VA_ARGS__) 6 | #define report(test, ...) ((test)?puts(#test): printf(__VA_ARGS__)) 7 | 8 | int test(int x, int y) { 9 | debug("Hello World!"); 10 | debug("X = %d\n", x); 11 | showlist(The first, second, and third items.); 12 | return report(x>y, "x is %d but y is %d", x, y); 13 | } 14 | 15 | #define call(func, ...) func(__VA_ARGS__) 16 | 17 | static int empty(void) { return 42; } 18 | 19 | int main(void) { 20 | int a = call(empty); 21 | return test(a, 5) + call(test, 3, 0) + call(empty); 22 | } 23 | -------------------------------------------------------------------------------- /test/c99/vla-arg.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int foo(int n, int a[][n + 1][n]) { 4 | int b = a[0][0][0]; 5 | int c = a[0][n][n - 1]; 6 | return printf("%d, %d, %lu, %lu\n", b, c, sizeof(a[0]), sizeof(a[1][n - 1])); 7 | } 8 | 9 | int main(void) { 10 | int n = 13; 11 | int a[2][n][n - 1]; 12 | 13 | a[0][0][0] = 42; 14 | a[0][n - 1][n - 2] = 33; 15 | 16 | return foo(n - 1, a); 17 | } 18 | -------------------------------------------------------------------------------- /test/c99/vla-block-declaration.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int bar(int n) { 4 | int a[1][n]; 5 | int i = 0, foo(int n, int (*a)[n]); 6 | 7 | for (i = 0; i < n; ++i) { 8 | a[0][i] = i + 1; 9 | } 10 | 11 | return foo(n, a); 12 | } 13 | 14 | int foo(int n, int a[][n]) { 15 | while (n--) { 16 | printf("(*a)[%d] = %d\n", n, a[0][n]); 17 | } 18 | 19 | return sizeof(*a); 20 | } 21 | 22 | int main(void) { 23 | return bar(16); 24 | } 25 | -------------------------------------------------------------------------------- /test/c99/vla-compatibility.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int *foo(int n) { 4 | int (*a)[n]; 5 | int (* volatile b)[n + 1]; 6 | static int k[] = {1, 2, 3}; 7 | 8 | a = &k; 9 | b = a; 10 | return *a; 11 | } 12 | 13 | int main(void) { 14 | return printf("%d, %d\n", *foo(3), foo(5)[2]); 15 | } 16 | -------------------------------------------------------------------------------- /test/c99/vla-matrix.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | void print(int n, int m, int arr[n][m]) { 4 | int i, j; 5 | for (i = 0; i < n; ++i) { 6 | for (j = 0; j < m; ++j) { 7 | printf("[%d][%d] = %d\n", i, j, arr[i][j]); 8 | } 9 | } 10 | 11 | printf("%lu, %lu\n", sizeof(arr[0]), sizeof(*arr)); 12 | } 13 | 14 | void matrix(int n, int m) { 15 | int i, arr[n][m]; 16 | for (i = 0; i < n * m; ++i) { 17 | arr[i / m][i % m] = i; 18 | } 19 | 20 | print(n, m, arr); 21 | } 22 | 23 | int main(void) { 24 | matrix(2, 3); 25 | matrix(31, 87); 26 | matrix(17, 1); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /test/c99/vla-old-param.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | #define N 42 4 | 5 | int foo(n, a) 6 | int n; 7 | int a[][n]; 8 | { 9 | int i; 10 | for (i = 0; i < n; ++i) 11 | printf("%d: %d\n", i, a[0][i]); 12 | return n; 13 | } 14 | 15 | int main(void) { 16 | int a[2][N] = {0}, i; 17 | for (i = 0; i < N; ++i) 18 | a[0][i] = i + 1; 19 | return printf("%d\n", foo(N, a)); 20 | } 21 | -------------------------------------------------------------------------------- /test/c99/vla-pointer.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | #define M 10 4 | 5 | void print(int n, int (*arr)[n]) { 6 | int i, j; 7 | for (i = 0; i < M; ++i) { 8 | for (j = 0; j < n; ++j) { 9 | printf("[%d][%d] = %d\n", i, j, arr[i][j]); 10 | } 11 | } 12 | } 13 | 14 | void pointer(int n, int arr[][n]) { 15 | int (*p)[n], (*q)[n], (*t)[n]; 16 | 17 | p = &arr[1]; 18 | q = &arr[M - 3]; 19 | 20 | printf("diff: %ld, %ld\n", q - p, q + 1 - p); 21 | 22 | t = q - 5; 23 | (*t)[4] = 3333; 24 | t[0][n - 1] = 9127684; 25 | 26 | printf("deref: %d, %d\n", (*t)[1], (*t)[n - 3]); 27 | } 28 | 29 | void test(int n) { 30 | int i, arr[M][n]; 31 | for (i = 0; i < n * M; ++i) { 32 | arr[i / n][i % n] = i; 33 | } 34 | 35 | pointer(n, arr); 36 | print(n, arr); 37 | } 38 | 39 | int main(void) { 40 | test(17); 41 | test(31); 42 | test(5); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /test/c99/vla-sizeof.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int main(void) { 4 | int n = 42, m = 13; 5 | return printf("%lu, %lu, %lu, %lu\n", 6 | sizeof(long double [n + m]), 7 | sizeof(float *[n]), 8 | sizeof(long [n][m]), 9 | sizeof(int [n > 10 ? m + 1 : n])); 10 | } 11 | -------------------------------------------------------------------------------- /test/c99/vla-static-pointer.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int B[] = {1, 2, 3, 4, 5, 6}; 4 | 5 | int foo(int n) { 6 | int i; 7 | static int (*p)[n] = &B; 8 | for (i = 0; i < n; ++i) { 9 | (*p)[i] = n + i; 10 | } 11 | return n; 12 | } 13 | 14 | int main(void) { 15 | int i; 16 | foo(4); 17 | for (i = 0; i < sizeof(B) / sizeof(int); ++i) { 18 | printf("%d\n", B[i]); 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test/c99/vla-ternary-length.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | int foo(int n, float a[][n % 2 ? 5 : 6][n - 2]) { 4 | return printf("(%lu, %lu, %f, %f)\n", 5 | sizeof(a[0]), 6 | sizeof(a[n - 1][n + 1]), 7 | a[0][0][1], 8 | a[0][0][4]); 9 | } 10 | 11 | int main(void) { 12 | float p[][2][7] = {3.14, 3.1, 5.1, 7.24, 6.12, 8.12, 9.13}; 13 | return foo(6, p) + foo(7, p); 14 | } 15 | -------------------------------------------------------------------------------- /test/c99/vla.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | void print(unsigned n, int arr[n]) { 4 | int i; 5 | for (i = 0; i < n; ++i) { 6 | printf("%d\n", arr[i]); 7 | } 8 | } 9 | 10 | int foo(unsigned short n) { 11 | int i, a[n]; 12 | int b[n]; 13 | 14 | for (i = 0; i < n; ++i) { 15 | a[i] = i; 16 | b[i] = a[i] - i; 17 | } 18 | 19 | print(n, a); 20 | print(n, b); 21 | 22 | for (i = 0; i < n; ++i) { 23 | a[i] = a[i] + b[i]; 24 | } 25 | 26 | print(n, a); 27 | return printf("%lu\n", sizeof(a)); 28 | } 29 | 30 | int main(void) { 31 | return foo(8); 32 | } 33 | -------------------------------------------------------------------------------- /test/check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if test -t 1 4 | then 5 | colors=$(tput colors) 6 | if test -n "$colors" && test $colors -ge 8 7 | then 8 | reset="$(tput sgr0)" 9 | red="$(tput setaf 1)" 10 | green="$(tput setaf 2)" 11 | fi 12 | fi 13 | 14 | lacc="$1" 15 | file="$2" 16 | comp="$3" 17 | bdir="$4" 18 | if [ -z "$file" ] || [ ! -f "$file" ]; then 19 | echo "Usage: $0 []"; 20 | exit 1 21 | fi 22 | 23 | if [ -z "$comp" ]; then 24 | comp="gcc -std=c89 -Wno-psabi" 25 | fi 26 | 27 | if [ -z "$bdir" ]; then 28 | bdir="." 29 | fi 30 | 31 | $comp -v 2>&1 >/dev/null | grep "enable-default-pie" > /dev/null 32 | if [ "$?" -eq "0" ]; then 33 | lacc="${lacc} -fPIC" 34 | fi 35 | 36 | i=`dirname ${file}` 37 | d=`dirname ${bdir}/${file}` 38 | f=`basename ${file} .c` 39 | mkdir -p ${d} 40 | $comp $file -o ${d}/${f}.out 41 | if [ "$?" -ne "0" ]; then 42 | echo "${file}: ${red}Invalid input file!${reset}"; 43 | exit 1 44 | fi 45 | 46 | ${d}/${f}.out > ${d}/${f}.ans.txt; answer="$?" 47 | 48 | check() 49 | { 50 | $lacc $1 $file -o ${d}/${f}.s 51 | if [ "$?" -ne "0" ]; then 52 | echo "${red}Compilation failed!${reset}"; 53 | return 1 54 | fi 55 | if [ "$1" = "-E" ]; then 56 | mv ${d}/${f}.s ${d}/${f}.i 57 | $lacc -c ${d}/${f}.i -o ${d}/${f}.o 58 | if [ "$?" -ne "0" ]; then 59 | echo "${red}Compilation failed!${reset}"; 60 | return 1 61 | fi 62 | elif [ "$1" = "-S" ]; then 63 | $comp -c ${d}/${f}.s -o ${d}/${f}.o 64 | if [ "$?" -ne "0" ]; then 65 | echo "${red}Assembly failed!${reset}"; 66 | return 1 67 | fi 68 | else 69 | mv ${d}/${f}.s ${d}/${f}.o 70 | fi 71 | $comp ${d}/${f}.o -o ${d}/${f}.out -lm 72 | if [ "$?" -ne "0" ]; then 73 | echo "${red}Linking failed!${reset}"; 74 | return 1 75 | fi 76 | 77 | ${d}/${f}.out > ${d}/${f}.txt 78 | result="$?" 79 | difference=`diff ${d}/${f}.ans.txt ${d}/${f}.txt` 80 | diffres="$?" 81 | 82 | if [ "$result" -eq "$answer" ] && [ "$diffres" -eq "0" ]; then 83 | echo "${green}Ok!${reset}" 84 | return 0 85 | else 86 | echo "${red}Wrong result!${reset}" 87 | if [ "$result" -ne "$answer" ]; then 88 | echo "Result differ: was ${result}, expected ${answer}." >&2 89 | fi 90 | if [ "$diffres" -ne "0" ]; then 91 | echo "Output differ:" >&2 92 | echo "$difference" >&2 93 | fi 94 | return 1 95 | fi 96 | } 97 | 98 | prp=$(check -E); result="$?"; retval=$((retval + result)) 99 | asm=$(check -S); result="$?"; retval=$((retval + result)) 100 | elf=$(check -c); result="$?"; retval=$((retval + result)) 101 | opt=$(check "-c -O1"); result="$?"; retval=$((retval + result)) 102 | echo "[-E: ${prp}] [-S: ${asm}] [-c: ${elf}] [-c -O1: ${opt}] :: ${file}" 103 | 104 | if [ $retval -eq 0 ] && [ -f "${i}/${f}.sh" ] 105 | then 106 | ./${i}/${f}.sh "$lacc" "${i}/${f}" "${bdir}" 107 | retval=$? 108 | if [ $retval -ne 0 ] 109 | then 110 | echo "${red}Failed validation script!${reset}" 111 | fi 112 | fi 113 | 114 | rm -f ${d}/${f}.out ${d}/${f}.ans.txt ${d}/${f}.txt ${d}/${f}.s ${d}/${f}.i ${d}/${f}.o 115 | exit $retval 116 | -------------------------------------------------------------------------------- /test/csmith.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | include="/usr/include/csmith" 4 | bin=../bin 5 | 6 | command -v $bin/lacc >/dev/null 2>&1 || { 7 | echo "$bin/lacc required, run 'make'." 8 | exit 1 9 | } 10 | 11 | command -v csmith >/dev/null 2>&1 || { 12 | echo >&2 "Please install csmith." 13 | exit 1 14 | } 15 | 16 | mkdir -p csmith $bin/csmith 17 | 18 | n=0 19 | while [ true ] 20 | do 21 | n=$((n + 1)) 22 | filename="csmith/${n}.c" 23 | program="$bin/csmith/program" 24 | if [ ! -f "${filename}" ] 25 | then 26 | csmith --no-packed-struct --float > "$filename" 27 | fi 28 | 29 | gcc -w -std=c99 -I "$include" "$filename" -o "$program" 30 | if [ $? -ne 0 ] 31 | then 32 | echo "Failed to compile with gcc" 33 | exit 1 34 | fi 35 | 36 | timeout 1 "$program" > "$bin/csmith/gcc.txt" 37 | if [ $? -ne 0 ] 38 | then 39 | rm "$filename" 40 | continue 41 | fi 42 | 43 | clang -w -std=c99 -I "$include" "$filename" -o "$program" 44 | if [ $? -ne 0 ] 45 | then 46 | echo "Failed to compile with clang" 47 | exit 1 48 | fi 49 | 50 | timeout 1 "$program" > "$bin/csmith/clang.txt" 51 | if [ $? -ne 0 ] 52 | then 53 | echo "Failed to run with clang" 54 | continue 55 | fi 56 | 57 | diff "$bin/csmith/gcc.txt" "$bin/csmith/clang.txt" 58 | if [ $? -ne 0 ] 59 | then 60 | echo "Skipping test because gcc and clang differ" 61 | continue 62 | fi 63 | 64 | ./check.sh \ 65 | "$bin/lacc -w -std=c99 -I ${include}" "$filename" \ 66 | "gcc -w -std=c99 -I ${include}" \ 67 | "$bin" 68 | if [ $? -ne 0 ] 69 | then 70 | break 71 | fi 72 | done 73 | 74 | # Run test case with both compilers, and print first diff line. This 75 | # reveals which variable is the first to create a mismatched checksum. 76 | # 77 | # Manual cleanup of test.c is required before running creduce. Remove 78 | # checksum calculation of other variables, and fix lines that produce 79 | # warnings. 80 | # 81 | # check.sh "../bin/lacc -std=c99" creduce/test.c "cc -std=c99" 2> foo.out 82 | # 83 | # Modify creduce/interesting.sh to contain the new values for expected 84 | # and actual checksum, provided as input script to creduce. 85 | 86 | mkdir -p creduce 87 | $bin/lacc -std=c99 -I "$include" -w -E "$filename" -o creduce/test.c 88 | $bin/lacc -std=c99 -I "$include" -w "$filename" -o creduce/program -lm 89 | gcc -std=c99 -I "$include" "$filename" -o creduce/reference 90 | cp interesting.sh creduce 91 | creduce/program 1 > creduce/program.out 92 | creduce/reference 1 > creduce/reference.out 93 | diff --side-by-side --suppress-common-lines \ 94 | creduce/program.out creduce/reference.out | head -n 1 95 | -------------------------------------------------------------------------------- /test/docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | distro="$1" 4 | if [ -z "$distro" ] || [ ! -f test/docker/${distro}.Dockerfile ] 5 | then 6 | echo "No Dockerfile found for '${distro}'." 7 | exit 1 8 | fi 9 | 10 | mkdir -p bin/docker/${distro} 11 | cp test/docker/${distro}.Dockerfile bin/docker/${distro}/Dockerfile 12 | cp .gitignore bin/docker/${distro}/Dockerfile.dockerignore 13 | 14 | sudo DOCKER_BUILDKIT=1 docker build . -f bin/docker/${distro}/Dockerfile -t lacc_${distro} 15 | 16 | sudo docker run -it --rm lacc_${distro} 17 | -------------------------------------------------------------------------------- /test/docker/alpine.Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | FROM alpine 3 | COPY . /code 4 | RUN apk add gcc libc-dev git make ncurses 5 | WORKDIR code 6 | -------------------------------------------------------------------------------- /test/extensions/__builtin_constant_p.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define init(x) (__builtin_constant_p(x) ? x : -1) 4 | 5 | int a = 5; 6 | 7 | static int data[] = { 8 | init(3 + 9), 9 | init(8 - a), 10 | init(0 ? a : 4) 11 | }; 12 | 13 | int main(void) { 14 | assert(data[0] == 12); 15 | assert(data[1] == -1); 16 | assert(data[2] == 4); 17 | return 1; 18 | } 19 | -------------------------------------------------------------------------------- /test/extensions/alloca.c: -------------------------------------------------------------------------------- 1 | #ifdef __OpenBSD__ 2 | #include 3 | #else 4 | #include 5 | #endif 6 | #include 7 | #include 8 | 9 | static int foo(int n, const char *str) { 10 | char *data = alloca(n); 11 | memcpy(data, str, n); 12 | 13 | return printf("%s\n", data); 14 | } 15 | 16 | static const char hello[] = "Hello world!"; 17 | 18 | int main(void) { 19 | return foo(sizeof(hello), hello); 20 | } 21 | -------------------------------------------------------------------------------- /test/extensions/comma-variable-args.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define lament(msg, ...) fprintf(stdout, msg, ##__VA_ARGS__) 5 | #define whoa(msg, ...) fprintf(stdout, msg, ##__VA_ARGS__, ##__VA_ARGS__) 6 | 7 | #define TUPLE_END INT_MIN 8 | #define tuple(...) tuple_im(_, ##__VA_ARGS__, TUPLE_END) 9 | #define tuple_im(_, ...) (int[]){__VA_ARGS__} 10 | 11 | void print_tuple(int *tuple) 12 | { 13 | lament("("); 14 | for (; *tuple != TUPLE_END; tuple++) { 15 | lament("%i", *tuple); 16 | if (tuple[1] != TUPLE_END) { 17 | lament(", "); 18 | } 19 | } 20 | lament(")\n"); 21 | } 22 | 23 | int main(int argc, char **argv) 24 | { 25 | (void) argc; 26 | (void) argv; 27 | lament("hey\n"); 28 | lament("hey %s\n", "you"); 29 | whoa("whoa!\n"); 30 | whoa("whoa: %s %s\n", "whoa!"); 31 | print_tuple(tuple()); 32 | print_tuple(tuple(1)); 33 | print_tuple(tuple(1, 2, 3)); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /test/extensions/keywords.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | static __inline void foo(char * __restrict p, char * __restrict__ q) { 5 | unsigned char x = (unsigned char) 0xff; 6 | __signed char a = (__signed__ char) x; 7 | 8 | assert(a == -1); 9 | assert(p != q); 10 | } 11 | 12 | char text[] = "Hello world!"; 13 | char * __volatile p = text, * __volatile__ q = text + 3; 14 | 15 | int main(void) { 16 | foo(p, q); 17 | return 0; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /test/extensions/variadic-macro-alias.c: -------------------------------------------------------------------------------- 1 | int printf(const char *, ...); 2 | 3 | #define out(msg, args...) printf(msg, args) 4 | 5 | int main(void) { 6 | out("%s", "Hello"); 7 | out("%c %s\n", ',', "World!"); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /test/interesting.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Interestingness script, to be supplied creduce together with the file 4 | # being reduced. Should return 0 if case is interesting, non-zero 5 | # otherwise. 6 | # 7 | # creduce ./interesting.sh test.c 8 | # 9 | # We are interested in catching wrong code generation bugs, which are 10 | # the hardest to get to the bottom to from just reading csmith generated 11 | # code. 12 | # 13 | # For best results, remove any unnecessary crc calculation for variables 14 | # that do not contribute to the wrong result. 15 | 16 | filename="test.c" 17 | 18 | # Replace these values, with output from correct compilation and faulty 19 | # lacc compilation. 20 | expect="checksum = 83CE8DDE" 21 | actual="checksum = ADF8FC99" 22 | 23 | # Give up after a couple of seconds. Reduced code can contain infinite 24 | # loops. 25 | ulimit -t 2 26 | 27 | # See that the file is still compilable. Make sure it has no screaming 28 | # warnings to avoid some undefined behavior. 29 | gcc -std=c99 "$filename" -o test > /dev/null 2> error.txt && ! grep "warning" error.txt 30 | if [ $? -ne 0 ] 31 | then 32 | exit 1 33 | fi 34 | 35 | # Get expected output from cc 36 | ./test > test.txt && grep "$expect" test.txt > /dev/null 2>&1 37 | if [ $? -ne 0 ] 38 | then 39 | exit 1 40 | fi 41 | 42 | # Get expected output from clang also, to avoid some cases of undefined 43 | # behavior that may be treated the same for gcc and lacc. 44 | clang -std=c99 -w "$filename" -o test > /dev/null 45 | ./test > test.txt && grep "$expect" test.txt > /dev/null 2>&1 46 | if [ $? -ne 0 ] 47 | then 48 | exit 1 49 | fi 50 | 51 | # Try to compile with lacc 52 | lacc -std=c99 "$filename" -o test -lm > /dev/null 53 | if [ $? -ne 0 ] 54 | then 55 | exit 1 56 | fi 57 | 58 | # Get output from lacc 59 | ./test > test.txt && grep "$actual" test.txt > /dev/null 2>&1 60 | -------------------------------------------------------------------------------- /test/limits/large-objects.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int printf(const char *, ...); 6 | 7 | #define SIZE (1UL << 61) 8 | 9 | struct S { 10 | short buf[SIZE]; 11 | int a; 12 | int b; 13 | }; 14 | 15 | union U { 16 | int a; 17 | char buf[SIZE]; 18 | }; 19 | 20 | int main(void) { 21 | assert(sizeof(struct S) == 4611686018427387912); 22 | assert(sizeof(union U) == 2305843009213693952); 23 | assert(offsetof(struct S, a) == 4611686018427387904); 24 | assert(offsetof(struct S, b) == 4611686018427387908); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /test/linker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if test -t 1 4 | then 5 | colors=$(tput colors) 6 | if test -n "$colors" && test $colors -ge 8 7 | then 8 | reset="$(tput sgr0)" 9 | red="$(tput setaf 1)" 10 | green="$(tput setaf 2)" 11 | fi 12 | fi 13 | 14 | lacc="$1" 15 | if [ -z "$lacc" ] 16 | then 17 | lacc=../bin/lacc 18 | command -v $lacc >/dev/null 2>&1 || { 19 | echo "$lacc required, run 'make'." 20 | exit 1 21 | } 22 | fi 23 | 24 | # Default should be a.out in current directory 25 | rm -f a.out 26 | $lacc linker/foo.c linker/bar.c 27 | if [ $? -ne 0 ] || [ ! -e a.out ] 28 | then 29 | echo "${red}Failed to produce default output a.out!${reset}"; 30 | return 1 31 | fi 32 | rm a.out 33 | 34 | bin=../bin/test/linker 35 | mkdir -p $bin 36 | 37 | # Target is always the same 38 | cc linker/foo.c linker/bar.c -o $bin/a.out 39 | expected=$($bin/a.out 1 2 3) 40 | 41 | check() 42 | { 43 | if [ $? -ne 0 ] 44 | then 45 | echo "${red}Compilation failed!${reset}"; 46 | return 1 47 | fi 48 | 49 | if [ ! -f "$bin/$1" ] 50 | then 51 | echo "${red}Did not create $1!${reset}"; 52 | return 1 53 | fi 54 | 55 | actual=$(LD_LIBRARY_PATH=$bin $bin/$1 1 2 3) 56 | 57 | if [ "$expected" != "$actual" ] 58 | then 59 | echo "${red}Wrong output!${reset}"; 60 | return 1 61 | fi 62 | 63 | echo "${green}Ok!${reset}" 64 | return 0 65 | } 66 | 67 | $lacc -fno-PIC linker/foo.c linker/bar.c -o $bin/a.out 68 | a=$(check "a.out"); result="$?"; retval=$((retval + result)) 69 | 70 | $lacc -fPIC linker/foo.c linker/bar.c -o $bin/foo 71 | b=$(check "foo"); result="$?"; retval=$((retval + result)) 72 | 73 | # Shared library 74 | $lacc -shared -fPIC linker/foo.c -o $bin/libfoo.so 75 | $lacc linker/bar.c -lfoo -L$bin -o $bin/a.out 76 | c=$(check "a.out"); result="$?"; retval=$((retval + result)) 77 | 78 | echo "[-fno-PIC: ${a}] [-fPIC: ${b}] [-shared: ${c}]" 79 | rm -f foo.o bar.o 80 | exit $retval 81 | -------------------------------------------------------------------------------- /test/linker/bar.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int foo(int n); 4 | 5 | int bar; 6 | 7 | int main(int argc, char *argv[]) { 8 | int n; 9 | 10 | bar = argc; 11 | while (argc-- > 1) { 12 | n = atoi(argv[argc]); 13 | foo(n); 14 | } 15 | 16 | return bar; 17 | } 18 | -------------------------------------------------------------------------------- /test/linker/foo.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int bar; 4 | 5 | int foo(int n) { 6 | bar++; 7 | return printf("%d\n", n); 8 | } 9 | -------------------------------------------------------------------------------- /test/sqlite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if test -t 1 4 | then 5 | colors=$(tput colors) 6 | if test -n "$colors" && test $colors -ge 8 7 | then 8 | reset="$(tput sgr0)" 9 | red="$(tput setaf 1)" 10 | green="$(tput setaf 2)" 11 | fi 12 | fi 13 | 14 | lacc="$1" 15 | if [ -z "$lacc" ] 16 | then 17 | lacc=../bin/lacc 18 | command -v $lacc >/dev/null 2>&1 || { 19 | echo "$lacc required, run 'make'." 20 | exit 1 21 | } 22 | fi 23 | 24 | if [ ! -f sqlite/shell.c ] || [ ! -f sqlite/sqlite3.c ] 25 | then 26 | echo "Missing sqlite source, download and place in 'test/sqlite' folder." 27 | exit 1 28 | fi 29 | 30 | bin=../bin/test/sqlite 31 | mkdir -p $bin 32 | 33 | # Build with lacc 34 | valgrind --leak-check=full --show-leak-kinds=all \ 35 | $lacc -std=c89 -fPIC -g -v -o $bin/program \ 36 | sqlite/shell.c sqlite/sqlite3.c \ 37 | -DSQLITE_DEBUG \ 38 | -DSQLITE_MEMDEBUG \ 39 | --dump-symbols \ 40 | --dump-types \ 41 | -lm -lpthread -ldl \ 42 | > /dev/null 43 | 44 | if [ $? -ne 0 ] 45 | then 46 | echo "${red}Compilation failed!${reset}"; 47 | exit 1 48 | fi 49 | 50 | rm shell.o sqlite3.o 51 | 52 | # Build with reference compiler 53 | cc sqlite/shell.c sqlite/sqlite3.c -o $bin/reference -lm -lpthread -ldl 54 | 55 | # Test case 56 | input=$(cat < 2 | 3 | int h; 4 | float g; 5 | 6 | int main(void) { 7 | h = (g = 0x7B5p46); 8 | 9 | assert(h == -2147483648); 10 | 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/undefined/cast-float-overflow.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int float_to_unsigned(void) { 5 | unsigned char 6 | float_char_of = (unsigned char) 289.0f, 7 | float_char_uf = (unsigned char) -41.0f, 8 | double_char_of = (unsigned char) 289.0, 9 | double_char_uf = (unsigned char) -41.0; 10 | unsigned short 11 | float_short_of = (unsigned short) 2234589.0f, 12 | float_short_uf = (unsigned short) -41.0f, 13 | double_short_of = (unsigned short) 2234589.0, 14 | double_short_uf = (unsigned short) -41.0; 15 | unsigned int 16 | float_int_of = (unsigned int) 5678134124.1f, 17 | float_int_uf = (unsigned int) -41.0f, 18 | double_int_of = (unsigned int) 5678134124.1, 19 | double_int_uf = (unsigned int) -41.0; 20 | unsigned long 21 | float_long_of = (unsigned long) 4.1e24f, 22 | float_long_uf = (unsigned long) -41.0f, 23 | double_long_of = (unsigned long) 4.1e24, 24 | double_long_uf = (unsigned long) -41.0; 25 | 26 | assert(float_char_of == 33); 27 | assert(float_char_uf == 215); 28 | assert(double_char_of == 33); 29 | assert(double_char_uf == 215); 30 | 31 | assert(float_short_of == 6365); 32 | assert(float_short_uf == 65495); 33 | assert(double_short_of == 6365); 34 | assert(double_short_uf == 65495); 35 | 36 | assert(float_int_of == 1383166976); 37 | assert(float_int_uf == 4294967255); 38 | assert(double_int_of == 1383166828); 39 | assert(double_int_uf == 4294967255); 40 | 41 | assert(float_long_of == 0); 42 | assert(float_long_uf == 18446744073709551575ul); 43 | assert(double_long_of == 0); 44 | assert(double_long_uf == 18446744073709551575ul); 45 | 46 | return 0; 47 | } 48 | 49 | static int float_to_signed(void) { 50 | char 51 | float_char_of = (char) 160.0f, 52 | float_char_uf = (char) -160.0f, 53 | double_char_of = (char) 160.0, 54 | double_char_uf = (char) -160.0; 55 | short 56 | float_short_of = (short) 2234589.0f, 57 | float_short_uf = (short) -2234589.0f, 58 | double_short_of = (short) 2234589.0, 59 | double_short_uf = (short) -2234589.0; 60 | int 61 | float_int_of = (int) 5678134124.1f, 62 | float_int_uf = (int) -5678134124.0f, 63 | double_int_of = (int) 5678134124.1, 64 | double_int_uf = (int) -5678134124.0; 65 | long 66 | float_long_of = (long) 4.1e24f, 67 | float_long_uf = (long) -4.1e24f, 68 | double_long_of = (long) 4.1e24, 69 | double_long_uf = (long) -4.1e24; 70 | 71 | assert(float_char_of == -96); 72 | assert(float_char_uf == 96); 73 | assert(double_char_of == -96); 74 | assert(double_char_uf == 96); 75 | 76 | assert(float_short_of == 6365); 77 | assert(float_short_uf == -6365); 78 | assert(double_short_of == 6365); 79 | assert(double_short_uf == -6365); 80 | 81 | assert(float_int_of == -2147483648); 82 | assert(float_int_uf == -2147483648); 83 | assert(double_int_of == -2147483648); 84 | assert(double_int_uf == -2147483648); 85 | 86 | assert(LONG_MIN == -9223372036854775807 - 1); 87 | assert(float_long_of == LONG_MIN); 88 | assert(float_long_uf == LONG_MIN); 89 | assert(double_long_of == LONG_MIN); 90 | assert(double_long_uf == LONG_MIN); 91 | 92 | return 0; 93 | } 94 | 95 | int main(void) { 96 | return float_to_unsigned() + float_to_signed(); 97 | } 98 | -------------------------------------------------------------------------------- /test/undefined/float-divide-zero.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | float a = 1.0/0.0; 6 | float b = (0.0/0.0) / 0.0; 7 | float c = (2.1/-0.0) / 0.0; 8 | float d = 0.0 / (2.1/0.0); 9 | float e = 1.0 / (2.1/-0.0); 10 | 11 | static char str[128]; 12 | 13 | int main(void) { 14 | sprintf(str, "a = %f, b = %f, c = %f, d = %f, e = %f", a, b, c, d, e); 15 | 16 | assert(!strcmp("a = inf, b = -nan, c = -inf, d = 0.000000, e = -0.000000", str)); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /test/undefined/long-double-convert.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long double 4 | x = 3.14, 5 | y = 145260912182745.12486L, 6 | z = -972316.70L; 7 | 8 | int main(void) { 9 | char a; 10 | unsigned char b; 11 | int c; 12 | unsigned int d; 13 | long e; 14 | unsigned long f; 15 | float g; 16 | double h; 17 | 18 | (a = x), assert(a == 3); 19 | (b = x), assert(b == 3); 20 | (c = x), assert(c == 3); 21 | (d = x), assert(d == 3); 22 | (e = x), assert(e == 3); 23 | (f = x), assert(f == 3); 24 | (g = x), assert(g == 3.14f); 25 | (h = x), assert(h == 3.14); 26 | 27 | (a = y), assert(a == 0); 28 | (b = y), assert(b == 0); 29 | (c = y), assert(c == -2147483648); 30 | (d = y), assert(d == 823264729); 31 | (e = y), assert(e == 145260912182745); 32 | (f = y), assert(f == 145260912182745); 33 | (g = y), assert(g == 145260911001600.000000f); 34 | (h = y), assert(h == 145260912182745.125000); 35 | 36 | (a = z), assert(a == 0); 37 | (b = z), assert(b == 0); 38 | (c = z), assert(c == -972316); 39 | (d = z), assert(d == 4293994980); 40 | (e = z), assert(e == -972316); 41 | (f = z), assert(f == 18446744073708579300ul); 42 | (g = z), assert(g == -972316.687500f); 43 | (h = z), assert(h == -972316.700000); 44 | 45 | return 0; 46 | } 47 | --------------------------------------------------------------------------------