├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── LICENSE-UNICODE ├── README.md ├── build.zig ├── build.zig.zon ├── build └── GenerateDef.zig ├── deps └── zig │ ├── arch │ └── x86_64 │ │ ├── Disassembler.zig │ │ ├── Encoding.zig │ │ ├── Lower.zig │ │ ├── Mir.zig │ │ ├── abi.zig │ │ ├── bits.zig │ │ ├── encoder.zig │ │ └── encodings.zig │ ├── lib.zig │ └── register_manager.zig ├── include ├── float.h ├── iso646.h ├── limits.h ├── stdalign.h ├── stdarg.h ├── stdatomic.h ├── stdbool.h ├── stdckdint.h ├── stddef.h ├── stdint.h ├── stdnoreturn.h └── varargs.h ├── src ├── aro.zig ├── aro │ ├── Attribute.zig │ ├── Attribute │ │ └── names.def │ ├── Builtins.zig │ ├── Builtins │ │ ├── Builtin.def │ │ ├── Properties.zig │ │ ├── TypeDescription.zig │ │ └── eval.zig │ ├── CodeGen.zig │ ├── Compilation.zig │ ├── Diagnostics.zig │ ├── Driver.zig │ ├── Driver │ │ ├── Distro.zig │ │ ├── Filesystem.zig │ │ ├── GCCDetector.zig │ │ ├── GCCVersion.zig │ │ └── Multilib.zig │ ├── Hideset.zig │ ├── InitList.zig │ ├── LangOpts.zig │ ├── Parser.zig │ ├── Parser │ │ └── Diagnostic.zig │ ├── Pragma.zig │ ├── Preprocessor.zig │ ├── Preprocessor │ │ └── Diagnostic.zig │ ├── Source.zig │ ├── StringInterner.zig │ ├── SymbolStack.zig │ ├── Tokenizer.zig │ ├── Toolchain.zig │ ├── Tree.zig │ ├── Tree │ │ └── number_affixes.zig │ ├── TypeStore.zig │ ├── Value.zig │ ├── annex_g.zig │ ├── char_info.zig │ ├── char_info │ │ └── identifier_tables.zig │ ├── features.zig │ ├── pragmas │ │ ├── gcc.zig │ │ ├── message.zig │ │ ├── once.zig │ │ └── pack.zig │ ├── record_layout.zig │ ├── target.zig │ ├── text_literal.zig │ ├── toolchains │ │ └── Linux.zig │ └── tracy.zig ├── assembly_backend.zig ├── assembly_backend │ └── x86_64.zig ├── backend.zig ├── backend │ ├── Assembly.zig │ ├── CodeGenOptions.zig │ ├── Interner.zig │ ├── Ir.zig │ ├── Ir │ │ └── x86 │ │ │ └── Renderer.zig │ ├── Object.zig │ └── Object │ │ └── Elf.zig └── main.zig └── test ├── README.MD ├── cases ├── #elifdef.c ├── #elifndef error.c ├── #elifndef.c ├── #embed.c ├── #if constant expression.c ├── #if expression error.c ├── #if expression macro ws.c ├── #ifdef.c ├── #pragma pack clang.c ├── #pragma pack gcc.c ├── #pragma pack msvc.c ├── #pragma pack.c ├── X macro.c ├── _BitInt change size.c ├── _BitInt min max.c ├── _BitInt.c ├── _Float16.c ├── __VA_OPT__.c ├── __auto_type self init.c ├── __auto_type.c ├── __builtin_types_compatible_p.c ├── __float80 clang.c ├── __float80.c ├── __func__.c ├── __has_attribute with define.c ├── __has_attribute.c ├── __has_builtin.c ├── __has_extension.c ├── __has_feature.c ├── __has_include.c ├── __has_warning.c ├── __is_identifier.c ├── __line__.c ├── address of label.c ├── adjust diagnostic levels.c ├── alignment.c ├── alloc_align attribute.c ├── allow fp16 parameter.c ├── alternate spellings for signed.c ├── anonymous attributed field.c ├── anonymous_struct_ms.c ├── anonymous_struct_no-ms.c ├── arithmetic conversion floats.c ├── arithmetic overflow.c ├── array argument is null.c ├── array argument too small.c ├── array designator too large.c ├── array of invalid.c ├── array of zero size type.c ├── array subscript with string.c ├── asm.c ├── assembly invalid token.c ├── assignment.c ├── ast │ ├── _Float16.c │ ├── __float80.c │ ├── atomic.c │ ├── attributed record fields.c │ ├── c23 auto.c │ ├── c23 true false ast.c │ ├── cast kinds.c │ ├── complex init.c │ ├── decayed attributed array.c │ ├── enum sizes linux.c │ ├── float eval method.c │ ├── for decl stmt.c │ ├── forever stmt.c │ ├── generic ast.c │ ├── msvc attribute keywords.c │ ├── native half type.c │ ├── nullability.c │ ├── promotion edge cases.c │ ├── stdckdint_ast.c │ ├── switch unsigned int.c │ ├── typeof_unqual.c │ ├── types.c │ └── vectors.c ├── atomic builtins.c ├── atomic.c ├── attribute errors.c ├── attributed anonymous record.c ├── attributed record fields.c ├── attributed typeof.c ├── attributes.c ├── avr sizeof long.c ├── basic math.c ├── binary expressions.c ├── binary literal.c ├── bitfields.c ├── builtin choose expr.c ├── builtin functions.c ├── builtin headers.c ├── builtin macro errors.c ├── c17 char8_t enabled.c ├── c17 char8_t.c ├── c23 attributes.c ├── c23 auto.c ├── c23 char8_t disabled.c ├── c23 char8_t.c ├── c23 defines.c ├── c23 digit separators.c ├── c23 identifiers.c ├── c23 keywords.c ├── c23 missing type specifier.c ├── c23 static_assert.c ├── c23 stdarg.c ├── c23 stdint.c ├── c23 true false ast.c ├── c89 standard.c ├── c99 standard.c ├── call undeclared function with invalid type.c ├── call.c ├── cast kinds.c ├── cast to union.c ├── casts.c ├── char literal sign extension.c ├── colon after #embed.c ├── comma operator.c ├── comment after define.c ├── complex float16.c ├── complex init.c ├── complex numbers clang.c ├── complex numbers gcc.c ├── complex values.c ├── compound literals.c ├── compound stmt fallthrough.c ├── concat improperly encoded strings.c ├── const decl folding.c ├── constexpr.c ├── containers.c ├── convertvector.c ├── darwin __float128.c ├── debug dump macro names.c ├── debug dump macros and results.c ├── debug dump macros.c ├── decayed attributed array.c ├── declspec.c ├── deferred macro expansion.c ├── deprecated vars.c ├── deref void.c ├── designated_init.c ├── digraph pretty print.c ├── digraphs disabled.c ├── digraphs enabled.c ├── digraphs not supported.c ├── digraphs.c ├── divide by zero.c ├── dollars in identifiers.c ├── double long.c ├── duplicate typedef.c ├── empty computed include.c ├── empty macro block expansion.c ├── empty records.c ├── empty va args comma delete c99.c ├── empty.c ├── enum attributes clang.c ├── enum attributes gcc.c ├── enum fixed _BitInt.c ├── enum fixed.c ├── enum overflow.c ├── enum pointer.c ├── enum sizes linux.c ├── enum sizes windows.c ├── enumerator constants.c ├── expanded │ ├── #elifdef.c │ ├── #elifndef error.c │ ├── #elifndef.c │ ├── #if constant expression.c │ ├── #ifdef.c │ ├── X macro.c │ ├── __VA_OPT__.c │ ├── __has_attribute with define.c │ ├── __line__.c │ ├── debug dump macro names.c │ ├── debug dump macros and results.c │ ├── debug dump macros.c │ ├── deferred macro expansion.c │ ├── digraph pretty print.c │ ├── empty macro block expansion.c │ ├── empty va args comma delete c99.c │ ├── float header aarch64-linux-gnu.c │ ├── float header netbsd 6.99.26.c │ ├── float header x86-64-linux.c │ ├── function macro expansion.c │ ├── gnu variadic macros.h │ ├── incorrect macro arg count.c │ ├── lazy macro.c │ ├── line counter.c │ ├── macro argument evaluation.c │ ├── macro expansion disabled.c │ ├── macro expansion exhaustion.c │ ├── macro re-expansion.c │ ├── macro self definition.c │ ├── macro token pasting order.c │ ├── macro unbalanced parens call.c │ ├── macro whitespace.c │ ├── multiline comment.c │ ├── nested #ifs.c │ ├── nested macro call.c │ ├── nested unterminated macro gcc.c │ ├── nested unterminated macro.c │ ├── object macro expansion.c │ ├── object macro token pasting.c │ ├── paste operator whitespace.c │ ├── placeholder tokens pasting.c │ ├── preserve comments in macros.c │ ├── preserve comments.c │ ├── recursive call non-expanded parens.c │ ├── recursive func macro.c │ ├── recursive object macro.c │ ├── source epoch.c │ ├── standard-concatenation-strings-example.c │ ├── standard-placeholder-example.c │ ├── standard-redefinition-reexamination-example.c │ ├── stringify invalid escape.c │ ├── token paste delete comma gnu.c │ ├── unspecified expansion.c │ ├── unterminated macro function at eof gcc.c │ ├── unterminated macro function at eof.c │ ├── var args macro functions.c │ ├── whitespace macro arguments.c │ └── zero argument macro.c ├── extended identifiers c11.c ├── extended identifiers c99.c ├── extension.c ├── extern variables.c ├── fixed size integer constants x86_64-linux-gnu.c ├── float array size.c ├── float builtins.c ├── float eval method.c ├── float header aarch64-linux-gnu.c ├── float header netbsd 6.99.26.c ├── float header x86-64-linux.c ├── float to int.c ├── float values.c ├── for decl stmt.c ├── forever stmt.c ├── fp16 parameter aarch64.c ├── fp16 parameter.c ├── function macro expansion.c ├── functions.c ├── generated location.c ├── generic ast.c ├── generic.c ├── gnu alignof.c ├── gnu designated init extension.c ├── gnu inline assembly statements.c ├── gnu pointer arith.c ├── gnu variadic macros.h ├── gnu89 standard.c ├── gnuc version default.c ├── gnuc version empty.c ├── gnuc version override.c ├── guard defined outside header.c ├── guard undef.c ├── hash_hash at func macro start.c ├── hello world.c ├── ignored attributes.c ├── imaginary constants.c ├── implicit main return zero.c ├── implicitly unsigned literal.c ├── include pragma.c ├── include │ ├── correct_guard.h │ ├── embed byte │ ├── embed data │ ├── empty │ ├── global_var.h │ ├── global_var_once.h │ ├── global_var_once_pragma_operator.h │ ├── incorrect_guard.h │ ├── ms-ext │ │ └── include other.h │ ├── my_include.h │ ├── next │ │ ├── my_include.h │ │ └── other.h │ ├── other.h │ ├── test_helpers.h │ └── two spaces │ │ └── three spaces.h ├── include_next.c ├── incomplete types.c ├── incorrect guard.c ├── incorrect macro arg count.c ├── incorrect typeof usage.c ├── indirect macro invocation wrong arg count.c ├── initializers.c ├── int128.c ├── integer conversions 32bit.c ├── integer conversions.c ├── integer literal promotion warning clang.c ├── integer literal promotion warning gcc 32.c ├── integer literal promotion warning gcc 64.c ├── intmax_t.c ├── intptr_t.c ├── invalid _BitInt pointer.c ├── invalid attributes.c ├── invalid continuation byte at eof.c ├── invalid epoch.c ├── invalid k&r functions.c ├── invalid types.c ├── keyword hidden by macro.c ├── kr_def_deprecated.c ├── labeled return.c ├── latin1.c ├── layout overflow.c ├── lazy macro.c ├── least and fast int.c ├── limits header.c ├── line counter.c ├── linux __float128.c ├── macro argument evaluation.c ├── macro backtrace limit.c ├── macro backtrace.c ├── macro definition errors.c ├── macro expansion disabled.c ├── macro expansion exhaustion.c ├── macro expansion to defined parsed.c ├── macro expansion to defined.c ├── macro keyword normalization.c ├── macro re-expansion.c ├── macro redefinition.c ├── macro self definition.c ├── macro token pasting order.c ├── macro unbalanced parens call.c ├── macro whitespace.c ├── main wrong return type.c ├── member expr.c ├── misplaced attribute.c ├── missing newline before eof.c ├── missing type specifier.c ├── ms-extensions.c ├── msp430 builtin types.c ├── msvc attribute keywords.c ├── msvc boolean bitfield.c ├── msvc flexible array in union.c ├── msvc macros.c ├── msvc zero size array.c ├── multiline comment.c ├── nameless param.c ├── native half type.c ├── negative and too big shift count.c ├── nested #ifs.c ├── nested attributes.c ├── nested invalid struct layout.c ├── nested macro call.c ├── nested unterminated macro gcc.c ├── nested unterminated macro.c ├── newline splicing.c ├── nl in macro param.c ├── no declarations.c ├── no declspec.c ├── no dollars in identifiers.c ├── no inline asm.c ├── non string attribute.c ├── nullability.c ├── nullptr.c ├── numbers.c ├── object macro expands to function macro.c ├── object macro expansion.c ├── object macro token pasting.c ├── offsetof.c ├── old style flexible array.c ├── packed member address.c ├── parser using typeof types.c ├── paste operator whitespace.c ├── pic1.c ├── pic2.c ├── pie1.c ├── pie2.c ├── placeholder tokens pasting.c ├── pointer subtraction.c ├── pragma changes warning to error in parser.c ├── pragma during parsing.c ├── pragma once.c ├── pragma operator.c ├── pragma poison.c ├── pragma warning and error.c ├── pragma without terminating newline.c ├── predefined macros.c ├── preprocessor binary operators.c ├── preserve comments in macros.c ├── preserve comments.c ├── promotion edge cases.c ├── recursive call non-expanded parens.c ├── recursive func macro.c ├── recursive object macro.c ├── redefine invalid typedef.c ├── redefine typedef.c ├── redefinitions.c ├── relocations.c ├── repeated preprocessor tokens.c ├── return.c ├── self_include.c ├── shufflevector.c ├── signed char.c ├── signed remainder.c ├── sizeof alignof.c ├── sizeof variably modified types.c ├── source epoch.c ├── spliced newline in char literal.c ├── spliced newline in string literal.c ├── standard attributes.c ├── standard-concatenation-strings-example.c ├── standard-placeholder-example.c ├── standard-redefinition-reexamination-example.c ├── statement expressions.c ├── statements.c ├── static assert messages.c ├── stdarg.c ├── stdckdint.c ├── stdckdint_ast.c ├── stringify backslashes.c ├── stringify invalid escape.c ├── stringify invalid.c ├── strings.c ├── subscript.c ├── switch unsigned int.c ├── tentative array.c ├── tentative definitions.c ├── token paste delete comma gnu.c ├── transparent_union.c ├── type_resolution.c ├── typedef extra specifiers disallowed.c ├── typeof incomplete array.c ├── typeof invalid pointer.c ├── typeof pointer wrong size.c ├── typeof quals.c ├── typeof.c ├── typeof_unqual.c ├── types.c ├── u8 character constant.c ├── ucn identifiers.c ├── unaligned u16 string literal.c ├── unary expressions.c ├── unavailable results.c ├── undef.c ├── undefined macro.c ├── unexpected pragmas.c ├── unexpected_type_name.c ├── unknown pragmas.c ├── unmatched macro paren.c ├── unreachable code.c ├── unreachable.c ├── unsigned char.c ├── unspecified expansion.c ├── unterminated char literal.c ├── unterminated comment in preprocessor expression.c ├── unterminated comment.c ├── unterminated macro function at eof gcc.c ├── unterminated macro function at eof.c ├── unterminated string literal.c ├── var args macro functions.c ├── vectors.c ├── vla.c ├── void star.c ├── warn unused result.c ├── whitespace macro arguments.c ├── wide character constants.c ├── wide strings.c ├── zero argument macro.c ├── zero length array.c └── zero length multidimensional array.c ├── docker └── fuzz │ └── Dockerfile ├── fuzz ├── fuzz_lib.zig └── main.c ├── record_readme.md ├── record_runner.zig ├── records ├── 0001_test.c ├── 0002_test.c ├── 0003_test.c ├── 0004_test.c ├── 0005_test.c ├── 0006_test.c ├── 0007_test.c ├── 0008_test.c ├── 0009_test.c ├── 0010_test.c ├── 0011_test.c ├── 0012_test.c ├── 0013_test.c ├── 0014_test.c ├── 0015_test.c ├── 0016_test.c ├── 0017_test.c ├── 0018_test.c ├── 0019_test.c ├── 0020_test.c ├── 0021_test.c ├── 0022_test.c ├── 0023_test.c ├── 0024_test.c ├── 0025_test.c ├── 0026_test.c ├── 0027_test.c ├── 0028_test.c ├── 0029_test.c ├── 0030_test.c ├── 0031_test.c ├── 0032_test.c ├── 0033_test.c ├── 0034_test.c ├── 0035_test.c ├── 0036_test.c ├── 0037_test.c ├── 0038_test.c ├── 0039_test.c ├── 0040_test.c ├── 0041_test.c ├── 0042_test.c ├── 0043_test.c ├── 0044_test.c ├── 0045_test.c ├── 0046_test.c ├── 0047_test.c ├── 0048_test.c ├── 0049_test.c ├── 0050_test.c ├── 0051_test.c ├── 0052_test.c ├── 0053_test.c ├── 0054_test.c ├── 0055_test.c ├── 0056_test.c ├── 0057_test.c ├── 0058_test.c ├── 0059_test.c ├── 0060_test.c ├── 0061_test.c ├── 0062_test.c ├── 0063_test.c ├── 0064_test.c ├── 0065_test.c ├── 0066_test.c ├── 0067_test.c ├── 0068_test.c ├── 0069_test.c ├── 0070_test.c ├── 0071_test.c ├── 0072_test.c ├── 0073_test.c ├── 0074_test.c ├── 0075_test.c ├── 0076_test.c ├── 0077_test.c ├── 0078_test.c ├── 0079_test.c ├── 0080_test.c ├── 0081_test.c ├── 0082_test.c ├── 0083_test.c ├── 0084_test.c ├── 0085_test.c ├── 0086_test.c ├── 0087_test.c └── 0088_test.c └── runner.zig /.gitattributes: -------------------------------------------------------------------------------- 1 | *.zig text eol=lf 2 | test/cases/expanded/* text eol=lf 3 | test/cases/ast/* text eol=lf 4 | 5 | deps/** linguist-vendored 6 | test/records/** linguist-generated=true 7 | src/builtins/BuiltinFunction.zig linguist-generated=true 8 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - tmp 8 | pull_request: 9 | paths: 10 | - '**.zig' 11 | - '**.c' 12 | - '**.h' 13 | 14 | jobs: 15 | build: 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | os: [ubuntu-latest, macos-latest, windows-latest] 20 | runs-on: ${{ matrix.os }} 21 | steps: 22 | - uses: actions/checkout@v3 23 | with: 24 | submodules: true 25 | - uses: mlugg/setup-zig@v2 26 | with: 27 | version: master 28 | 29 | - name: Fmt 30 | run: zig fmt . --check 31 | if: matrix.os == 'ubuntu-latest' 32 | 33 | - name: Build 34 | run: zig build 35 | 36 | - name: Build 32-bit 37 | run: zig build -Dtarget=arm-linux 38 | if: matrix.os == 'ubuntu-latest' 39 | 40 | - name: Build release 41 | run: zig build -Doptimize=ReleaseSafe 42 | 43 | - name: Run Tests 44 | run: zig build test 45 | 46 | # - name: Run Tests in release mode 47 | # run: zig build test -Doptimize=ReleaseFast 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .zig-cache/ 2 | zig-out/ 3 | test/fuzz-output/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Veikka Tuominen 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 | -------------------------------------------------------------------------------- /build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .aro, 3 | 4 | .version = "0.0.0", 5 | 6 | .fingerprint = 0x76501fb842f52025, // Changing this has security and trust implications. 7 | 8 | .minimum_zig_version = "0.15.0-dev.460+f4e9846bc", 9 | 10 | .dependencies = .{}, 11 | 12 | .paths = .{ 13 | "build", 14 | "build.zig", 15 | "build.zig.zon", 16 | "deps", 17 | "include", 18 | "src", 19 | "LICENSE", 20 | "LICENSE-UNICODE", 21 | "README.md", 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /deps/zig/lib.zig: -------------------------------------------------------------------------------- 1 | pub const arch = struct { 2 | pub const x86_64 = struct { 3 | pub const abi = @import("arch/x86_64/abi.zig"); 4 | pub const bits = @import("arch/x86_64/bits.zig"); 5 | }; 6 | }; 7 | pub const RegisterManager = @import("register_manager.zig").RegisterManager; 8 | -------------------------------------------------------------------------------- /include/iso646.h: -------------------------------------------------------------------------------- 1 | /* for the Aro C compiler */ 2 | 3 | #pragma once 4 | 5 | #define and && 6 | #define and_eq &= 7 | #define bitand & 8 | #define bitor | 9 | #define compl ~ 10 | #define not ! 11 | #define not_eq != 12 | #define or || 13 | #define or_eq |= 14 | #define xor ^ 15 | #define xor_eq ^= 16 | -------------------------------------------------------------------------------- /include/stdalign.h: -------------------------------------------------------------------------------- 1 | /* for the Aro C compiler */ 2 | 3 | #pragma once 4 | #if __STDC_VERSION__ < 202311L 5 | 6 | #define alignas _Alignas 7 | #define alignof _Alignof 8 | 9 | #define __alignas_is_defined 1 10 | #define __alignof_is_defined 1 11 | #endif 12 | -------------------------------------------------------------------------------- /include/stdarg.h: -------------------------------------------------------------------------------- 1 | /* for the Aro C compiler */ 2 | 3 | #pragma once 4 | /* Todo: Set to 202311L once header is compliant with C23 */ 5 | #define __STDC_VERSION_STDARG_H__ 0 6 | 7 | typedef __builtin_va_list va_list; 8 | #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L 9 | /* C23 no longer requires the second parameter */ 10 | #define va_start(ap, ...) __builtin_va_start(ap, __VA_ARGS__) 11 | #else 12 | #define va_start(ap, param) __builtin_va_start(ap, param) 13 | #endif 14 | #define va_end(ap) __builtin_va_end(ap) 15 | #define va_arg(ap, type) __builtin_va_arg(ap, type) 16 | 17 | /* GCC and Clang always define __va_copy */ 18 | #define __va_copy(d, s) __builtin_va_copy(d, s) 19 | 20 | /* but va_copy only on c99+ or when strict ansi mode is turned off */ 21 | #if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) 22 | #define va_copy(d, s) __builtin_va_copy(d, s) 23 | #endif 24 | 25 | #ifndef __GNUC_VA_LIST 26 | #define __GNUC_VA_LIST 1 27 | typedef __builtin_va_list __gnuc_va_list; 28 | #endif 29 | -------------------------------------------------------------------------------- /include/stdbool.h: -------------------------------------------------------------------------------- 1 | /* for the Aro C compiler */ 2 | 3 | #pragma once 4 | 5 | #if __STDC_VERSION__ < 202311L 6 | #define bool _Bool 7 | 8 | #define true 1 9 | #define false 0 10 | 11 | #define __bool_true_false_are_defined 1 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /include/stdckdint.h: -------------------------------------------------------------------------------- 1 | /* for the Aro C compiler */ 2 | 3 | #pragma once 4 | 5 | #define __STDC_VERSION_STDCKDINT_H__ 202311L 6 | 7 | #define ckd_add(result, a, b) __builtin_add_overflow(a, b, result) 8 | #define ckd_sub(result, a, b) __builtin_sub_overflow(a, b, result) 9 | #define ckd_mul(result, a, b) __builtin_mul_overflow(a, b, result) 10 | -------------------------------------------------------------------------------- /include/stddef.h: -------------------------------------------------------------------------------- 1 | /* for the Aro C compiler */ 2 | 3 | #pragma once 4 | 5 | #define __STDC_VERSION_STDDEF_H__ 202311L 6 | 7 | typedef __PTRDIFF_TYPE__ ptrdiff_t; 8 | typedef __SIZE_TYPE__ size_t; 9 | typedef __WCHAR_TYPE__ wchar_t; 10 | 11 | /* define max_align_t to match GCC and Clang */ 12 | typedef struct { 13 | long long __aro_max_align_ll; 14 | long double __aro_max_align_ld; 15 | } max_align_t; 16 | 17 | #define NULL ((void*)0) 18 | #define offsetof(T, member) __builtin_offsetof(T, member) 19 | 20 | #if __STDC_VERSION__ >= 202311L 21 | # pragma GCC diagnostic push 22 | # pragma GCC diagnostic ignored "-Wpre-c23-compat" 23 | typedef typeof(nullptr) nullptr_t; 24 | # pragma GCC diagnostic pop 25 | 26 | # if defined unreachable 27 | # error unreachable() is a standard macro in C23 28 | # else 29 | # define unreachable() __builtin_unreachable() 30 | # endif 31 | #endif 32 | -------------------------------------------------------------------------------- /include/stdnoreturn.h: -------------------------------------------------------------------------------- 1 | /* for the Aro C compiler */ 2 | 3 | #pragma once 4 | 5 | #define noreturn _Noreturn 6 | #define __noreturn_is_defined 1 7 | -------------------------------------------------------------------------------- /include/varargs.h: -------------------------------------------------------------------------------- 1 | /* for the Aro C compiler */ 2 | #pragma once 3 | #error please use instead of 4 | -------------------------------------------------------------------------------- /src/aro/StringInterner.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const mem = std.mem; 3 | const Compilation = @import("Compilation.zig"); 4 | 5 | const StringInterner = @This(); 6 | 7 | pub const StringId = enum(u32) { 8 | empty = std.math.maxInt(u32), 9 | _, 10 | 11 | pub fn lookup(id: StringId, comp: *const Compilation) []const u8 { 12 | if (id == .empty) return ""; 13 | return comp.string_interner.table.keys()[@intFromEnum(id)]; 14 | } 15 | 16 | pub fn lookupExtra(id: StringId, si: StringInterner) []const u8 { 17 | if (id == .empty) return ""; 18 | return si.table.keys()[@intFromEnum(id)]; 19 | } 20 | }; 21 | 22 | table: std.StringArrayHashMapUnmanaged(void) = .empty, 23 | 24 | pub fn deinit(si: *StringInterner, allocator: mem.Allocator) void { 25 | si.table.deinit(allocator); 26 | si.* = undefined; 27 | } 28 | 29 | /// Intern externally owned string. 30 | pub fn intern(si: *StringInterner, allocator: mem.Allocator, str: []const u8) !StringId { 31 | if (str.len == 0) return .empty; 32 | 33 | const gop = try si.table.getOrPut(allocator, str); 34 | return @enumFromInt(gop.index); 35 | } 36 | -------------------------------------------------------------------------------- /src/assembly_backend.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | const aro = @import("aro"); 4 | 5 | pub const x86_64 = @import("assembly_backend/x86_64.zig"); 6 | 7 | pub fn genAsm(target: std.Target, tree: *const aro.Tree) aro.Compilation.Error!aro.Assembly { 8 | return switch (target.cpu.arch) { 9 | .x86_64 => x86_64.genAsm(tree), 10 | else => std.debug.panic("genAsm not implemented: {s}", .{@tagName(target.cpu.arch)}), 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /src/backend.zig: -------------------------------------------------------------------------------- 1 | pub const Assembly = @import("backend/Assembly.zig"); 2 | pub const CodeGenOptions = @import("backend/CodeGenOptions.zig"); 3 | pub const Interner = @import("backend/Interner.zig"); 4 | pub const Ir = @import("backend/Ir.zig"); 5 | pub const Object = @import("backend/Object.zig"); 6 | 7 | pub const CallingConvention = enum { 8 | c, 9 | stdcall, 10 | thiscall, 11 | vectorcall, 12 | fastcall, 13 | regcall, 14 | riscv_vector, 15 | aarch64_sve_pcs, 16 | aarch64_vector_pcs, 17 | arm_aapcs, 18 | arm_aapcs_vfp, 19 | x86_64_sysv, 20 | x86_64_win, 21 | }; 22 | 23 | pub const version_str = @import("build_options").version_str; 24 | pub const version = @import("std").SemanticVersion.parse(version_str) catch unreachable; 25 | -------------------------------------------------------------------------------- /src/backend/Assembly.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const Allocator = std.mem.Allocator; 3 | 4 | data: []const u8, 5 | text: []const u8, 6 | 7 | const Assembly = @This(); 8 | 9 | pub fn deinit(self: *const Assembly, gpa: Allocator) void { 10 | gpa.free(self.data); 11 | gpa.free(self.text); 12 | } 13 | 14 | pub fn writeToFile(self: Assembly, file: std.fs.File) !void { 15 | var vec: [2]std.posix.iovec_const = .{ 16 | .{ .base = self.data.ptr, .len = self.data.len }, 17 | .{ .base = self.text.ptr, .len = self.text.len }, 18 | }; 19 | return file.writevAll(&vec); 20 | } 21 | -------------------------------------------------------------------------------- /test/cases/#elifdef.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #ifdef FOO 3 | long long 4 | #elifdef FOO 5 | long 6 | #elifndef FOO 7 | int 8 | #endif 9 | 10 | #define BAR 11 | #ifdef FOO 12 | long long 13 | #elifdef BAR 14 | long 15 | #elifndef FOO 16 | int 17 | #endif 18 | -------------------------------------------------------------------------------- /test/cases/#elifndef error.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -std=c23 -P 2 | #define EXPECTED_ERRORS \ 3 | "#elifndef error.c:8:9: error: macro name missing" \ 4 | "#elifndef error.c:17:10: error: macro name missing" 5 | #ifdef FOO 6 | long long 7 | #elifdef 8 | long 9 | #else 10 | int 11 | #endif 12 | 13 | #define BAR 14 | #ifdef FOO 15 | long long 16 | #elifndef 17 | long 18 | #else 19 | int 20 | #endif 21 | -------------------------------------------------------------------------------- /test/cases/#elifndef.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 -E -P 2 | #ifdef FOO 3 | long long 4 | #elifdef FOO 5 | long 6 | #elifndef FOO 7 | int 8 | #endif 9 | 10 | #define BAR 11 | #ifdef FOO 12 | long long 13 | #elifdef BAR 14 | long 15 | #elifndef FOO 16 | int 17 | #endif 18 | -------------------------------------------------------------------------------- /test/cases/#if constant expression.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -Wno-integer-overflow -P 2 | 3 | #if defined FOO & !defined(BAZ) 4 | void 5 | #elif !defined(BAR) 6 | long 7 | #endif 8 | 9 | #if 1 - 1 10 | #error "foo" 11 | #endif 12 | 13 | #if defined BAR ? 1 : 0 14 | #error foo 15 | #endif 16 | 17 | #if 0 && 0 18 | # error foo 19 | #endif 20 | 21 | #if 0 || 0 22 | # error foo 23 | #endif 24 | #if 0U - 1 != 18446744073709551615ULL 25 | #error incorrect unsigned subtraction in preprocessor 26 | #endif 27 | -------------------------------------------------------------------------------- /test/cases/#if expression error.c: -------------------------------------------------------------------------------- 1 | #if 1/q 2 | #endif 3 | 4 | #define EXPECTED_ERRORS "#if expression error.c:1:6: error: division by zero in preprocessor expression" \ 5 | -------------------------------------------------------------------------------- /test/cases/#if expression macro ws.c: -------------------------------------------------------------------------------- 1 | #define FOO(X) X 2 | 3 | #if FOO( X ) 4 | #error Should not error 5 | #endif 6 | 7 | #define Y 1 8 | 9 | #if FOO ( Y ) 10 | #error Should error 11 | #endif 12 | 13 | #define EXPECTED_ERRORS "#if expression macro ws.c:10:2: error: Should error" \ 14 | 15 | -------------------------------------------------------------------------------- /test/cases/#ifdef.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define FOO 4 | #ifdef FOO 5 | long 6 | #else 7 | int 8 | #endif 9 | 10 | #define BAR 11 | #ifdef BAZ 12 | long 13 | #else 14 | int 15 | #endif 16 | -------------------------------------------------------------------------------- /test/cases/#pragma pack clang.c: -------------------------------------------------------------------------------- 1 | //aro-args --emulate=clang 2 | 3 | struct A { 4 | char c; 5 | int x; 6 | }; 7 | 8 | struct B { 9 | #pragma pack(1) 10 | char c; 11 | int x; 12 | }; 13 | 14 | #pragma pack() 15 | struct C { 16 | char c; 17 | #pragma pack(1) 18 | int x; 19 | }; 20 | 21 | #pragma pack() 22 | struct D { 23 | char c; 24 | int x; 25 | #pragma pack(1) 26 | }; 27 | 28 | _Static_assert(sizeof(struct A) == sizeof(struct B), ""); 29 | _Static_assert(sizeof(struct A) == sizeof(struct C), ""); 30 | _Static_assert(sizeof(struct A) == sizeof(struct D), ""); 31 | -------------------------------------------------------------------------------- /test/cases/#pragma pack gcc.c: -------------------------------------------------------------------------------- 1 | //aro-args --emulate=gcc 2 | 3 | struct A { 4 | char c; 5 | int x; 6 | }; 7 | 8 | struct B { 9 | #pragma pack(1) 10 | char c; 11 | int x; 12 | }; 13 | 14 | #pragma pack() 15 | struct C { 16 | char c; 17 | #pragma pack(1) 18 | int x; 19 | }; 20 | 21 | #pragma pack() 22 | struct D { 23 | char c; 24 | int x; 25 | #pragma pack(1) 26 | }; 27 | 28 | _Static_assert(sizeof(struct A) > sizeof(struct B), ""); 29 | _Static_assert(sizeof(struct B) == sizeof(char) + sizeof(int), ""); 30 | _Static_assert(sizeof(struct C) == sizeof(char) + sizeof(int), ""); 31 | _Static_assert(sizeof(struct D) == sizeof(char) + sizeof(int), ""); 32 | -------------------------------------------------------------------------------- /test/cases/#pragma pack msvc.c: -------------------------------------------------------------------------------- 1 | //aro-args --emulate=msvc 2 | 3 | struct A { 4 | char c; 5 | int x; 6 | }; 7 | 8 | struct B { 9 | #pragma pack(1) 10 | char c; 11 | int x; 12 | }; 13 | 14 | #pragma pack() 15 | struct C { 16 | char c; 17 | #pragma pack(1) 18 | int x; 19 | }; 20 | 21 | #pragma pack() 22 | struct D { 23 | char c; 24 | int x; 25 | #pragma pack(1) 26 | }; 27 | 28 | _Static_assert(sizeof(struct A) > sizeof(struct B), ""); 29 | _Static_assert(sizeof(struct B) == sizeof(struct C), ""); 30 | _Static_assert(sizeof(struct B) == sizeof(char) + sizeof(int), ""); 31 | // _Static_assert(sizeof(struct A) == sizeof(struct D), ""); 32 | 33 | #define TESTS_SKIPPED 1 34 | -------------------------------------------------------------------------------- /test/cases/X macro.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define X(a) Foo_ ## a = a, 4 | enum Foo { 5 | X(1) 6 | X(2) 7 | X(3) 8 | X(4) 9 | X(5) 10 | }; 11 | -------------------------------------------------------------------------------- /test/cases/_BitInt change size.c: -------------------------------------------------------------------------------- 1 | _BitInt(10) x = 1.2; 2 | _Complex unsigned _BitInt(10) y = 1.2; 3 | 4 | #define EXPECTED_ERRORS "_BitInt change size.c:1:17: warning: implicit conversion from 'double' to 'signed _BitInt(10)' changes value from 1.2 to 1 [-Wfloat-conversion]"\ 5 | "_BitInt change size.c:2:35: warning: implicit conversion from 'double' to '_Complex unsigned _BitInt(10)' changes value from 1.2 to 1 [-Wfloat-conversion]" 6 | -------------------------------------------------------------------------------- /test/cases/_BitInt min max.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | _Static_assert(-10 % -444444444444444442051616WB != 0, ""); 3 | 4 | enum E: _BitInt(512) { 5 | A = -6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042048WB, 6 | B = 6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042047WB, 7 | }; 8 | -------------------------------------------------------------------------------- /test/cases/_Float16.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | #include 3 | 4 | _Float16 foo(_Float16 x, _Float16 y) { 5 | return x + y ; 6 | } 7 | 8 | void bar(int x, ...) { 9 | va_list va; 10 | va_start(va, x); 11 | va_end(va); 12 | } 13 | 14 | void quux(void) { 15 | _Float16 f = 1.0f16; 16 | bar(1, f); // _Float16 does not promote to double when used as vararg 17 | } 18 | 19 | void conversions(void) { 20 | double d = 1.0; 21 | _Float16 f16 = 2.0f16; 22 | __fp16 fp16 = 0; 23 | d = d + f16; 24 | (void)(f16 + fp16); // _Float16 + __fp16 promotes both to float 25 | } 26 | 27 | #define TESTS_SKIPPED 1 28 | -------------------------------------------------------------------------------- /test/cases/__VA_OPT__.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #define foo(...) __VA_OPT__(1, 2, ) __VA_OPT__(3, 4) 3 | foo(1) 4 | 5 | #define bar(...) a ## __VA_OPT__(3, 4) + 6 | bar() 7 | 8 | #define baz() __VA_OPT__(1) 9 | baz() 10 | 11 | #define invalid1(...) __VA_OPT__ 1 12 | #define invalid2(...) __VA_OPT__(1 13 | 14 | #define EXPECTED_ERRORS \ 15 | "__VA_OPT__.c:11:33: error: missing '(' following __VA_OPT__" \ 16 | "__VA_OPT__.c:13:35: error: unterminated __VA_OPT__ argument list" \ 17 | "__VA_OPT__.c:12:33: note: to match this '('" \ 18 | -------------------------------------------------------------------------------- /test/cases/__auto_type self init.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | void foo(void) { 3 | int x; 4 | __auto_type x = x; 5 | 6 | __auto_type y = (int []){1, y}; 7 | 8 | auto z = z + 1; 9 | } 10 | 11 | #define EXPECTED_ERRORS "__auto_type self init.c:4:21: error: variable 'x' declared with deduced type '__auto_type' cannot appear in its own initializer" \ 12 | "__auto_type self init.c:6:33: error: variable 'y' declared with deduced type '__auto_type' cannot appear in its own initializer" \ 13 | "__auto_type self init.c:8:14: error: variable 'z' declared with deduced type '__auto_type' cannot appear in its own initializer" \ 14 | 15 | -------------------------------------------------------------------------------- /test/cases/__float80 clang.c: -------------------------------------------------------------------------------- 1 | //aro-args --emulate=clang 2 | 3 | void foo(void) { 4 | __float80 x; 5 | double y = 1.0w; 6 | _Complex double z = 2.0iw; 7 | } 8 | 9 | #define EXPECTED_ERRORS "__float80 clang.c:4:5: error: use of undeclared identifier '__float80'" \ 10 | "__float80 clang.c:5:16: error: invalid suffix 'w' on floating constant" \ 11 | "__float80 clang.c:6:25: error: invalid suffix 'iw' on floating constant" \ 12 | 13 | -------------------------------------------------------------------------------- /test/cases/__float80.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux 2 | void foo(void) { 3 | __float80 x = 1.0w; 4 | x = 1.0W; 5 | _Complex long double z; 6 | z = 1.0wI; 7 | z = 1.0iW; 8 | } 9 | -------------------------------------------------------------------------------- /test/cases/__func__.c: -------------------------------------------------------------------------------- 1 | extern int puts(const char*); 2 | 3 | static const char *f = __func__; 4 | static const char *f1 = __FUNCTION__; 5 | static const char *f2 = __PRETTY_FUNCTION__; 6 | 7 | int foo(void) { 8 | puts(f); 9 | puts(f1); 10 | puts(f2); 11 | puts(__func__); 12 | puts(__FUNCTION__); 13 | puts(__PRETTY_FUNCTION__); 14 | return 0; 15 | } 16 | long *bar(int a) { 17 | puts(__FUNCTION__); 18 | puts(__func__); 19 | puts(__PRETTY_FUNCTION__); 20 | return 0; 21 | } 22 | 23 | #define EXPECTED_ERRORS "__func__.c:3:24: warning: predefined identifier is only valid inside function [-Wpredefined-identifier-outside-function]" \ 24 | "__func__.c:4:25: warning: predefined identifier is only valid inside function [-Wpredefined-identifier-outside-function]" \ 25 | "__func__.c:5:25: warning: predefined identifier is only valid inside function [-Wpredefined-identifier-outside-function]" \ 26 | -------------------------------------------------------------------------------- /test/cases/__has_attribute with define.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define foo __has_attribute(used) 4 | #define bar 1 + __has_attribute(does_not_exist) 5 | #define HASATTR(X) __has_attribute(X) 6 | #define HASATTR2(X, Y) __has_attribute(X ## Y) 7 | foo 8 | bar 9 | HASATTR(used) 10 | HASATTR2(us, ed) 11 | -------------------------------------------------------------------------------- /test/cases/__has_attribute.c: -------------------------------------------------------------------------------- 1 | #if defined __has_attribute 2 | # if __has_attribute(aligned) 3 | #error attribute exists 4 | # endif 5 | # if __has_attribute(does_not_exist) 6 | #error attribute exists 7 | # endif 8 | #endif 9 | 10 | #define EXPECTED_ERRORS "__has_attribute.c:3:8: error: attribute exists" 11 | -------------------------------------------------------------------------------- /test/cases/__has_builtin.c: -------------------------------------------------------------------------------- 1 | #if defined __has_builtin 2 | # if __has_builtin(__builtin_va_start) && __has_builtin(__builtin_va_arg) 3 | #error builtin exists 4 | # endif 5 | # if __has_builtin(__builtin_foobar) 6 | #error builtin exists 7 | # endif 8 | #endif 9 | 10 | #define EXPECTED_ERRORS "__has_builtin.c:3:8: error: builtin exists" 11 | -------------------------------------------------------------------------------- /test/cases/__has_extension.c: -------------------------------------------------------------------------------- 1 | #if defined __has_extension 2 | # if __has_extension(c_alignas) 3 | #error extension exists 4 | # endif 5 | # if __has_extension(does_not_exist) 6 | #error extension exists 7 | # endif 8 | #endif 9 | 10 | #define EXPECTED_ERRORS "__has_extension.c:3:8: error: extension exists" 11 | -------------------------------------------------------------------------------- /test/cases/__has_feature.c: -------------------------------------------------------------------------------- 1 | #if defined __has_feature 2 | # if __has_feature(enumerator_attributes) 3 | #error feature exists 4 | # endif 5 | # if __has_feature(does_not_exist) 6 | #error feature exists 7 | # endif 8 | #endif 9 | 10 | #define EXPECTED_ERRORS "__has_feature.c:3:8: error: feature exists" 11 | -------------------------------------------------------------------------------- /test/cases/__has_warning.c: -------------------------------------------------------------------------------- 1 | #if !__has_warning("-Wextern-initializer") 2 | #error 3 | #endif 4 | 5 | #if __has_warning("-Wfoo") 6 | #error foo should not exist 7 | #elif !__has_warning("-Wunrea" "chable-code") 8 | #error unreachable-code should exist 9 | #endif 10 | 11 | #if __has_warning("foobar") 12 | #error 13 | #elif __has_warning(foobar) 14 | #error 15 | #endif 16 | 17 | #define X __has_warning("-Wextern-initializer") 18 | _Static_assert(X == 1, "Failed to find warning"); 19 | 20 | #define EXPECTED_ERRORS "__has_warning.c:11:19: warning: __has_warning expected option name (e.g. \"-Wundef\") [-Wmalformed-warning-check]" \ 21 | "__has_warning.c:13:21: error: expected string literal in '__has_warning'" \ 22 | -------------------------------------------------------------------------------- /test/cases/__is_identifier.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c17 2 | #if !__is_identifier(typeof) 3 | #error typeof should be an identifier in c17 4 | #endif 5 | 6 | #if __is_identifier(inline) 7 | #error inline should not be an identifier in c17 8 | #endif 9 | 10 | #if __is_identifier(for) 11 | #error for is not an identifier 12 | #endif 13 | 14 | #if __is_identifier("foo") 15 | #error string should not be an identifier 16 | #endif 17 | 18 | #if __is_identifier(_Static_assert) 19 | #error static assert is reserved 20 | #endif 21 | 22 | #define X __is_identifier(foobar) 23 | _Static_assert(X == 1, "'foobar' should be an identifier"); 24 | 25 | #if __is_identifier(foo bar) 26 | #error too many arguments 27 | #endif 28 | 29 | #if __is_identifier() 30 | #error not enough arguments 31 | #endif 32 | 33 | #define EXPECTED_ERRORS "__is_identifier.c:25:25: error: missing ')', after builtin feature-check macro" \ 34 | "__is_identifier.c:29:5: error: expected 1 argument(s) got 0" 35 | -------------------------------------------------------------------------------- /test/cases/__line__.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #define LINE __LINE__ 3 | 4 | void foo(void) { 5 | \ 6 | i\ 7 | nt x = __LI\ 8 | NE__; 9 | \ 10 | \ 11 | int y = __LINE__; 12 | 13 | int z = LINE; 14 | \ 15 | \ 16 | 17 | } 18 | -------------------------------------------------------------------------------- /test/cases/address of label.c: -------------------------------------------------------------------------------- 1 | void foo(void) { 2 | int x = 5; 3 | void *y = &&baz; 4 | bar: 5 | y = &&bar; 6 | baz: 7 | x = 0; 8 | goto *y; 9 | goto *&&baz; 10 | } 11 | 12 | void no_address_of_label(void *arg) { 13 | label: 14 | goto *arg; 15 | } 16 | 17 | void implicit_conversion(void) { 18 | int x = 0; 19 | void *y = &&label; 20 | label: 21 | goto *0; 22 | goto *x; 23 | } 24 | 25 | void invalid_param(void) { 26 | void *p = &&label; 27 | float f = 0.0f; 28 | label: 29 | goto *f; 30 | } 31 | 32 | #define EXPECTED_ERRORS "address of label.c:14:5: error: computed goto in function with no address-of-label expressions" \ 33 | "address of label.c:22:11: warning: implicit integer to pointer conversion from 'int' to 'const void *' [-Wint-conversion]" \ 34 | "address of label.c:29:11: error: passing 'float' to parameter of incompatible type 'const void *'" \ 35 | -------------------------------------------------------------------------------- /test/cases/adjust diagnostic levels.c: -------------------------------------------------------------------------------- 1 | #define FOO 1 2 | #define FOO 2 3 | 4 | #pragma GCC diagnostic error "-Wmacro-redefined" 5 | #define BAR 1 6 | #define BAR 2 7 | 8 | #pragma GCC diagnostic push 9 | 10 | #pragma GCC diagnostic ignored "-Wmacro-redefined" 11 | #define BAZ 1 12 | #define BAZ 2 13 | 14 | #pragma GCC diagnostic pop 15 | #pragma GCC diagnostic pop 16 | 17 | #define QUX 1 18 | #define QUX 2 19 | 20 | #pragma GCC diagnostic push 21 | #pragma GCC diagnostic error "-Wpedantic" 22 | #pragma GCC diagnostic pop 23 | struct Foo {}; 24 | 25 | #define EXPECTED_ERRORS "adjust diagnostic levels.c:2:9: warning: 'FOO' macro redefined [-Wmacro-redefined]" \ 26 | "adjust diagnostic levels.c:1:9: note: previous definition is here" \ 27 | "adjust diagnostic levels.c:6:9: error: 'BAR' macro redefined [-Werror,-Wmacro-redefined]" \ 28 | "adjust diagnostic levels.c:5:9: note: previous definition is here" \ 29 | "adjust diagnostic levels.c:18:9: warning: 'QUX' macro redefined [-Wmacro-redefined]" \ 30 | "adjust diagnostic levels.c:17:9: note: previous definition is here" \ 31 | -------------------------------------------------------------------------------- /test/cases/alloc_align attribute.c: -------------------------------------------------------------------------------- 1 | __attribute__((alloc_align(0))) int* foo1(int x, double y); 2 | __attribute__((alloc_align(1))) int* foo2(int x, double y); 3 | __attribute__((alloc_align(2))) int* foo3(int x, double y); 4 | __attribute__((alloc_align(3))) int* foo4(int x, double y); 5 | __attribute__((alloc_align(1))) int foo5(int x, double y); 6 | 7 | #define EXPECTED_ERRORS \ 8 | "alloc_align attribute.c:1:16: error: 'alloc_align' attribute parameter 1 is out of bounds" \ 9 | "alloc_align attribute.c:3:16: error: 'alloc_align' attribute argument may only refer to a function parameter of integer type" \ 10 | "alloc_align attribute.c:4:16: error: 'alloc_align' attribute parameter 1 is out of bounds" \ 11 | "alloc_align attribute.c:5:16: warning: 'alloc_align' attribute only applies to return values that are pointers [-Wignored-attributes]" \ 12 | 13 | -------------------------------------------------------------------------------- /test/cases/allow fp16 parameter.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu -fnative-half-arguments-and-returns 2 | 3 | __fp16 foo(__fp16 x) { 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /test/cases/alternate spellings for signed.c: -------------------------------------------------------------------------------- 1 | _Static_assert(__builtin_types_compatible_p(signed, __signed), ""); 2 | _Static_assert(__builtin_types_compatible_p(signed, __signed__), ""); 3 | _Static_assert(__builtin_types_compatible_p(signed char, __signed char), ""); 4 | _Static_assert(__builtin_types_compatible_p(signed short, short __signed__), ""); 5 | 6 | _Static_assert(!__builtin_types_compatible_p(unsigned, __signed), ""); 7 | _Static_assert(!__builtin_types_compatible_p(unsigned, __signed__), ""); 8 | _Static_assert(!__builtin_types_compatible_p(unsigned char, char __signed), ""); 9 | _Static_assert(!__builtin_types_compatible_p(unsigned char, __signed__ char), ""); 10 | -------------------------------------------------------------------------------- /test/cases/anonymous attributed field.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | struct A { 3 | union { 4 | char a 5 | } __attribute__((packed))} b = __builtin_offsetof(struct A,a -------------------------------------------------------------------------------- /test/cases/anonymous_struct_ms.c: -------------------------------------------------------------------------------- 1 | //aro-args -fms-extensions 2 | typedef struct { 3 | int a; 4 | } unnamed; 5 | typedef struct named { 6 | int b; 7 | } named; 8 | 9 | struct S { 10 | unnamed; 11 | named; 12 | }; 13 | 14 | #define EXPECTED_ERRORS \ 15 | "anonymous_struct_ms.c:10:12: warning: anonymous structs are a Microsoft extension [-Wmicrosoft-anon-tag]" \ 16 | "anonymous_struct_ms.c:11:10: warning: anonymous structs are a Microsoft extension [-Wmicrosoft-anon-tag]" \ 17 | -------------------------------------------------------------------------------- /test/cases/anonymous_struct_no-ms.c: -------------------------------------------------------------------------------- 1 | //aro-args -fno-ms-extensions 2 | typedef struct { 3 | int a; 4 | } unnamed; 5 | typedef struct named { 6 | int b; 7 | } named; 8 | 9 | struct S { 10 | unnamed; 11 | named; 12 | }; 13 | 14 | #define EXPECTED_ERRORS \ 15 | "anonymous_struct_no-ms.c:10:12: warning: declaration does not declare anything [-Wmissing-declaration]" \ 16 | "anonymous_struct_no-ms.c:11:10: warning: declaration does not declare anything [-Wmissing-declaration]" \ 17 | -------------------------------------------------------------------------------- /test/cases/arithmetic conversion floats.c: -------------------------------------------------------------------------------- 1 | #include "include/test_helpers.h" 2 | 3 | void foo(void) { 4 | EXPECT_TYPE((long double)1 + 1.fi, _Complex long double); 5 | EXPECT_TYPE(1.i + 1.f, _Complex double); 6 | EXPECT_TYPE((long double)1 + 1., long double); 7 | EXPECT_TYPE(1.fi + 1.f, _Complex float); 8 | EXPECT_TYPE(1.f + 1.f, float); 9 | EXPECT_TYPE((long double)1.f + 1.f, long double); 10 | } 11 | -------------------------------------------------------------------------------- /test/cases/arithmetic overflow.c: -------------------------------------------------------------------------------- 1 | _Static_assert(0xFFFFFFFF + 1 == 0, ""); 2 | _Static_assert(1 + 0xFFFFFFFF == 0, ""); 3 | _Static_assert(0 - 0x00000001 == 0xFFFFFFFF, ""); 4 | _Static_assert(0x00000000 - 0x00000001 == 0xFFFFFFFF, ""); 5 | _Static_assert(0x80000000 * 2 == 0, ""); 6 | _Static_assert(2 * 0x80000000 == 0, ""); 7 | _Static_assert(sizeof(int) != 4 || ((unsigned)(-1) << 1) == 0xFFFFFFFFU - 1, ""); 8 | _Static_assert((-9223372036854775807LL - 1LL) / -1 != 0, "failed"); 9 | 10 | #define EXPECTED_ERRORS "arithmetic overflow.c:8:47: warning: overflow in expression; result is '9223372036854775808' [-Winteger-overflow]" \ 11 | 12 | -------------------------------------------------------------------------------- /test/cases/array argument is null.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | #include 3 | void foo(int x[static 10]) { 4 | 5 | } 6 | 7 | void bar(void) { 8 | foo(NULL); 9 | foo(nullptr); 10 | foo(0); 11 | } 12 | 13 | #define EXPECTED_ERRORS "array argument is null.c:8:9: warning: null passed to a callee that requires a non-null argument [-Wnonnull]"\ 14 | "stddef.h:17:14: note: expanded from here"\ 15 | "array argument is null.c:3:14: note: callee declares array parameter as static here"\ 16 | "array argument is null.c:9:9: warning: null passed to a callee that requires a non-null argument [-Wnonnull]"\ 17 | "array argument is null.c:3:14: note: callee declares array parameter as static here"\ 18 | "array argument is null.c:10:9: warning: null passed to a callee that requires a non-null argument [-Wnonnull]"\ 19 | "array argument is null.c:3:14: note: callee declares array parameter as static here" 20 | -------------------------------------------------------------------------------- /test/cases/array argument too small.c: -------------------------------------------------------------------------------- 1 | void foo(int x[static 10]) { 2 | 3 | } 4 | 5 | void bar(void) { 6 | int x[5]; 7 | foo(x); 8 | } 9 | 10 | #define EXPECTED_ERRORS "array argument too small.c:7:9: warning: array argument is too small; contains 5 elements, callee requires at least 10 [-Warray-bounds]"\ 11 | "array argument too small.c:1:14: note: callee declares array parameter as static here" 12 | -------------------------------------------------------------------------------- /test/cases/array designator too large.c: -------------------------------------------------------------------------------- 1 | int arr1[] = { [0x800000000000000 - 1] = 0 }; 2 | int arr2[] = { [0x800000000000000 - 2] = 0 }; 3 | _Static_assert(sizeof(arr1), ""); 4 | _Static_assert(sizeof(arr2), ""); 5 | 6 | #define EXPECTED_ERRORS "array designator too large.c:1:14: error: array is too large" \ 7 | 8 | -------------------------------------------------------------------------------- /test/cases/array of invalid.c: -------------------------------------------------------------------------------- 1 | _BitInt(0) a[]; 2 | _BitInt(0) b[10]; 3 | 4 | #define EXPECTED_ERRORS "array of invalid.c:1:1: error: signed _BitInt must have a bit size of at least 2" \ 5 | "array of invalid.c:2:1: error: signed _BitInt must have a bit size of at least 2" \ 6 | 7 | -------------------------------------------------------------------------------- /test/cases/array of zero size type.c: -------------------------------------------------------------------------------- 1 | struct { 2 | int:0; 3 | 4 | } c [] = {}; 5 | 6 | _Static_assert(sizeof(c) == 0, ""); -------------------------------------------------------------------------------- /test/cases/array subscript with string.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | int x[2]; 3 | x[""[""] 4 | -------------------------------------------------------------------------------- /test/cases/asm.c: -------------------------------------------------------------------------------- 1 | void foo(void) __asm__("foo"); 2 | __asm__ volatile volatile("foo"); 3 | __asm__(u8"nop"); 4 | __asm__(L"nop"); 5 | __asm__(5); 6 | 7 | #define EXPECTED_ERRORS "asm.c:2:9: error: meaningless 'volatile' on assembly outside function" \ 8 | "asm.c:2:18: error: meaningless 'volatile' on assembly outside function" \ 9 | "asm.c:2:18: error: duplicate asm qualifier 'volatile'" \ 10 | "asm.c:3:9: error: cannot use unicode string literal in assembly" \ 11 | "asm.c:4:9: error: cannot use wide string literal in assembly" \ 12 | "asm.c:5:9: error: expected string literal in 'asm'" \ 13 | 14 | -------------------------------------------------------------------------------- /test/cases/assembly invalid token.c: -------------------------------------------------------------------------------- 1 | void foo(void) { 2 | __asm__("") 3 | } 4 | 5 | #define EXPECTED_ERRORS "assembly invalid token.c:2:15: error: expected ')', found 'invalid bytes'" \ 6 | 7 | -------------------------------------------------------------------------------- /test/cases/ast/__float80.c: -------------------------------------------------------------------------------- 1 | implicit typedef: '__int128' 2 | name: __int128_t 3 | 4 | implicit typedef: 'unsigned __int128' 5 | name: __uint128_t 6 | 7 | implicit typedef: '*char' 8 | name: __builtin_ms_va_list 9 | 10 | implicit typedef: '[1]struct __va_list_tag' 11 | name: __builtin_va_list 12 | 13 | implicit typedef: 'struct __NSConstantString_tag' 14 | name: __NSConstantString 15 | 16 | implicit typedef: 'long double' 17 | name: __float80 18 | 19 | fn_def: 'fn () void' 20 | name: foo 21 | body: 22 | compound_stmt 23 | variable: '__float80: long double' 24 | name: x 25 | init: 26 | float_literal: 'long double' (value: 1) 27 | 28 | assign_expr: '__float80: long double' 29 | lhs: 30 | decl_ref_expr: '__float80: long double' lvalue 31 | name: x 32 | rhs: 33 | float_literal: 'long double' (value: 1) 34 | 35 | variable: '_Complex long double' 36 | name: z 37 | 38 | assign_expr: '_Complex long double' 39 | lhs: 40 | decl_ref_expr: '_Complex long double' lvalue 41 | name: z 42 | rhs: 43 | imaginary_literal: '_Complex long double' (value: 0 + 1i) 44 | operand: 45 | float_literal: 'long double' 46 | 47 | assign_expr: '_Complex long double' 48 | lhs: 49 | decl_ref_expr: '_Complex long double' lvalue 50 | name: z 51 | rhs: 52 | imaginary_literal: '_Complex long double' (value: 0 + 1i) 53 | operand: 54 | float_literal: 'long double' 55 | 56 | implicit return_stmt: 'void' 57 | 58 | -------------------------------------------------------------------------------- /test/cases/ast/c23 true false ast.c: -------------------------------------------------------------------------------- 1 | implicit typedef: 'unsigned char' 2 | name: char8_t 3 | 4 | implicit typedef: '__int128' 5 | name: __int128_t 6 | 7 | implicit typedef: 'unsigned __int128' 8 | name: __uint128_t 9 | 10 | implicit typedef: '*char' 11 | name: __builtin_ms_va_list 12 | 13 | implicit typedef: '[1]struct __va_list_tag' 14 | name: __builtin_va_list 15 | 16 | implicit typedef: 'struct __NSConstantString_tag' 17 | name: __NSConstantString 18 | 19 | implicit typedef: 'long double' 20 | name: __float80 21 | 22 | variable: 'bool' 23 | name: a 24 | init: 25 | bool_literal: 'bool' (value: true) 26 | 27 | variable: 'bool' 28 | name: b 29 | init: 30 | bool_literal: 'bool' (value: false) 31 | 32 | variable: 'bool' 33 | name: c 34 | init: 35 | implicit cast: (int_to_bool) 'bool' (value: false) 36 | int_literal: 'int' (value: 0) 37 | 38 | variable: 'bool' 39 | name: d 40 | init: 41 | implicit cast: (int_to_bool) 'bool' (value: true) 42 | int_literal: 'int' (value: 1) 43 | 44 | variable: 'int' 45 | name: e 46 | init: 47 | implicit cast: (bool_to_int) 'int' (value: 1) 48 | bool_literal: 'bool' (value: true) 49 | 50 | variable: 'int' 51 | name: f 52 | init: 53 | implicit cast: (bool_to_int) 'int' (value: 0) 54 | bool_literal: 'bool' (value: false) 55 | 56 | variable: 'int' 57 | name: g 58 | init: 59 | add_expr: 'int' (value: 2) 60 | lhs: 61 | implicit cast: (bool_to_int) 'int' 62 | bool_literal: 'bool' (value: true) 63 | rhs: 64 | int_literal: 'int' (value: 1) 65 | 66 | -------------------------------------------------------------------------------- /test/cases/ast/for decl stmt.c: -------------------------------------------------------------------------------- 1 | implicit typedef: '__int128' 2 | name: __int128_t 3 | 4 | implicit typedef: 'unsigned __int128' 5 | name: __uint128_t 6 | 7 | implicit typedef: '*char' 8 | name: __builtin_ms_va_list 9 | 10 | implicit typedef: '[1]struct __va_list_tag' 11 | name: __builtin_va_list 12 | 13 | implicit typedef: 'struct __NSConstantString_tag' 14 | name: __NSConstantString 15 | 16 | implicit typedef: 'long double' 17 | name: __float80 18 | 19 | fn_def: 'fn () int' 20 | name: main 21 | body: 22 | compound_stmt 23 | for_stmt 24 | decl: 25 | variable: 'int' 26 | name: x 27 | init: 28 | int_literal: 'int' (value: 0) 29 | 30 | variable: 'int' 31 | name: y 32 | init: 33 | int_literal: 'int' (value: 1) 34 | 35 | incr: 36 | post_inc_expr: 'int' 37 | operand: 38 | decl_ref_expr: 'int' lvalue 39 | name: x 40 | body: 41 | null_stmt: 'void' 42 | 43 | implicit return_stmt: 'int' 44 | 45 | -------------------------------------------------------------------------------- /test/cases/ast/forever stmt.c: -------------------------------------------------------------------------------- 1 | implicit typedef: '__int128' 2 | name: __int128_t 3 | 4 | implicit typedef: 'unsigned __int128' 5 | name: __uint128_t 6 | 7 | implicit typedef: '*char' 8 | name: __builtin_ms_va_list 9 | 10 | implicit typedef: '[1]struct __va_list_tag' 11 | name: __builtin_va_list 12 | 13 | implicit typedef: 'struct __NSConstantString_tag' 14 | name: __NSConstantString 15 | 16 | implicit typedef: 'long double' 17 | name: __float80 18 | 19 | fn_def: 'fn () int' 20 | name: main 21 | body: 22 | compound_stmt 23 | for_stmt 24 | body: 25 | null_stmt: 'void' 26 | 27 | implicit return_stmt: 'int' 28 | 29 | -------------------------------------------------------------------------------- /test/cases/ast/generic ast.c: -------------------------------------------------------------------------------- 1 | implicit typedef: '__int128' 2 | name: __int128_t 3 | 4 | implicit typedef: 'unsigned __int128' 5 | name: __uint128_t 6 | 7 | implicit typedef: '*char' 8 | name: __builtin_ms_va_list 9 | 10 | implicit typedef: '[1]struct __va_list_tag' 11 | name: __builtin_va_list 12 | 13 | implicit typedef: 'struct __NSConstantString_tag' 14 | name: __NSConstantString 15 | 16 | implicit typedef: 'long double' 17 | name: __float80 18 | 19 | variable: 'int' 20 | name: x 21 | init: 22 | generic_expr: 'int' (value: 42) 23 | controlling: 24 | int_literal: 'int' (value: 5) 25 | chosen: 26 | generic_association_expr 27 | int_literal: 'int' (value: 42) 28 | rest: 29 | generic_association_expr 30 | float_literal: 'double' (value: 32.5) 31 | 32 | variable: 'int' 33 | name: y 34 | init: 35 | generic_expr: 'int' (value: 42) 36 | controlling: 37 | int_literal: 'int' (value: 5) 38 | chosen: 39 | generic_association_expr 40 | int_literal: 'int' (value: 42) 41 | rest: 42 | generic_association_expr 43 | float_literal: 'double' (value: 32.5) 44 | generic_default_expr 45 | string_literal_expr: '[7]char' lvalue (value: "string") 46 | 47 | variable: 'double' 48 | name: z 49 | init: 50 | implicit cast: (int_to_float) 'double' (value: 32) 51 | generic_expr: 'int' 52 | controlling: 53 | int_literal: 'int' (value: 5) 54 | chosen: 55 | generic_default_expr 56 | int_literal: 'int' (value: 32) 57 | 58 | -------------------------------------------------------------------------------- /test/cases/ast/msvc attribute keywords.c: -------------------------------------------------------------------------------- 1 | implicit typedef: '__int128' 2 | name: __int128_t 3 | 4 | implicit typedef: 'unsigned __int128' 5 | name: __uint128_t 6 | 7 | implicit typedef: '*char' 8 | name: __builtin_ms_va_list 9 | 10 | implicit typedef: '*char' 11 | name: __builtin_va_list 12 | 13 | implicit typedef: 'struct __NSConstantString_tag' 14 | name: __NSConstantString 15 | 16 | variable: '*attributed(int)' 17 | name: a 18 | 19 | variable: 'attributed(int)' 20 | attr: unaligned 21 | name: b 22 | 23 | fn_proto: 'kr (...) int' 24 | name: foo 25 | 26 | fn_proto: 'attributed(kr (...) *int)' 27 | attr: calling_convention cc: stdcall 28 | name: bar 29 | 30 | fn_proto: 'fn (decayed *[]attributed(int), decayed *attributed([]int)) int' 31 | name: baz 32 | 33 | fn_proto: 'fn (fn_ptr: *fn () void) void' 34 | name: quux 35 | 36 | variable: 'unsigned long long' 37 | name: l 38 | 39 | variable: 'unsigned long long' 40 | name: l 41 | 42 | -------------------------------------------------------------------------------- /test/cases/ast/native half type.c: -------------------------------------------------------------------------------- 1 | implicit typedef: '__int128' 2 | name: __int128_t 3 | 4 | implicit typedef: 'unsigned __int128' 5 | name: __uint128_t 6 | 7 | implicit typedef: '*char' 8 | name: __builtin_ms_va_list 9 | 10 | implicit typedef: '[1]struct __va_list_tag' 11 | name: __builtin_va_list 12 | 13 | implicit typedef: 'struct __NSConstantString_tag' 14 | name: __NSConstantString 15 | 16 | implicit typedef: 'long double' 17 | name: __float80 18 | 19 | fn_def: 'fn () void' 20 | name: foo 21 | body: 22 | compound_stmt 23 | variable: '__fp16' 24 | name: x 25 | init: 26 | implicit cast: (float_cast) '__fp16' (value: 1) 27 | float_literal: 'float' (value: 1) 28 | 29 | variable: '__fp16' 30 | name: y 31 | init: 32 | implicit cast: (float_cast) '__fp16' (value: 2) 33 | float_literal: 'float' (value: 2) 34 | 35 | assign_expr: '__fp16' 36 | lhs: 37 | decl_ref_expr: '__fp16' lvalue 38 | name: x 39 | rhs: 40 | add_expr: '__fp16' 41 | lhs: 42 | implicit cast: (lval_to_rval) '__fp16' 43 | decl_ref_expr: '__fp16' lvalue 44 | name: x 45 | rhs: 46 | implicit cast: (lval_to_rval) '__fp16' 47 | decl_ref_expr: '__fp16' lvalue 48 | name: y 49 | 50 | implicit return_stmt: 'void' 51 | 52 | -------------------------------------------------------------------------------- /test/cases/ast/nullability.c: -------------------------------------------------------------------------------- 1 | implicit typedef: '__int128' 2 | name: __int128_t 3 | 4 | implicit typedef: 'unsigned __int128' 5 | name: __uint128_t 6 | 7 | implicit typedef: '*char' 8 | name: __builtin_ms_va_list 9 | 10 | implicit typedef: '[1]struct __va_list_tag' 11 | name: __builtin_va_list 12 | 13 | implicit typedef: 'struct __NSConstantString_tag' 14 | name: __NSConstantString 15 | 16 | implicit typedef: 'long double' 17 | name: __float80 18 | 19 | variable: 'attributed(*int)' 20 | attr: nullability kind: nonnull 21 | name: a 22 | 23 | variable: 'attributed(*int)' 24 | attr: nullability kind: nonnull 25 | name: b 26 | 27 | variable: 'attributed(int)' 28 | attr: nullability kind: nonnull 29 | name: c 30 | 31 | fn_proto: 'attributed(fn () int)' 32 | attr: nullability kind: nullable 33 | name: d 34 | 35 | fn_proto: 'attributed(fn () *int)' 36 | attr: nullability kind: unspecified 37 | name: e 38 | 39 | struct_decl: 'struct __sFILE' 40 | record_field: '*fn (*void) int' 41 | name: _close 42 | field attr: nullability kind: nullable 43 | 44 | typedef: 'struct __sFILE' 45 | name: FILE 46 | 47 | -------------------------------------------------------------------------------- /test/cases/ast/typeof_unqual.c: -------------------------------------------------------------------------------- 1 | implicit typedef: 'unsigned char' 2 | name: char8_t 3 | 4 | implicit typedef: '__int128' 5 | name: __int128_t 6 | 7 | implicit typedef: 'unsigned __int128' 8 | name: __uint128_t 9 | 10 | implicit typedef: '*char' 11 | name: __builtin_ms_va_list 12 | 13 | implicit typedef: '[1]struct __va_list_tag' 14 | name: __builtin_va_list 15 | 16 | implicit typedef: 'struct __NSConstantString_tag' 17 | name: __NSConstantString 18 | 19 | implicit typedef: 'long double' 20 | name: __float80 21 | 22 | variable: 'const int' 23 | name: a 24 | 25 | variable: 'const typeof(: const int)' 26 | name: b 27 | 28 | variable: 'typeof(: const int)' 29 | name: c 30 | 31 | -------------------------------------------------------------------------------- /test/cases/attributed anonymous record.c: -------------------------------------------------------------------------------- 1 | struct A{ 2 | union { 3 | char a; 4 | } __attribute__((packed)); 5 | }; 6 | -------------------------------------------------------------------------------- /test/cases/attributed record fields.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-windows-msvc 2 | struct S1 {}; 3 | 4 | struct S2 { 5 | __attribute__((packed)) int x; 6 | }; 7 | 8 | struct S3 { 9 | int __attribute__((packed)) x; 10 | }; 11 | 12 | struct S4 { 13 | int x __attribute__((packed)); 14 | }; 15 | 16 | struct S5 { 17 | __attribute__((packed)) int x, y; 18 | }; 19 | 20 | struct S6 { 21 | int __attribute__((packed)) x, y; 22 | }; 23 | 24 | struct S7 { 25 | int x __attribute__((packed)), y; 26 | }; 27 | 28 | struct S8 { 29 | int x, y __attribute__((packed)); 30 | }; 31 | 32 | struct S9 { 33 | int __attribute__((packed)) x __attribute__((aligned)); 34 | float f; 35 | __attribute__((packed)) long __attribute__((aligned(16))) l __attribute__((warn_if_not_aligned(16))); 36 | }; 37 | 38 | union U1 { 39 | long x; 40 | __attribute__((aligned(32))) int y; 41 | unsigned __attribute__((packed)) z; 42 | }; 43 | 44 | union U2 { 45 | int x __attribute__((packed)), y, __attribute__((packed)) z, w __attribute__((aligned)); 46 | }; 47 | -------------------------------------------------------------------------------- /test/cases/attributed typeof.c: -------------------------------------------------------------------------------- 1 | typedef __attribute__((aligned(16))) int aligned_int; 2 | 3 | void foo(void) { 4 | aligned_int a; 5 | __attribute__((aligned(16))) int b; 6 | typeof(a) c; 7 | typeof(aligned_int) d; 8 | typeof(b) e; 9 | } 10 | 11 | #define EXPECTED_TYPES "aligned_int: attributed(int)" "attributed(int)" \ 12 | "typeof(: aligned_int: attributed(int))" \ 13 | "typeof(aligned_int: attributed(int))" \ 14 | "typeof(: attributed(int))" 15 | -------------------------------------------------------------------------------- /test/cases/avr sizeof long.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=avr-freestanding-none 2 | 3 | _Static_assert(sizeof(int) == 2, "wrong sizeof int"); 4 | _Static_assert(sizeof(unsigned) == 2, "wrong sizeof unsigned"); 5 | _Static_assert(sizeof(signed) == 2, "wrong sizeof signed"); 6 | _Static_assert(sizeof(short) == 2, "wrong sizeof short"); 7 | _Static_assert(sizeof(unsigned short) == 2, "wrong sizeof unsigned short"); 8 | _Static_assert(sizeof(signed short) == 2, "wrong sizeof signed short"); 9 | _Static_assert(sizeof(long) == 4, "wrong sizeof long"); 10 | _Static_assert(sizeof(unsigned long) == 4, "wrong sizeof unsigned long"); 11 | _Static_assert(sizeof(signed long) == 4, "wrong sizeof signed long"); 12 | _Static_assert(sizeof(long double) == 4, "wrong sizeof long double"); 13 | _Static_assert(sizeof(long long) == 8, "wrong sizeof long long"); 14 | _Static_assert(sizeof(unsigned long long) == 8, "wrong sizeof unsigned long long"); 15 | _Static_assert(sizeof(signed long long) == 8, "wrong sizeof signed long long"); 16 | -------------------------------------------------------------------------------- /test/cases/basic math.c: -------------------------------------------------------------------------------- 1 | _Static_assert(1 + 1u == 2, "unexpected result"); 2 | -------------------------------------------------------------------------------- /test/cases/binary literal.c: -------------------------------------------------------------------------------- 1 | //aro-args -Wpedantic 2 | void foo() { 3 | 0b11; 4 | } 5 | 6 | #define EXPECTED_ERRORS "binary literal.c:3:3: warning: binary integer literals are a GNU extension [-Wgnu-binary-literal]" 7 | -------------------------------------------------------------------------------- /test/cases/bitfields.c: -------------------------------------------------------------------------------- 1 | int b; 2 | 3 | struct Foo { 4 | float a: 1; 5 | int c: b, d: -1; 6 | int e: 64, f:0; 7 | }; 8 | 9 | #define EXPECTED_ERRORS "bitfields.c:4:10: error: bit-field has non-integer type 'float'" \ 10 | "bitfields.c:5:11: error: expression is not an integer constant expression" \ 11 | "bitfields.c:5:14: error: bit-field has negative width (-1)" \ 12 | "bitfields.c:6:8: error: width of bit-field exceeds width of its type" \ 13 | "bitfields.c:6:15: error: named bit-field has zero width" \ 14 | -------------------------------------------------------------------------------- /test/cases/builtin choose expr.c: -------------------------------------------------------------------------------- 1 | void foo(void) { 2 | int x, y; 3 | __builtin_choose_expr(1, x, 0/0) = 10; 4 | __builtin_choose_expr(0, x/0, y) = 32; 5 | __builtin_choose_expr(x, 1, 2); 6 | int z = __builtin_choose_expr(1>0, 1, (char *)5); 7 | float f = __builtin_choose_expr(0!=0, (char *)10, 1.0f); 8 | } 9 | 10 | #define EXPECTED_ERRORS "builtin choose expr.c:5:27: error: '__builtin_choose_expr' requires a constant expression" 11 | -------------------------------------------------------------------------------- /test/cases/builtin functions.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=powerpc-freestanding-none 2 | int foo(void) { 3 | char c[] = "hello"; 4 | return strlen(c); 5 | } 6 | 7 | void bar(int x) { 8 | __builtin_ppc_trap(x); 9 | } 10 | 11 | void ns_constant_string(void) { 12 | const __NSConstantString *ns_str = __builtin___NSStringMakeConstantString("Hello, world!"); 13 | (void)ns_str; 14 | } 15 | 16 | #define EXPECTED_ERRORS "builtin functions.c:4:12: error: implicitly declaring library function 'strlen' [-Wimplicit-function-declaration]" \ 17 | "builtin functions.c:4:12: note: include the header or explicitly provide a declaration for 'strlen'" \ 18 | 19 | -------------------------------------------------------------------------------- /test/cases/builtin headers.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | /* a */ # /* b */ include /* c */ 6 | 7 | #define HEADER 8 | #include HEADER 9 | -------------------------------------------------------------------------------- /test/cases/builtin macro errors.c: -------------------------------------------------------------------------------- 1 | #if __has_attribute(42) 2 | #endif 3 | 4 | #if __has_attribute aligned 5 | #endif 6 | 7 | #if __has_attribute(aligned 8 | #endif 9 | 10 | #define __has_attribute 42 11 | int x = __has_attribute; 12 | 13 | #if __has_feature(__const__) 14 | #endif 15 | 16 | #define EXPECTED_ERRORS \ 17 | "builtin macro errors.c:1:21: error: builtin feature check macro requires a parenthesized identifier" \ 18 | "builtin macro errors.c:4:5: error: Missing '(' after built-in macro '__has_attribute'" \ 19 | "builtin macro errors.c:7:5: error: unterminated function macro argument list" \ 20 | "builtin macro errors.c:8:28: error: expected value in expression" \ 21 | "builtin macro errors.c:10:9: warning: redefining builtin macro [-Wbuiltin-macro-redefined]" \ 22 | -------------------------------------------------------------------------------- /test/cases/c17 char8_t enabled.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c17 -fchar8_t 2 | 3 | void foo(void) { 4 | char8_t c = 0; 5 | } 6 | 7 | _Static_assert (_Generic (u8"hello", unsigned char*: 1, default: 2) == 1, "Incorrect type for u8 string literal"); 8 | _Static_assert (_Generic (u8"A"[0], unsigned char: 1, default: 2) == 1, "Incorrect type for u8 string literal element"); 9 | 10 | const char cbuf1[] = u8"text"; 11 | const char cbuf2[] = { u8"text" }; 12 | const signed char scbuf1[] = u8"text"; 13 | const signed char scbuf2[] = { u8"text" }; 14 | const unsigned char ucbuf1[] = u8"text"; 15 | const unsigned char ucbuf2[] = { u8"text" }; 16 | const char8_t c8buf1[] = u8"text"; 17 | const char8_t c8buf2[] = { u8"text" }; 18 | const char8_t c8buf3[] = "text"; 19 | const char8_t c8buf4[] = { "text" }; 20 | -------------------------------------------------------------------------------- /test/cases/c17 char8_t.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c17 2 | 3 | void foo(void) { 4 | char8_t c = 0; 5 | } 6 | 7 | _Static_assert (_Generic (u8"hello", char*: 1, default: 2) == 1, "Incorrect type for u8 string literal"); 8 | _Static_assert (_Generic (u8"A"[0], char: 1, default: 2) == 1, "Incorrect type for u8 string literal element"); 9 | 10 | const char cbuf1[] = u8"text"; 11 | const char cbuf2[] = { u8"text" }; 12 | const signed char scbuf1[] = u8"text"; 13 | const signed char scbuf2[] = { u8"text" }; 14 | const unsigned char ucbuf1[] = u8"text"; 15 | const unsigned char ucbuf2[] = { u8"text" }; 16 | 17 | #define EXPECTED_ERRORS "c17 char8_t.c:4:5: error: use of undeclared identifier 'char8_t'" \ 18 | -------------------------------------------------------------------------------- /test/cases/c23 attributes.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | 3 | // Example adapted from N2956 - unsequenced functions 4 | 5 | extern double sqrt(double); 6 | 7 | inline double distance(double const x[static 2]) [[reproducible]] { 8 | extern double sqrt(double) [[unsequenced]]; 9 | return sqrt(x[0]*x[0] + x[1]*x[1]); 10 | } 11 | 12 | int main(void) { 13 | (void) sqrt(2.); 14 | (void) distance((double[]) {1., 2.}); 15 | } 16 | -------------------------------------------------------------------------------- /test/cases/c23 auto.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 --target=x86_64-linux-gnu 2 | auto a(); 3 | 4 | void bad() { 5 | auto a; 6 | auto b = 1, c = 2, d = 3; 7 | auto e[] = ""; 8 | auto f = {1}; 9 | restrict auto g = 1; 10 | } 11 | 12 | void good() { 13 | auto a = 1; 14 | auto b = "foo"; 15 | auto c = good; 16 | } 17 | 18 | #define EXPECTED_ERRORS \ 19 | "c23 auto.c:2:1: error: 'auto' not allowed in function return type" \ 20 | "c23 auto.c:5:10: error: 'auto' requires an initializer" \ 21 | "c23 auto.c:6:5: error: 'auto' can only be used with a single declarator" \ 22 | "c23 auto.c:7:5: error: 'e' declared as array of 'auto'" \ 23 | "c23 auto.c:8:14: error: cannot use 'auto' with array" \ 24 | "c23 auto.c:9:5: error: restrict requires a pointer or reference ('auto' is invalid)" \ 25 | -------------------------------------------------------------------------------- /test/cases/c23 char8_t disabled.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 -fno-char8_t 2 | 3 | void foo(void) { 4 | char8_t c = 0; 5 | } 6 | 7 | _Static_assert(_Generic(u8"hello", char*: 1, default: 2) == 1, "Incorrect type for u8 string literal"); 8 | _Static_assert(_Generic(u8"A"[0], char: 1, default: 2) == 1, "Incorrect type for u8 string literal element"); 9 | 10 | const char cbuf1[] = u8"text"; 11 | const char cbuf2[] = { u8"text" }; 12 | const signed char scbuf1[] = u8"text"; 13 | const signed char scbuf2[] = { u8"text" }; 14 | const unsigned char ucbuf1[] = u8"text"; 15 | const unsigned char ucbuf2[] = { u8"text" }; 16 | 17 | #define EXPECTED_ERRORS "c23 char8_t disabled.c:4:5: error: use of undeclared identifier 'char8_t'" \ 18 | 19 | -------------------------------------------------------------------------------- /test/cases/c23 char8_t.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | 3 | void foo(void) { 4 | char8_t c = 0; 5 | } 6 | 7 | _Static_assert(_Generic(u8"hello", unsigned char*: 1, default: 2) == 1, "Incorrect type for u8 string literal"); 8 | _Static_assert(_Generic(u8"A"[0], unsigned char: 1, default: 2) == 1, "Incorrect type for u8 string literal element"); 9 | 10 | const char cbuf1[] = u8"text"; 11 | const char cbuf2[] = { u8"text" }; 12 | const signed char scbuf1[] = u8"text"; 13 | const signed char scbuf2[] = { u8"text" }; 14 | const unsigned char ucbuf1[] = u8"text"; 15 | const unsigned char ucbuf2[] = { u8"text" }; 16 | const char8_t c8buf1[] = u8"text"; 17 | const char8_t c8buf2[] = { u8"text" }; 18 | const char8_t c8buf3[] = "text"; 19 | const char8_t c8buf4[] = { "text" }; 20 | -------------------------------------------------------------------------------- /test/cases/c23 defines.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | _Static_assert(__STDC_VERSION__ == 202311L, ""); 3 | -------------------------------------------------------------------------------- /test/cases/c23 digit separators.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | _Static_assert(0b1001'0110 == 150); 3 | _Static_assert(1'2wb == 12); -------------------------------------------------------------------------------- /test/cases/c23 identifiers.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c2x 2 | 3 | struct £ { 4 | int x; 5 | }; 6 | 7 | void foo(void) { 8 | int ™ = 0; 9 | int Dž = 0; 10 | int ʶ = 0; 11 | int Ⅸ = 9; 12 | int ڴ = 0; 13 | int ‿ = 0; 14 | int a‿1 = 0; 15 | } 16 | 17 | int à = 1; //NFC_Quick_Check=Maybe 18 | int à = 1; //NFC_Quick_Check=No 19 | 20 | #define EXPECTED_ERRORS "c23 identifiers.c:3:8: error: unexpected character " \ 21 | "c23 identifiers.c:3:1: warning: declaration does not declare anything [-Wmissing-declaration]" \ 22 | "c23 identifiers.c:8:9: error: unexpected character " \ 23 | "c23 identifiers.c:8:11: error: expected identifier or '('" \ 24 | "c23 identifiers.c:13:9: error: unexpected character " \ 25 | "c23 identifiers.c:13:11: error: expected identifier or '('" \ 26 | "c23 identifiers.c:17:5: warning: 'a\\u0300' is not in NFC [-Wnormalized]" \ 27 | "c23 identifiers.c:18:5: warning: 'a\\u0340' is not in NFC [-Wnormalized]" \ 28 | 29 | -------------------------------------------------------------------------------- /test/cases/c23 keywords.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 -pedantic -Wundef 2 | #include 3 | static_assert(1 == 1); 4 | static_assert(alignof(char) == 1); 5 | thread_local int x; 6 | bool b = 1; 7 | int alignas(16) y; 8 | 9 | #define static_assert no 10 | #define alignof no 11 | #define thread_local no 12 | #define bool no 13 | #define alignas no 14 | 15 | typedef typeof(int) MyInt; 16 | 17 | #if false 18 | #error false should expand to 0 19 | #endif 20 | 21 | #if true 22 | #else 23 | #error true should expand to 1 24 | #endif 25 | 26 | #define FOO true 27 | #if FOO 28 | #else 29 | #error true should expand to 1 30 | #endif 31 | 32 | #if true + 1 != 2 33 | #error true should expand to 1 in preprocessor arithmetic 34 | #endif 35 | 36 | #if defined(true) || defined(false) 37 | #error true and false should not be defined 38 | #endif 39 | 40 | #define EXPECTED_ERRORS \ 41 | "c23 keywords.c:9:9: warning: keyword is hidden by macro definition [-Wkeyword-macro]" \ 42 | "c23 keywords.c:10:9: warning: keyword is hidden by macro definition [-Wkeyword-macro]" \ 43 | "c23 keywords.c:11:9: warning: keyword is hidden by macro definition [-Wkeyword-macro]" \ 44 | "c23 keywords.c:12:9: warning: keyword is hidden by macro definition [-Wkeyword-macro]" \ 45 | "c23 keywords.c:13:9: warning: keyword is hidden by macro definition [-Wkeyword-macro]" \ 46 | 47 | -------------------------------------------------------------------------------- /test/cases/c23 missing type specifier.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | #define EXPECTED_ERRORS \ 3 | "c23 missing type specifier.c:4:8: error: a type specifier is required for all declarations" 4 | static x = 5; 5 | -------------------------------------------------------------------------------- /test/cases/c23 static_assert.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | void foo(void) { 3 | _Static_assert(1); 4 | } 5 | -------------------------------------------------------------------------------- /test/cases/c23 stdarg.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | #include 3 | void foo(...) { 4 | va_list va, new; 5 | va_start(va); 6 | int arg = va_arg(va, int); 7 | va_copy(va, new); 8 | va_end(va); 9 | } 10 | -------------------------------------------------------------------------------- /test/cases/c23 true false ast.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 --target=x86_64-linux-gnu 2 | bool a = true; 3 | bool b = false; 4 | bool c = 0; 5 | bool d = 1; 6 | 7 | int e = true; 8 | int f = false; 9 | 10 | int g = true + 1; 11 | -------------------------------------------------------------------------------- /test/cases/c89 standard.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c89 2 | void foo(void) { 3 | int inline = 5; 4 | int restrict = 10; 5 | int typeof = 20; 6 | } 7 | -------------------------------------------------------------------------------- /test/cases/c99 standard.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c99 2 | void foo(void) { 3 | int typeof = 5; 4 | } 5 | -------------------------------------------------------------------------------- /test/cases/call undeclared function with invalid type.c: -------------------------------------------------------------------------------- 1 | struct S { 2 | does_not_exist x; 3 | }; 4 | 5 | void foo(void) { 6 | struct S s = {0}; 7 | bar(s.x); 8 | } 9 | 10 | #define EXPECTED_ERRORS "call undeclared function with invalid type.c:2:5: error: unknown type name 'does_not_exist'" \ 11 | "call undeclared function with invalid type.c:7:5: error: call to undeclared function 'bar'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]" 12 | 13 | -------------------------------------------------------------------------------- /test/cases/cast kinds.c: -------------------------------------------------------------------------------- 1 | //aro-args -Wno-int-conversion --target=x86_64-linux-gnu 2 | union U { 3 | int x; 4 | float y; 5 | }; 6 | 7 | int bar(void) { 8 | return 42; 9 | } 10 | void foo(void) { 11 | int x; 12 | float f; 13 | double d; 14 | int arr[2]; 15 | int *p; 16 | 17 | p = (int *)&f; // bitcast 18 | p = arr; // array_to_pointer 19 | 20 | x = bar(); // function_to_pointer 21 | 22 | _Bool b = p; // pointer_to_bool 23 | 24 | x = p; // pointer_to_int 25 | 26 | x = b; // bool_to_int 27 | 28 | f = b; // bool_to_float 29 | 30 | p = b; // bool_to_pointer 31 | 32 | b = x; // int_to_bool 33 | 34 | f = x; // int_to_float 35 | 36 | p = x; // int_to_pointer 37 | 38 | b = f; //float_to_bool 39 | 40 | x = f; //float_to_int 41 | 42 | x = 1L; // int_cast 43 | 44 | f = d; // float_cast 45 | d = f; // float_cast 46 | 47 | p = 0; // null_to_pointer 48 | 49 | (void)p; // to_void 50 | 51 | union U u; 52 | 53 | u = (union U)x; // to_union 54 | u = (union U)f; // to_union 55 | 56 | void *vp; 57 | vp = p; // bitcast 58 | p = vp; // bitcast 59 | 60 | #pragma GCC diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers" 61 | const int *const_p; 62 | const_p = p; // no_op 63 | p = const_p; // bitcast 64 | 65 | volatile int *volatile_p; 66 | volatile_p = p; // no_op 67 | p = volatile_p; // bitcast 68 | } 69 | -------------------------------------------------------------------------------- /test/cases/cast to union.c: -------------------------------------------------------------------------------- 1 | union U { 2 | int x; 3 | float y; 4 | }; 5 | union Forward; 6 | 7 | void foo(void) { 8 | union U u; 9 | #pragma GCC diagnostic push 10 | #pragma GCC diagnostic warning "-Wpedantic" 11 | u = (union U)1; 12 | #pragma GCC diagnostic pop 13 | 14 | u = (union U)1.0f; 15 | u = (union U)1.0; 16 | (union Forward)1; 17 | (union DoesNotExist)1; 18 | } 19 | 20 | #define EXPECTED_ERRORS "cast to union.c:11:9: warning: cast to union type is a GNU extension [-Wgnu-union-cast]" \ 21 | "cast to union.c:15:9: error: cast to union type from type 'double' not present in union" \ 22 | "cast to union.c:16:5: error: cast to incomplete type 'union Forward'" \ 23 | "cast to union.c:17:5: error: cast to incomplete type 'union DoesNotExist'" \ 24 | 25 | -------------------------------------------------------------------------------- /test/cases/casts.c: -------------------------------------------------------------------------------- 1 | void foo(void) { 2 | struct Foo { 3 | int a; 4 | }; 5 | (struct Foo)1; 6 | (float)(int*)1l; 7 | (int*)1.f; 8 | (const int)1; 9 | const int p_i[] = (typeof(p_i))0; 10 | int a = (char)"foo"; 11 | int b = (float)"foo"; 12 | unsigned long long d = (unsigned long long)"foo"; 13 | 14 | int x = 1; 15 | x ? (void)1 : 1; 16 | (enum E)1; 17 | int *ptr; 18 | ptr = (int *)(void)5; 19 | (enum DoesNotExist)2.0; 20 | } 21 | 22 | #define EXPECTED_ERRORS "casts.c:5:5: error: cannot cast to non arithmetic or pointer type 'struct Foo'" \ 23 | "casts.c:6:5: error: pointer cannot be cast to type 'float'" \ 24 | "casts.c:7:5: error: operand of type 'float' cannot be cast to a pointer type" \ 25 | "casts.c:8:5: warning: cast to type 'const int' will not preserve qualifiers [-Wcast-qualifiers]" \ 26 | "casts.c:9:23: error: cannot cast to non arithmetic or pointer type 'typeof(const int [])' (aka 'const int ')" \ 27 | "casts.c:10:13: warning: cast to smaller integer type 'char' from 'char *' [-Wpointer-to-int-cast]" \ 28 | "casts.c:11:13: error: pointer cannot be cast to type 'float'" \ 29 | "casts.c:16:5: error: cast to incomplete type 'enum E'" \ 30 | "casts.c:18:18: error: operand of type 'void' where arithmetic or pointer type is required" \ 31 | "casts.c:19:5: error: cast to incomplete type 'enum DoesNotExist'" \ 32 | 33 | -------------------------------------------------------------------------------- /test/cases/char literal sign extension.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 -fsigned-char -Wno-multichar 2 | _Static_assert('\xFF' == -1, ""); 3 | _Static_assert(u8'\xFF' == 0xFF, ""); 4 | 5 | #if '\xFF' != -1 6 | #error comparison failed 7 | #endif 8 | 9 | #if u8'\xFF' != 0xFF 10 | #error comparison failed 11 | #endif 12 | 13 | _Static_assert('\x00\xFF' == 255, ""); 14 | _Static_assert('\xFF\xFF' == 65535, ""); 15 | -------------------------------------------------------------------------------- /test/cases/colon after #embed.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | 3 | #embed "embed byte"n: -------------------------------------------------------------------------------- /test/cases/comma operator.c: -------------------------------------------------------------------------------- 1 | //aro-args -Wno-sizeof-array-argument 2 | void foo(void) { 3 | char a[1]; 4 | _Static_assert(sizeof(((void)0, a)) == sizeof(char *), ""); 5 | const int x = 0; 6 | __typeof__(((void) 0, x)) y = 5; 7 | y = 2; 8 | } 9 | -------------------------------------------------------------------------------- /test/cases/comment after define.c: -------------------------------------------------------------------------------- 1 | #define FOO /* comment */ 2 | #if 0 3 | #endif 4 | 5 | #define BAR // comment 6 | #if 0 7 | #endif 8 | -------------------------------------------------------------------------------- /test/cases/complex float16.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | _Static_assert(3.0f16 + 4.0if16 == 2.0f16 + 1.0f16 + 2.0if16 + 2.0if16); 3 | constexpr _Complex _Float16 f = 2.0f16 + 4.0if16; 4 | constexpr _Complex _Float16 f2 = (2.0f16 - 4.0if16); 5 | _Static_assert(f * f2 == 20.f16); 6 | -------------------------------------------------------------------------------- /test/cases/complex init.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=aarch64-macos-musl 2 | void foo(void) { 3 | _Complex double cd = { 1.0, 2.0 }; 4 | _Complex float cf = { 1.0f, 2.0f }; 5 | // _Complex int ci = {1, 2}; // TODO: complx integer initializer 6 | 7 | cd = __builtin_complex(1.0, 2.0); 8 | cf = __builtin_complex(1.0f, 2.0f); 9 | 10 | cd = (_Complex double) { 1.0f, 2.0f}; // convert float literals to double 11 | cf = (_Complex float) { 1.0, 2.0 }; // convert double literals to float 12 | } 13 | -------------------------------------------------------------------------------- /test/cases/complex numbers clang.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 --emulate=clang -pedantic 2 | 3 | void foo(int x, float y) { 4 | _Static_assert(__imag(42) == 0); 5 | _Static_assert(__imag(42.0) == 0.0); 6 | _Static_assert(__imag(x) == 0); 7 | _Static_assert(__imag(y) == 0); 8 | 9 | _Complex double z = (_Complex double){1.0, 2.0}; 10 | z++; 11 | 12 | z = __builtin_complex(2.0, 3); 13 | z = __builtin_complex(2.0, 3.0f); 14 | z = __builtin_complex(2.0, 3.0); 15 | z = ~z; 16 | } 17 | 18 | #define EXPECTED_ERRORS "complex numbers clang.c:6:20: error: static assertion expression is not an integral constant expression" \ 19 | "complex numbers clang.c:7:20: error: static assertion expression is not an integral constant expression" \ 20 | "complex numbers clang.c:9:42: warning: complex initialization specifying real and imaginary components is an extension [-Wcomplex-component-init]" \ 21 | "complex numbers clang.c:10:6: warning: ISO C does not support '++'/'--' on complex type '_Complex double' [-Wpedantic]" \ 22 | "complex numbers clang.c:12:32: error: argument type 'int' is not a real floating point type" \ 23 | "complex numbers clang.c:13:32: error: arguments are of different types ('double' vs 'float')" \ 24 | "complex numbers clang.c:15:9: warning: ISO C does not support '~' for complex conjugation of '_Complex double' [-Wpedantic]" \ 25 | 26 | -------------------------------------------------------------------------------- /test/cases/complex numbers gcc.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 --emulate=gcc 2 | 3 | void foo(int x, float y) { 4 | _Static_assert(__imag(42) == 0); 5 | _Static_assert(__imag(42.0) == 0.0); 6 | _Static_assert(__imag(x) == 0); 7 | _Static_assert(__imag(y) == 0); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /test/cases/compound literals.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | struct A { 3 | int x; 4 | }; 5 | struct B { 6 | struct A a; 7 | int y; 8 | }; 9 | 10 | int *p = (int []){2, 4}; 11 | 12 | void foo(struct A *a) { 13 | (void)a; 14 | } 15 | void bar(void) { 16 | int a = (struct B){ 17 | .y = 1, 18 | .a = {.x = 2}, 19 | }.a.x; 20 | int b = (int []){1,2,3,4,5}[4]; 21 | int c = (int []){1,2,3,4,5}[10]; 22 | foo(&(struct A){.x = 42}); 23 | 24 | char *str1 = "string 1"; 25 | char *str2 = (char []){"string 2"}; 26 | const char *str3 = (const char []){"string 3"}; 27 | } 28 | 29 | void baz() { 30 | &(register int){0}; 31 | &(static thread_local int){0}; 32 | &(extern int){0}; 33 | } 34 | 35 | unsigned long qux(unsigned long x) { 36 | return ((union{unsigned long _x;}){x})._x; 37 | } 38 | 39 | #define EXPECTED_ERRORS \ 40 | "compound literals.c:21:32: warning: array index 10 is past the end of the array [-Warray-bounds]" \ 41 | "compound literals.c:30:5: error: address of register variable requested" \ 42 | "compound literals.c:31:5: warning: expression result unused [-Wunused-value]" \ 43 | "compound literals.c:32:7: error: compound literal cannot have extern storage class" \ 44 | -------------------------------------------------------------------------------- /test/cases/compound stmt fallthrough.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 5; 3 | switch (x) { 4 | case 1: { 5 | __attribute__((fallthrough)); 6 | } 7 | case 2: { 8 | __attribute__((fallthrough)); 9 | } 10 | default: { 11 | 12 | } 13 | } 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /test/cases/concat improperly encoded strings.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vexu/arocc/7339f1b1f1450a769be2aaa2ff9d2a17a728f135/test/cases/concat improperly encoded strings.c -------------------------------------------------------------------------------- /test/cases/constexpr.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 -Wpedantic 2 | 3 | constexpr int a = 1; 4 | static constexpr int b = 2; 5 | thread_local constexpr int c = 3; 6 | 7 | constexpr int foo(constexpr int param) { 8 | auto constexpr a = 1; 9 | register constexpr int b = 2; 10 | return b; 11 | } 12 | 13 | constexpr _BitInt(b) bit = 4; 14 | 15 | int non_const = 4; 16 | constexpr int invalid = non_const; 17 | 18 | constexpr bool const_bool_true = true; 19 | static_assert(const_bool_true); 20 | constexpr bool const_bool_false = false; 21 | static_assert(!const_bool_false); 22 | 23 | struct S { 24 | int x; 25 | int y; 26 | }; 27 | 28 | constexpr struct S s1 = { 1, 2}; 29 | constexpr struct S s2 = { 1, a}; 30 | constexpr struct S s3 = { 1, non_const}; 31 | // constexpr int s1_x = s1.x; 32 | 33 | #define TESTS_SKIPPED 1 34 | 35 | #define EXPECTED_ERRORS "constexpr.c:5:14: error: cannot combine with previous 'thread_local' specifier" \ 36 | "constexpr.c:7:19: error: invalid storage class on function parameter" \ 37 | "constexpr.c:7:1: error: illegal storage class on function" \ 38 | "constexpr.c:13:28: warning: implicit conversion from 'int' to 'signed _BitInt(2)' changes non-zero value from 4 to 0 [-Wconstant-conversion]" \ 39 | "constexpr.c:16:25: error: constexpr variable must be initialized by a constant expression" \ 40 | "constexpr.c:30:30: error: constexpr variable must be initialized by a constant expression" \ 41 | 42 | -------------------------------------------------------------------------------- /test/cases/convertvector.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu -Wno-unused 2 | typedef int i2v __attribute__((__vector_size__(sizeof(float) * 2))); 3 | typedef float f2v __attribute__((__vector_size__(sizeof(float) * 2))); 4 | typedef short s4v __attribute__((__vector_size__(sizeof(short) * 4))); 5 | typedef short s2v __attribute__((__vector_size__(sizeof(short) * 2))); 6 | typedef int i4v __attribute__((__vector_size__(sizeof(int) * 4))); 7 | 8 | void foo(i2v a, f2v b, i4v c) { 9 | __builtin_convertvector(a, f2v); 10 | __builtin_convertvector(a, i4v); 11 | __builtin_convertvector(a, s4v); 12 | __builtin_convertvector(a, s2v); 13 | __builtin_convertvector(b, s2v); 14 | __builtin_convertvector(c, s2v); 15 | __builtin_convertvector(a, int); 16 | __builtin_convertvector(a, 1); 17 | __builtin_convertvector(1, f2v); 18 | } 19 | 20 | #define EXPECTED_ERRORS "convertvector.c:10:5: error: first two arguments to __builtin_convertvector must have the same number of elements" \ 21 | "convertvector.c:11:5: error: first two arguments to __builtin_convertvector must have the same number of elements" \ 22 | "convertvector.c:14:5: error: first two arguments to __builtin_convertvector must have the same number of elements" \ 23 | "convertvector.c:15:5: error: second argument to __builtin_convertvector must be a vector type" \ 24 | "convertvector.c:16:32: error: expected a type" \ 25 | "convertvector.c:17:5: error: first argument to __builtin_convertvector must be a vector type" \ 26 | -------------------------------------------------------------------------------- /test/cases/darwin __float128.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-macos 2 | __float128 q = 0.0; 3 | 4 | #define EXPECTED_ERRORS "darwin __float128.c:2:1: error: __float128 is not supported on this target" \ 5 | 6 | -------------------------------------------------------------------------------- /test/cases/debug dump macro names.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -dN 2 | 3 | #define CHECK_PARTIAL_MATCH 4 | 5 | #define FOO 42 6 | #define BAR FOO 7 | int x = BAR; 8 | #undef FOO 9 | #define FOO 43 10 | -------------------------------------------------------------------------------- /test/cases/debug dump macros and results.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -dD 2 | 3 | #define CHECK_PARTIAL_MATCH 4 | 5 | #define FOO 42 6 | #define BAR FOO 7 | int x = BAR; 8 | #undef FOO 9 | #define FOO 43 10 | -------------------------------------------------------------------------------- /test/cases/debug dump macros.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -dM 2 | 3 | #define CHECK_PARTIAL_MATCH 4 | 5 | #define FOO 42 6 | #define BAR FOO 7 | int x = FOO; 8 | #undef BAR 9 | #define BAR 43 10 | -------------------------------------------------------------------------------- /test/cases/decayed attributed array.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | __attribute__((aligned)) int arr[1] = {0}; 3 | int *ptr = arr; 4 | 5 | void foo(void) { 6 | _Alignas(8) char x[64]; 7 | char *y = &(x)[0]; 8 | } 9 | -------------------------------------------------------------------------------- /test/cases/declspec.c: -------------------------------------------------------------------------------- 1 | //aro-args -fdeclspec --target=x86_64-linux 2 | 3 | #pragma GCC diagnostic ignored "-Wgnu-alignof-expression" 4 | 5 | __declspec(align) int foo; 6 | __declspec(align(16)) int bar; 7 | __declspec(aligned(16)) int baz; 8 | 9 | _Static_assert(_Alignof(bar) == 16, "wrong alignment"); 10 | 11 | #if __has_declspec_attribute(foo) 12 | #error fail 13 | #endif 14 | 15 | #if !__has_declspec_attribute(align) 16 | #error fail 17 | #endif 18 | 19 | typedef int Int1 __declspec(align(8)); 20 | typedef __declspec(align(8)) int Int2; 21 | 22 | _Static_assert(_Alignof(Int2) == 8, ""); 23 | 24 | __declspec(restrict) int *qux(void); // TODO should be allowed 25 | 26 | #define TESTS_SKIPPED 1 27 | #define EXPECTED_ERRORS "declspec.c:7:12: warning: __declspec attribute 'aligned' is not supported [-Wignored-attributes]" \ 28 | "declspec.c:19:18: error: 'declspec' attribute not allowed after declarator" \ 29 | "declspec.c:19:13: note: this declarator" \ 30 | "declspec.c:24:12: warning: attribute 'restrict' ignored on functions [-Wignored-attributes]" \ 31 | -------------------------------------------------------------------------------- /test/cases/deferred macro expansion.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #define F(acc) F_PROGRESS(acc) 3 | #define F_PROGRESS(acc) CONTINUE(F)(acc##X) 4 | #define F_HOOK() F 5 | #define UNROLL(...) __VA_ARGS__ 6 | #define DEFER(op) op EMPTY 7 | #define EMPTY 8 | #define CONTINUE(k) DEFER(k##_HOOK)() 9 | 10 | UNROLL(F_PROGRESS(X)) -------------------------------------------------------------------------------- /test/cases/deref void.c: -------------------------------------------------------------------------------- 1 | void foo(void) { 2 | void *p = 0; 3 | (void)*p; 4 | p = &*p; 5 | } 6 | -------------------------------------------------------------------------------- /test/cases/designated_init.c: -------------------------------------------------------------------------------- 1 | union U { 2 | int a; 3 | float b; 4 | } __attribute__((designated_init)); 5 | struct S { 6 | int a; 7 | float b; 8 | } __attribute__((designated_init)) a = { 1 }; 9 | 10 | #define EXPECTED_ERRORS \ 11 | "designated_init.c:4:18: error: 'designated_init' attribute is only valid on 'struct' type'" \ 12 | "designated_init.c:8:42: warning: positional initialization of field in 'struct' declared with 'designated_init' attribute [-Wdesignated-init]" \ 13 | -------------------------------------------------------------------------------- /test/cases/digraph pretty print.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | %:%: %: <%<%> > <::> 4 | -------------------------------------------------------------------------------- /test/cases/digraphs disabled.c: -------------------------------------------------------------------------------- 1 | //aro-args -fno-digraphs 2 | 3 | void baz(void) { 4 | int x<:5:>; 5 | } 6 | 7 | #define EXPECTED_ERRORS "digraphs disabled.c:4:10: error: expected ';', found '<'" 8 | -------------------------------------------------------------------------------- /test/cases/digraphs enabled.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c89 -fdigraphs 2 | 3 | #define STRINGIZE(X) %:X 4 | #define PASTE(X, Y) (X %:%: Y) 5 | 6 | void baz(void) <% 7 | int int_arr<::> = <%1%>; 8 | char char_arr<::> = STRINGIZE(HELLO); 9 | char no_digraph[] = "<::>"; 10 | 11 | _Static_assert(sizeof(int_arr) == sizeof(int), "wrong size"); 12 | _Static_assert(PASTE(1,2) == 12, "bad token pasting"); 13 | _Static_assert(sizeof(char_arr) == sizeof("HELLO"), "bad stringize"); 14 | _Static_assert(sizeof(no_digraph) == 5, "string literals should not produce digraph tokens"); 15 | %> 16 | -------------------------------------------------------------------------------- /test/cases/digraphs not supported.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c89 2 | 3 | void baz(void) { 4 | int x<:5:>; 5 | } 6 | 7 | #define EXPECTED_ERRORS "digraphs not supported.c:4:10: error: expected ';', found '<'" 8 | -------------------------------------------------------------------------------- /test/cases/digraphs.c: -------------------------------------------------------------------------------- 1 | //aro-args -DSTRINGIZE(X)=%:X 2 | 3 | #define PASTE(X, Y) (X %:%: Y) 4 | 5 | void baz(void) <% 6 | int int_arr<::> = <%1%>; 7 | char char_arr<::> = STRINGIZE(HELLO); 8 | char no_digraph[] = "<::>"; 9 | 10 | _Static_assert(sizeof(int_arr) == sizeof(int), "wrong size"); 11 | _Static_assert(PASTE(1,2) == 12, "bad token pasting"); 12 | _Static_assert(sizeof(char_arr) == sizeof("HELLO"), "bad stringify"); 13 | _Static_assert(sizeof(no_digraph) == 5, "string literals should not produce digraph tokens"); 14 | %> 15 | -------------------------------------------------------------------------------- /test/cases/divide by zero.c: -------------------------------------------------------------------------------- 1 | void foo(void) { 2 | int x = 10; 3 | (void)(x/0); 4 | (void)(x%0); 5 | x /= 0; 6 | x %= 0; 7 | (void)(0/0); 8 | (void)(1%0); 9 | _Static_assert(1/0, "unavailable"); 10 | float f = 0.0f / 0.0f; 11 | f /= 0.0f; 12 | x = 1 / 2.0f; 13 | } 14 | 15 | #define EXPECTED_ERRORS \ 16 | "divide by zero.c:3:13: warning: division by zero is undefined [-Wdivision-by-zero]" \ 17 | "divide by zero.c:4:13: warning: remainder by zero is undefined [-Wdivision-by-zero]" \ 18 | "divide by zero.c:5:7: warning: division by zero is undefined [-Wdivision-by-zero]" \ 19 | "divide by zero.c:6:7: warning: remainder by zero is undefined [-Wdivision-by-zero]" \ 20 | "divide by zero.c:7:13: warning: division by zero is undefined [-Wdivision-by-zero]" \ 21 | "divide by zero.c:8:13: warning: remainder by zero is undefined [-Wdivision-by-zero]" \ 22 | "divide by zero.c:9:21: warning: division by zero is undefined [-Wdivision-by-zero]" \ 23 | "divide by zero.c:9:20: error: static assertion expression is not an integral constant expression" \ 24 | -------------------------------------------------------------------------------- /test/cases/dollars in identifiers.c: -------------------------------------------------------------------------------- 1 | void foo$() { } 2 | 3 | void fib() { 4 | int $test; 5 | } 6 | 7 | void ano$ther() {} 8 | 9 | #pragma GCC diagnostic warning "-Wdollar-in-identifier-extension" 10 | 11 | void identi$fier() {} 12 | 13 | void inside() { 14 | int vari$able; 15 | } 16 | 17 | #define EXPECTED_ERRORS "dollars in identifiers.c:11:12: warning: '$' in identifier [-Wdollar-in-identifier-extension]" \ 18 | "dollars in identifiers.c:14:11: warning: '$' in identifier [-Wdollar-in-identifier-extension]" \ 19 | -------------------------------------------------------------------------------- /test/cases/double long.c: -------------------------------------------------------------------------------- 1 | _Complex double long x; 2 | double long y; 3 | -------------------------------------------------------------------------------- /test/cases/duplicate typedef.c: -------------------------------------------------------------------------------- 1 | typedef long foo; 2 | typedef long foo; 3 | _Static_assert(__builtin_types_compatible_p(long, foo), ""); 4 | 5 | typedef foo bar; 6 | typedef foo bar; 7 | _Static_assert(__builtin_types_compatible_p(bar, foo), ""); 8 | -------------------------------------------------------------------------------- /test/cases/empty computed include.c: -------------------------------------------------------------------------------- 1 | #define FOO 2 | #include FOO 3 | 4 | #define EXPECTED_ERRORS "empty computed include.c:2:10: error: expected \"FILENAME\" or " \ 5 | 6 | -------------------------------------------------------------------------------- /test/cases/empty macro block expansion.c: -------------------------------------------------------------------------------- 1 | //aro-args -P -E 2 | #define CONTINUE(k) DEFER(k##_HOOK)() 3 | #define DEFER(op) op EMPTY 4 | #define EMPTY 5 | #define F_HOOK() F 6 | 7 | CONTINUE( F) 8 | CONTINUE(F) 9 | -------------------------------------------------------------------------------- /test/cases/empty records.c: -------------------------------------------------------------------------------- 1 | #pragma GCC diagnostic warning "-Wgnu-empty-struct" 2 | #pragma GCC diagnostic warning "-Wc++-compat" 3 | 4 | struct {}s; 5 | union {}u; 6 | 7 | #define EXPECTED_ERRORS "empty records.c:4:1: warning: empty struct is a GNU extension [-Wgnu-empty-struct]" \ 8 | "empty records.c:4:1: warning: empty struct has size 0 in C, size 1 in C++ [-Wc++-compat]" \ 9 | "empty records.c:5:1: warning: empty union is a GNU extension [-Wgnu-empty-struct]" \ 10 | "empty records.c:5:1: warning: empty union has size 0 in C, size 1 in C++ [-Wc++-compat]" \ 11 | -------------------------------------------------------------------------------- /test/cases/empty va args comma delete c99.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -std=c99 -P 2 | 3 | #define ZERO_ARGS(...) foo(a, ##__VA_ARGS__) 4 | 5 | ZERO_ARGS() 6 | ZERO_ARGS(b) 7 | -------------------------------------------------------------------------------- /test/cases/empty.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vexu/arocc/7339f1b1f1450a769be2aaa2ff9d2a17a728f135/test/cases/empty.c -------------------------------------------------------------------------------- /test/cases/enum attributes gcc.c: -------------------------------------------------------------------------------- 1 | //aro-args --emulate=gcc 2 | 3 | enum __attribute__((vector_size(32))) VectorSize2 { 4 | A 5 | }; 6 | 7 | #define EXPECTED_ERRORS "enum attributes gcc.c:3:21: error: invalid vector element type 'enum VectorSize2'" \ 8 | 9 | -------------------------------------------------------------------------------- /test/cases/enum fixed _BitInt.c: -------------------------------------------------------------------------------- 1 | enum E: _BitInt(20) { 2 | A, 3 | }; 4 | 5 | void foo(void) { 6 | enum E e = 1; 7 | int x = -e; 8 | } -------------------------------------------------------------------------------- /test/cases/enum pointer.c: -------------------------------------------------------------------------------- 1 | enum E { 2 | A, 3 | }; 4 | 5 | void foo(void) { 6 | int x; 7 | unsigned y; 8 | enum E *p1 = &x; 9 | enum E *p2 = &y; 10 | } 11 | 12 | #if __WIN32__ 13 | #define EXPECTED_ERRORS "enum pointer.c:9:18: warning: incompatible pointer types initializing 'enum E *' from incompatible type 'unsigned int *' converts between pointers to integer types with different sign [-Wpointer-sign]" \ 14 | 15 | #else 16 | #define EXPECTED_ERRORS "enum pointer.c:8:18: warning: incompatible pointer types initializing 'enum E *' from incompatible type 'int *' [-Wincompatible-pointer-types]" \ 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /test/cases/enum sizes linux.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | 3 | enum Small { 4 | A 5 | } __attribute__((packed)); 6 | 7 | _Static_assert(sizeof(enum Small) == 1, "Small"); 8 | 9 | enum __attribute__((packed)) StillSmall { 10 | B = 255 11 | }; 12 | 13 | _Static_assert(sizeof(enum StillSmall) == 1, "StillSmall"); 14 | 15 | enum Medium { 16 | C = 255, 17 | D 18 | } __attribute__((packed)); 19 | 20 | _Static_assert(sizeof(enum Medium) == 2, "Medium"); 21 | 22 | enum StillMedium { 23 | E = -32768, 24 | F = 32767 25 | } __attribute__((packed)); 26 | 27 | _Static_assert(sizeof(enum StillMedium) == 2, "StillMedium"); 28 | 29 | enum Normal { 30 | G = -2147483648, 31 | H = 2147483647 32 | }; 33 | _Static_assert(sizeof(enum Normal) == 4, "Normal"); 34 | 35 | enum Unsigned { 36 | I = 4294967295, 37 | }; 38 | _Static_assert(sizeof(enum Unsigned) == 4, "Unsigned"); 39 | 40 | enum Large { 41 | J = -1, 42 | K = 4294967295 43 | }; 44 | _Static_assert(sizeof(enum Large) == 8, "Large"); 45 | 46 | enum Huge { 47 | L = 18446744073709551615ULL 48 | }; 49 | _Static_assert(sizeof(enum Huge) == 8, "Huge"); 50 | 51 | #pragma GCC diagnostic ignored "-Wenum-too-large" 52 | enum EnumWithInits { 53 | Negative = -2, 54 | Positive = 0xFFFFFFFFFFFFFFFF, 55 | }; 56 | -------------------------------------------------------------------------------- /test/cases/enum sizes windows.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-windows-msvc 2 | 3 | enum Small { 4 | A 5 | } __attribute__((packed)); 6 | 7 | _Static_assert(sizeof(enum Small) == sizeof(int), "Small"); 8 | 9 | enum __attribute__((packed)) StillSmall { 10 | B = 255 11 | }; 12 | 13 | _Static_assert(sizeof(enum StillSmall) == sizeof(int), "StillSmall"); 14 | 15 | enum Medium { 16 | C = 255, 17 | D 18 | } __attribute__((packed)); 19 | 20 | _Static_assert(sizeof(enum Medium) == sizeof(int), "Medium"); 21 | 22 | enum StillMedium { 23 | E = -32768, 24 | F = 32767 25 | } __attribute__((packed)); 26 | 27 | _Static_assert(sizeof(enum StillMedium) == sizeof(int), "StillMedium"); 28 | 29 | enum Normal { 30 | G = -2147483648, 31 | H = 2147483647 32 | }; 33 | _Static_assert(sizeof(enum Normal) == sizeof(int), "Normal"); 34 | 35 | enum Unsigned { 36 | I = 4294967295, 37 | }; 38 | _Static_assert(sizeof(enum Unsigned) == sizeof(int), "Unsigned"); 39 | 40 | enum Large { 41 | J = -1, 42 | K = 4294967295 43 | }; 44 | _Static_assert(sizeof(enum Large) == sizeof(int), "Large"); 45 | 46 | enum Huge { 47 | L = 18446744073709551615ULL 48 | }; 49 | _Static_assert(sizeof(enum Huge) == sizeof(int), "Huge"); 50 | -------------------------------------------------------------------------------- /test/cases/enumerator constants.c: -------------------------------------------------------------------------------- 1 | enum E { 2 | A, 3 | B = 10, 4 | C, 5 | D = 2, 6 | E = -2, 7 | F, 8 | #pragma GCC diagnostic warning "-Wpedantic" 9 | G = -2147483649, 10 | H = 2147483648, 11 | #pragma GCC diagnostic ignored "-Wpedantic" 12 | }; 13 | 14 | _Static_assert(A == 0, "A is wrong"); 15 | _Static_assert(B == 10, "B is wrong"); 16 | _Static_assert(C == 11, "C is wrong"); 17 | _Static_assert(D == 2, "D is wrong"); 18 | _Static_assert(E == -2, "E is wrong"); 19 | _Static_assert(F == -1, "F is wrong"); 20 | 21 | void foo(enum E e) { 22 | switch (e) { 23 | case A: return; 24 | default: return; 25 | } 26 | } 27 | 28 | #if __INT_MAX__ <= 2147483647 // 2 or 4 byte ints 29 | #define EXPECTED_ERRORS \ 30 | "enumerator constants.c:9:5: warning: ISO C restricts enumerator values to range of 'int' (-2147483649 is too small) [-Wpedantic]" \ 31 | "enumerator constants.c:10:5: warning: ISO C restricts enumerator values to range of 'int' (2147483648 is too large) [-Wpedantic]" \ 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /test/cases/expanded/#elifdef.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vexu/arocc/7339f1b1f1450a769be2aaa2ff9d2a17a728f135/test/cases/expanded/#elifdef.c -------------------------------------------------------------------------------- /test/cases/expanded/#elifndef error.c: -------------------------------------------------------------------------------- 1 | int 2 | int 3 | -------------------------------------------------------------------------------- /test/cases/expanded/#elifndef.c: -------------------------------------------------------------------------------- 1 | int 2 | long 3 | -------------------------------------------------------------------------------- /test/cases/expanded/#if constant expression.c: -------------------------------------------------------------------------------- 1 | long 2 | -------------------------------------------------------------------------------- /test/cases/expanded/#ifdef.c: -------------------------------------------------------------------------------- 1 | long 2 | int 3 | -------------------------------------------------------------------------------- /test/cases/expanded/X macro.c: -------------------------------------------------------------------------------- 1 | enum Foo { 2 | Foo_1 = 1, 3 | Foo_2 = 2, 4 | Foo_3 = 3, 5 | Foo_4 = 4, 6 | Foo_5 = 5, 7 | }; 8 | -------------------------------------------------------------------------------- /test/cases/expanded/__VA_OPT__.c: -------------------------------------------------------------------------------- 1 | 1, 2, 3, 4 2 | a + 3 | __VA_OPT__(1) 4 | -------------------------------------------------------------------------------- /test/cases/expanded/__has_attribute with define.c: -------------------------------------------------------------------------------- 1 | 1 2 | 1 + 0 3 | 1 4 | 1 5 | -------------------------------------------------------------------------------- /test/cases/expanded/__line__.c: -------------------------------------------------------------------------------- 1 | void foo(void) { 2 | int x = 7; 3 | int y = 11; 4 | int z = 13; 5 | } 6 | -------------------------------------------------------------------------------- /test/cases/expanded/debug dump macro names.c: -------------------------------------------------------------------------------- 1 | #define FOO 2 | #define BAR 3 | int x = 42; 4 | #undef FOO 5 | #define FOO -------------------------------------------------------------------------------- /test/cases/expanded/debug dump macros and results.c: -------------------------------------------------------------------------------- 1 | #define FOO 42 2 | #define BAR FOO 3 | int x = 42; 4 | #undef FOO 5 | #define FOO 43 -------------------------------------------------------------------------------- /test/cases/expanded/debug dump macros.c: -------------------------------------------------------------------------------- 1 | #define BAR 43 -------------------------------------------------------------------------------- /test/cases/expanded/deferred macro expansion.c: -------------------------------------------------------------------------------- 1 | F_HOOK ()(XXX) 2 | -------------------------------------------------------------------------------- /test/cases/expanded/digraph pretty print.c: -------------------------------------------------------------------------------- 1 | %:%: %: <%<%> > <::> 2 | -------------------------------------------------------------------------------- /test/cases/expanded/empty macro block expansion.c: -------------------------------------------------------------------------------- 1 | F_HOOK () 2 | F_HOOK () 3 | -------------------------------------------------------------------------------- /test/cases/expanded/empty va args comma delete c99.c: -------------------------------------------------------------------------------- 1 | foo(a,) 2 | foo(a,b) 3 | -------------------------------------------------------------------------------- /test/cases/expanded/float header aarch64-linux-gnu.c: -------------------------------------------------------------------------------- 1 | 2 | 15 3 | 2.2204460492503131e-16 4 | 53 5 | 308 6 | 1024 7 | 1.7976931348623157e+308 8 | (-307) 9 | (-1021) 10 | 2.2250738585072014e-308 11 | 36 12 | 6 13 | 1.19209290e-7F 14 | 24 15 | 38 16 | 128 17 | 3.40282347e+38F 18 | (-37) 19 | (-125) 20 | 1.17549435e-38F 21 | 2 22 | 33 23 | 1.92592994438723585305597794258492732e-34L 24 | 113 25 | 4932 26 | 16384 27 | 1.18973149535723176508575932662800702e+4932L 28 | (-4931) 29 | (-16381) 30 | 3.36210314311209350626267781732175260e-4932L 31 | 2 32 | -------------------------------------------------------------------------------- /test/cases/expanded/float header netbsd 6.99.26.c: -------------------------------------------------------------------------------- 1 | 2 | 15 3 | 2.2204460492503131e-16 4 | 53 5 | 308 6 | 1024 7 | 1.7976931348623157e+308 8 | (-307) 9 | (-1021) 10 | 2.2250738585072014e-308 11 | 21 12 | 6 13 | 1.19209290e-7F 14 | 24 15 | 38 16 | 128 17 | 3.40282347e+38F 18 | (-37) 19 | (-125) 20 | 1.17549435e-38F 21 | 2 22 | 18 23 | 1.08420217248550443401e-19L 24 | 64 25 | 4932 26 | 16384 27 | 1.18973149535723176502e+4932L 28 | (-4931) 29 | (-16381) 30 | 3.36210314311209350626e-4932L 31 | 1 32 | -------------------------------------------------------------------------------- /test/cases/expanded/float header x86-64-linux.c: -------------------------------------------------------------------------------- 1 | 2 | 15 3 | 2.2204460492503131e-16 4 | 53 5 | 308 6 | 1024 7 | 1.7976931348623157e+308 8 | (-307) 9 | (-1021) 10 | 2.2250738585072014e-308 11 | 21 12 | 6 13 | 1.19209290e-7F 14 | 24 15 | 38 16 | 128 17 | 3.40282347e+38F 18 | (-37) 19 | (-125) 20 | 1.17549435e-38F 21 | 2 22 | 18 23 | 1.08420217248550443401e-19L 24 | 64 25 | 4932 26 | 16384 27 | 1.18973149535723176502e+4932L 28 | (-4931) 29 | (-16381) 30 | 3.36210314311209350626e-4932L 31 | 0 32 | -------------------------------------------------------------------------------- /test/cases/expanded/function macro expansion.c: -------------------------------------------------------------------------------- 1 | "HI THERE" 2 | HI_THERE 3 | "HI THERE" 4 | 1, (2, 3) 5 | S() 6 | -------------------------------------------------------------------------------- /test/cases/expanded/gnu variadic macros.h: -------------------------------------------------------------------------------- 1 | "2,3,4", 1 __VA_ARGS__ 2,3,4 2 | -------------------------------------------------------------------------------- /test/cases/expanded/incorrect macro arg count.c: -------------------------------------------------------------------------------- 1 | TWO_ARGS 2 | TWO_ARGS 3 | TWO_ARGS 4 | TWO_ARGS 5 | -------------------------------------------------------------------------------- /test/cases/expanded/lazy macro.c: -------------------------------------------------------------------------------- 1 | REC_0_HOOK () 2 | -------------------------------------------------------------------------------- /test/cases/expanded/line counter.c: -------------------------------------------------------------------------------- 1 | 3 0 2 | 4 1 4 2 3 | -------------------------------------------------------------------------------- /test/cases/expanded/macro argument evaluation.c: -------------------------------------------------------------------------------- 1 | AOK 2 | 1 3 | -------------------------------------------------------------------------------- /test/cases/expanded/macro expansion disabled.c: -------------------------------------------------------------------------------- 1 | 1 LOOP_INDIRECTION () (1) 2 | 123 3 | -------------------------------------------------------------------------------- /test/cases/expanded/macro expansion exhaustion.c: -------------------------------------------------------------------------------- 1 | (2 + 2) 2 | -------------------------------------------------------------------------------- /test/cases/expanded/macro re-expansion.c: -------------------------------------------------------------------------------- 1 | z[0] 2 | z[0] 3 | z[0] 4 | z[0] 5 | z[0] 6 | h (s) 7 | 1 8 | 13 9 | z[0] z[0] Z1 10 | 1 TAU(2) 11 | 1 TAU(1) 1 z[0] 12 | -------------------------------------------------------------------------------- /test/cases/expanded/macro self definition.c: -------------------------------------------------------------------------------- 1 | FOO 2 | BAR 3 | BAZ 4 | -------------------------------------------------------------------------------- /test/cases/expanded/macro token pasting order.c: -------------------------------------------------------------------------------- 1 | TEST_0 2 | TEST_M(0) 3 | 1 4 | a bc 5 | -------------------------------------------------------------------------------- /test/cases/expanded/macro unbalanced parens call.c: -------------------------------------------------------------------------------- 1 | FIRST 42 2 | -------------------------------------------------------------------------------- /test/cases/expanded/macro whitespace.c: -------------------------------------------------------------------------------- 1 | "1 2" 2 | "+ /" 3 | "1" 4 | "1 2" 5 | "2" 6 | "3" 7 | "5" 8 | "6" 9 | foo bar 10 | -------------------------------------------------------------------------------- /test/cases/expanded/multiline comment.c: -------------------------------------------------------------------------------- 1 | int I_exist; 2 | int x; 3 | int y; 4 | int foo ; int bar; 5 | -------------------------------------------------------------------------------- /test/cases/expanded/nested #ifs.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vexu/arocc/7339f1b1f1450a769be2aaa2ff9d2a17a728f135/test/cases/expanded/nested #ifs.c -------------------------------------------------------------------------------- /test/cases/expanded/nested macro call.c: -------------------------------------------------------------------------------- 1 | x 2 | x 3 | -------------------------------------------------------------------------------- /test/cases/expanded/nested unterminated macro gcc.c: -------------------------------------------------------------------------------- 1 | "str" str 2 | -------------------------------------------------------------------------------- /test/cases/expanded/nested unterminated macro.c: -------------------------------------------------------------------------------- 1 | "" 2 | -------------------------------------------------------------------------------- /test/cases/expanded/object macro expansion.c: -------------------------------------------------------------------------------- 1 | a 2 | 1 3 | define 4 | -------------------------------------------------------------------------------- /test/cases/expanded/object macro token pasting.c: -------------------------------------------------------------------------------- 1 | a1 2 | a1 3 | -------------------------------------------------------------------------------- /test/cases/expanded/paste operator whitespace.c: -------------------------------------------------------------------------------- 1 | (AY) 2 | -------------------------------------------------------------------------------- /test/cases/expanded/placeholder tokens pasting.c: -------------------------------------------------------------------------------- 1 | x x 2 | y 3 | x ()x 4 | (y) 5 | (x) 6 | -------------------------------------------------------------------------------- /test/cases/expanded/preserve comments in macros.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P -CC 2 | 1 /*foo*//*bar*/ 2 3 | 1 /*foo*//*bar*/ 2 4 | 1 /*foo*/ 5 | 1 /*foo*/ 6 | hello/*foo*/1 7 | -------------------------------------------------------------------------------- /test/cases/expanded/preserve comments.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P -C 2 | 12 3 | 12 4 | 1 5 | 1 6 | hello1 7 | -------------------------------------------------------------------------------- /test/cases/expanded/recursive call non-expanded parens.c: -------------------------------------------------------------------------------- 1 | 1 2 1 bar 2 | -------------------------------------------------------------------------------- /test/cases/expanded/recursive func macro.c: -------------------------------------------------------------------------------- 1 | F(1) 2 | -------------------------------------------------------------------------------- /test/cases/expanded/recursive object macro.c: -------------------------------------------------------------------------------- 1 | x 2 | x 3 | -------------------------------------------------------------------------------- /test/cases/expanded/source epoch.c: -------------------------------------------------------------------------------- 1 | "Jan 1 1970" 2 | "00:00:00" 3 | "Thu Jan 1 00:00:00 1970" 4 | -------------------------------------------------------------------------------- /test/cases/expanded/standard-concatenation-strings-example.c: -------------------------------------------------------------------------------- 1 | printf("x" "1" "= %d, x" "2" "= %s", x1, x2); 2 | fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" 3 | ": @\n", s); 4 | "vers2.h" 5 | "vers2 . h" 6 | "INCFILE(2).h" 7 | "INCFILE(2) . h" 8 | "hello"; 9 | "hello" ", world" 10 | -------------------------------------------------------------------------------- /test/cases/expanded/standard-placeholder-example.c: -------------------------------------------------------------------------------- 1 | int j[] = { 123, 45, 67, 89, 2 | 10, 11, 12, }; 3 | -------------------------------------------------------------------------------- /test/cases/expanded/standard-redefinition-reexamination-example.c: -------------------------------------------------------------------------------- 1 | f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); 2 | f(2 * (2+(3,4)-0,1)) | f(2 * (\~{ } 5)) & f(2 * (0,1)) 3 | ^m(0,1); 4 | int i[] = { 1, 23, 4, 5, }; 5 | char c[2][6] = { "hello", "" }; 6 | -------------------------------------------------------------------------------- /test/cases/expanded/stringify invalid escape.c: -------------------------------------------------------------------------------- 1 | x["" 2 | -------------------------------------------------------------------------------- /test/cases/expanded/token paste delete comma gnu.c: -------------------------------------------------------------------------------- 1 | fprintf (stderr, "foo"); 2 | fprintf (stderr, "foo",); 3 | fprintf (stderr, "foo", "bar"); 4 | foo(a) 5 | foo(a,b) 6 | 1, 7 | -------------------------------------------------------------------------------- /test/cases/expanded/unspecified expansion.c: -------------------------------------------------------------------------------- 1 | 2*9*g 2 | -------------------------------------------------------------------------------- /test/cases/expanded/unterminated macro function at eof gcc.c: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /test/cases/expanded/unterminated macro function at eof.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vexu/arocc/7339f1b1f1450a769be2aaa2ff9d2a17a728f135/test/cases/expanded/unterminated macro function at eof.c -------------------------------------------------------------------------------- /test/cases/expanded/var args macro functions.c: -------------------------------------------------------------------------------- 1 | "2,3,4,5,6" 2 | baz bar 3,4 3 | -------------------------------------------------------------------------------- /test/cases/expanded/whitespace macro arguments.c: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | q 1 4 | 5 | 1 6 | 2 3 7 | 3 8 | -------------------------------------------------------------------------------- /test/cases/expanded/zero argument macro.c: -------------------------------------------------------------------------------- 1 | NO_ARGUMENTS 2 | -------------------------------------------------------------------------------- /test/cases/extended identifiers c99.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c99 2 | 3 | #define Ǻ 42 4 | int fǿǿ(void) { 5 | int Ǿ = Ǻ; 6 | return Ǿ; 7 | } 8 | 9 | int bȁr(void) { 10 | int ™ = 0; 11 | return 0; 12 | } 13 | 14 | int bȁz(void) { 15 | int a١ = 0; 16 | int ١a = 0; 17 | return 0; 18 | } 19 | 20 | int uǿ = 0; 21 | int uǿ1 = 0; 22 | int u8ǿ = 0; 23 | int u8ǿ1 = 0; 24 | int Uǿ = 0; 25 | int Uǿ1 = 0; 26 | int Lǿ = 0; 27 | int Lǿ1 = 0; 28 | 29 | #define EXPECTED_ERRORS "extended identifiers c99.c:10:9: error: unexpected character " \ 30 | "extended identifiers c99.c:10:11: error: expected identifier or '('" \ 31 | "extended identifiers c99.c:16:9: error: character not allowed at the start of an identifier" \ 32 | 33 | -------------------------------------------------------------------------------- /test/cases/extension.c: -------------------------------------------------------------------------------- 1 | __extension__; 2 | __extension__ int a; 3 | 4 | void foo(void) { 5 | __extension__ __auto_type a = 1; 6 | __extension__; 7 | __extension__ 1; 8 | } 9 | 10 | struct Foo { 11 | __extension__; 12 | __extension__ int a; 13 | }; 14 | 15 | #pragma GCC diagnostic warning "-Wextra-semi" 16 | 17 | ; 18 | 19 | __extension__; 20 | __extension__ __extension__ _Static_assert(1, ""); 21 | 22 | __extension__ 23 | 24 | #define EXPECTED_ERRORS "extension.c:6:18: error: expected expression" \ 25 | "extension.c:7:5: warning: expression result unused [-Wunused-value]" \ 26 | "extension.c:11:18: error: expected a type" \ 27 | "extension.c:17:1: warning: extra ';' outside of a function [-Wextra-semi]" \ 28 | "extension.c:22:14: error: expected external declaration" \ 29 | -------------------------------------------------------------------------------- /test/cases/extern variables.c: -------------------------------------------------------------------------------- 1 | extern int foo[]; 2 | extern struct Bar bar; 3 | -------------------------------------------------------------------------------- /test/cases/float array size.c: -------------------------------------------------------------------------------- 1 | void foo(float f) { 2 | int bar[2.0] = {0}; 3 | int baz[f]; 4 | } 5 | 6 | #define EXPECTED_ERRORS "float array size.c:2:13: error: size of array has non-integer type 'double'" \ 7 | "float array size.c:3:13: error: size of array has non-integer type 'float'" \ 8 | -------------------------------------------------------------------------------- /test/cases/float builtins.c: -------------------------------------------------------------------------------- 1 | _Static_assert(__builtin_isinf_sign(__builtin_inf()) == 1, ""); 2 | _Static_assert(__builtin_isinf_sign(2.0) == 0, ""); 3 | _Static_assert(__builtin_isinf_sign(-5.0 / 0.0) == -1, ""); 4 | double d = 10.0; 5 | _Static_assert(__builtin_isinf_sign(d) == 0, ""); 6 | _Static_assert(!__builtin_isinf(d), ""); 7 | 8 | _Static_assert(__builtin_inf() == __builtin_inf(), ""); 9 | _Static_assert(100.0 < __builtin_inf(), ""); 10 | _Static_assert(__builtin_inf() > 0.0, ""); 11 | 12 | _Static_assert(__builtin_isinf(__builtin_inff()), ""); 13 | _Static_assert(__builtin_isinf(__builtin_inf()), ""); 14 | _Static_assert(__builtin_isinf(__builtin_infl()), ""); 15 | _Static_assert(__builtin_isinf(1.0 / 0.0), ""); 16 | _Static_assert(!__builtin_isinf(2.0 + 3.0), ""); 17 | 18 | #define EXPECTED_ERRORS "float builtins.c:5:16: error: static assertion expression is not an integral constant expression" \ 19 | "float builtins.c:6:16: error: static assertion expression is not an integral constant expression" \ 20 | 21 | -------------------------------------------------------------------------------- /test/cases/float eval method.c: -------------------------------------------------------------------------------- 1 | //aro-args -ffp-eval-method=double --target=x86_64-linux-gnu 2 | 3 | void foo(void) { 4 | float a = 1.0f, b = 2.0f; 5 | float c = a + b; 6 | _Complex float ca = 0.0f; 7 | ca = ca + a; 8 | } 9 | -------------------------------------------------------------------------------- /test/cases/float header aarch64-linux-gnu.c: -------------------------------------------------------------------------------- 1 | //aro-args -E --target=aarch64-linux-gnu -std=c11 -ffp-eval-method=extended -P 2 | #include 3 | DBL_DIG 4 | DBL_EPSILON 5 | DBL_MANT_DIG 6 | DBL_MAX_10_EXP 7 | DBL_MAX_EXP 8 | DBL_MAX 9 | DBL_MIN_10_EXP 10 | DBL_MIN_EXP 11 | DBL_MIN 12 | DECIMAL_DIG 13 | FLT_DIG 14 | FLT_EPSILON 15 | FLT_MANT_DIG 16 | FLT_MAX_10_EXP 17 | FLT_MAX_EXP 18 | FLT_MAX 19 | FLT_MIN_10_EXP 20 | FLT_MIN_EXP 21 | FLT_MIN 22 | FLT_RADIX 23 | LDBL_DIG 24 | LDBL_EPSILON 25 | LDBL_MANT_DIG 26 | LDBL_MAX_10_EXP 27 | LDBL_MAX_EXP 28 | LDBL_MAX 29 | LDBL_MIN_10_EXP 30 | LDBL_MIN_EXP 31 | LDBL_MIN 32 | FLT_EVAL_METHOD 33 | -------------------------------------------------------------------------------- /test/cases/float header netbsd 6.99.26.c: -------------------------------------------------------------------------------- 1 | //aro-args -E --target=x86-netbsd.6.99.26-gnu -std=c11 -P 2 | #include 3 | DBL_DIG 4 | DBL_EPSILON 5 | DBL_MANT_DIG 6 | DBL_MAX_10_EXP 7 | DBL_MAX_EXP 8 | DBL_MAX 9 | DBL_MIN_10_EXP 10 | DBL_MIN_EXP 11 | DBL_MIN 12 | DECIMAL_DIG 13 | FLT_DIG 14 | FLT_EPSILON 15 | FLT_MANT_DIG 16 | FLT_MAX_10_EXP 17 | FLT_MAX_EXP 18 | FLT_MAX 19 | FLT_MIN_10_EXP 20 | FLT_MIN_EXP 21 | FLT_MIN 22 | FLT_RADIX 23 | LDBL_DIG 24 | LDBL_EPSILON 25 | LDBL_MANT_DIG 26 | LDBL_MAX_10_EXP 27 | LDBL_MAX_EXP 28 | LDBL_MAX 29 | LDBL_MIN_10_EXP 30 | LDBL_MIN_EXP 31 | LDBL_MIN 32 | FLT_EVAL_METHOD 33 | -------------------------------------------------------------------------------- /test/cases/float header x86-64-linux.c: -------------------------------------------------------------------------------- 1 | //aro-args -E --target=x86_64-linux-gnu -std=c11 -P 2 | #include 3 | DBL_DIG 4 | DBL_EPSILON 5 | DBL_MANT_DIG 6 | DBL_MAX_10_EXP 7 | DBL_MAX_EXP 8 | DBL_MAX 9 | DBL_MIN_10_EXP 10 | DBL_MIN_EXP 11 | DBL_MIN 12 | DECIMAL_DIG 13 | FLT_DIG 14 | FLT_EPSILON 15 | FLT_MANT_DIG 16 | FLT_MAX_10_EXP 17 | FLT_MAX_EXP 18 | FLT_MAX 19 | FLT_MIN_10_EXP 20 | FLT_MIN_EXP 21 | FLT_MIN 22 | FLT_RADIX 23 | LDBL_DIG 24 | LDBL_EPSILON 25 | LDBL_MANT_DIG 26 | LDBL_MAX_10_EXP 27 | LDBL_MAX_EXP 28 | LDBL_MAX 29 | LDBL_MIN_10_EXP 30 | LDBL_MIN_EXP 31 | LDBL_MIN 32 | FLT_EVAL_METHOD 33 | -------------------------------------------------------------------------------- /test/cases/float values.c: -------------------------------------------------------------------------------- 1 | _Static_assert(-1.0 - 1.0 == -2.0, ""); 2 | _Static_assert(-2.0f == -2.0, ""); 3 | _Static_assert(1.0 == (2.0||0), ""); 4 | void foo(void) { 5 | float f = 2.0 || 0; 6 | } 7 | -------------------------------------------------------------------------------- /test/cases/for decl stmt.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | int main(void) { 3 | for (int x=0, y=1; ; x++); 4 | } 5 | -------------------------------------------------------------------------------- /test/cases/forever stmt.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | int main(void) { 3 | for (;;); 4 | } 5 | -------------------------------------------------------------------------------- /test/cases/fp16 parameter aarch64.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=aarch64-linux-gnu 2 | __fp16 foo(__fp16 x) { 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /test/cases/fp16 parameter.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | __fp16 foo(__fp16 param) { 3 | return 0; 4 | } 5 | 6 | #define EXPECTED_ERRORS "fp16 parameter.c:2:19: error: parameters cannot have __fp16 type; did you forget * ?" \ 7 | "fp16 parameter.c:2:11: error: function return value cannot have __fp16 type; did you forget * ?" \ 8 | 9 | -------------------------------------------------------------------------------- /test/cases/function macro expansion.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P -h 2 | 3 | #define HE HI 4 | #define LLO _THERE 5 | #define HELLO "HI THERE" 6 | #define CAT(a,b) a##b 7 | #define XCAT(a,b) CAT(a,b) 8 | #define CALL(fn) fn(HE,LLO) 9 | CAT(HE, LLO) 10 | XCAT(HE, LLO) 11 | CALL(CAT) 12 | 13 | #define FOO(a, b) BAR(a, b) 14 | #define BAR(a, b) a, b 15 | 16 | FOO(1, (2, 3)) 17 | 18 | #define S(...) S() 19 | S() 20 | -------------------------------------------------------------------------------- /test/cases/generated location.c: -------------------------------------------------------------------------------- 1 | __has_attribute(foo) 2 | 3 | #define EXPECTED_ERRORS "generated location.c:1:1: error: expected external declaration" \ 4 | ":1:1: note: expanded from here" \ 5 | -------------------------------------------------------------------------------- /test/cases/generic ast.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | int x = _Generic(5, 3 | int: 42, 4 | double: 32.5 5 | ); 6 | 7 | int y = _Generic(5, 8 | int: 42, 9 | double: 32.5, 10 | default: "string" 11 | ); 12 | 13 | double z = _Generic(5, 14 | default: 32 15 | ); -------------------------------------------------------------------------------- /test/cases/gnu alignof.c: -------------------------------------------------------------------------------- 1 | //aro-args --emulate=gcc 2 | void foo(void) { 3 | (void) _Alignof 2; 4 | (void) _Alignof(2); 5 | } 6 | -------------------------------------------------------------------------------- /test/cases/gnu designated init extension.c: -------------------------------------------------------------------------------- 1 | int x[] = {[1] 2, [3] 4}; 2 | _Static_assert(sizeof(x) == sizeof(int[4]), "Incorrect array size"); 3 | 4 | #define EXPECTED_ERRORS "gnu designated init extension.c:1:16: warning: use of GNU 'missing =' extension in designator [-Wgnu-designator]" \ 5 | "gnu designated init extension.c:1:23: warning: use of GNU 'missing =' extension in designator [-Wgnu-designator]" \ 6 | 7 | -------------------------------------------------------------------------------- /test/cases/gnu pointer arith.c: -------------------------------------------------------------------------------- 1 | //aro-args -Wgnu-pointer-arith 2 | 3 | void foo(void *a, void *b) { 4 | b - a; 5 | a - 1; 6 | a + 1; 7 | ++a; 8 | --a; 9 | b++; 10 | b--; 11 | } 12 | 13 | #define EXPECTED_ERRORS "gnu pointer arith.c:4:7: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\ 14 | "gnu pointer arith.c:5:7: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\ 15 | "gnu pointer arith.c:6:7: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\ 16 | "gnu pointer arith.c:7:5: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\ 17 | "gnu pointer arith.c:8:5: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\ 18 | "gnu pointer arith.c:9:6: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]"\ 19 | "gnu pointer arith.c:10:6: warning: arithmetic on pointers to void is a GNU extension [-Wgnu-pointer-arith]" 20 | -------------------------------------------------------------------------------- /test/cases/gnu variadic macros.h: -------------------------------------------------------------------------------- 1 | //aro-args -E -Wpedantic -P 2 | #define a(foo, args...) #args, foo __VA_ARGS__ args 3 | a(1,2,3,4) 4 | 5 | #define EXPECTED_ERRORS "gnu variadic macros.h:2:20: warning: named variadic macros are a GNU extension [-Wvariadic-macros]" 6 | -------------------------------------------------------------------------------- /test/cases/gnu89 standard.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=gnu89 2 | 3 | void foo() { 4 | typeof(int) x = 5; 5 | } 6 | -------------------------------------------------------------------------------- /test/cases/gnuc version default.c: -------------------------------------------------------------------------------- 1 | _Static_assert(__GNUC__ == 4, ""); 2 | _Static_assert(__GNUC_MINOR__ == 2, ""); 3 | _Static_assert(__GNUC_PATCHLEVEL__ == 1, ""); 4 | -------------------------------------------------------------------------------- /test/cases/gnuc version empty.c: -------------------------------------------------------------------------------- 1 | //aro-args -fgnuc-version= 2 | 3 | #if defined(__GNUC__) || defined(__GNUC_MINOR__) || defined(__GNUC_PATCHLEVEL__) 4 | #error "__GNUC__ macros should not be defined" 5 | #endif 6 | -------------------------------------------------------------------------------- /test/cases/gnuc version override.c: -------------------------------------------------------------------------------- 1 | //aro-args -fgnuc-version=5.3.42 2 | 3 | _Static_assert(__GNUC__ == 5, ""); 4 | _Static_assert(__GNUC_MINOR__ == 3, ""); 5 | _Static_assert(__GNUC_PATCHLEVEL__ == 42, ""); 6 | -------------------------------------------------------------------------------- /test/cases/guard defined outside header.c: -------------------------------------------------------------------------------- 1 | #include "incorrect_guard.h" 2 | #define INCORRECT_GUARD_H 3 | #include "incorrect_guard.h" 4 | -------------------------------------------------------------------------------- /test/cases/guard undef.c: -------------------------------------------------------------------------------- 1 | #include "correct_guard.h" 2 | #undef CORRECT_GUARD_H 3 | #include "correct_guard.h" 4 | 5 | #define EXPECTED_ERRORS \ 6 | "correct_guard.h:3:5: error: redefinition of 'x'" \ 7 | "correct_guard.h:3:5: note: previous definition is here" \ 8 | 9 | -------------------------------------------------------------------------------- /test/cases/hash_hash at func macro start.c: -------------------------------------------------------------------------------- 1 | #define EXPECTED_ERRORS \ 2 | "'##' cannot appear at the start of a macro expansion" 3 | 4 | #define foo(X) ## x 5 | 6 | -------------------------------------------------------------------------------- /test/cases/hello world.c: -------------------------------------------------------------------------------- 1 | extern int printf(const char*, ...); 2 | static int foo(void); 3 | 4 | int main(int argc, char **argv) { 5 | return foo(); 6 | } 7 | 8 | static int foo(void) { 9 | printf("Hello, world!\n"); 10 | return 0; 11 | } 12 | 13 | // TODO re-enable when a backend is available again. 14 | // #if defined __linux__ && defined __x86_64__ 15 | // #define EXPECTED_OUTPUT "Hello, world!\n" 16 | // #else 17 | #define TESTS_SKIPPED 1 18 | // #endif -------------------------------------------------------------------------------- /test/cases/ignored attributes.c: -------------------------------------------------------------------------------- 1 | __attribute__((malloc)) int foo(void); 2 | __attribute__((malloc)) int *bar(void); 3 | 4 | #define EXPECTED_ERRORS "ignored attributes.c:1:16: warning: attribute 'malloc' ignored on functions that do not return pointers [-Wignored-attributes]" \ 5 | 6 | -------------------------------------------------------------------------------- /test/cases/imaginary constants.c: -------------------------------------------------------------------------------- 1 | #pragma GCC diagnostic push 2 | #pragma GCC diagnostic warning "-Wgnu-imaginary-constant" 3 | 4 | void foo(void) { 5 | _Complex double cd = 1.0 + 2.0i; 6 | #pragma GCC diagnostic pop 7 | _Complex float cf = 1.0f + 2.0if; 8 | 9 | _Complex long double cld; 10 | cld = 1.0l + 2.0il; 11 | 12 | #pragma GCC diagnostic warning "-Wgnu-complex-integer" 13 | int _Complex ci = 1i; 14 | #pragma GCC diagnostic ignored "-Wgnu-complex-integer" 15 | _Complex unsigned long cl = 1uli; 16 | } 17 | 18 | #if 1.0i 19 | #endif 20 | 21 | #define EXPECTED_ERRORS "imaginary constants.c:5:32: warning: imaginary constants are a GNU extension [-Wgnu-imaginary-constant]" \ 22 | "imaginary constants.c:18:5: error: floating point literal in preprocessor expression" \ 23 | "imaginary constants.c:13:9: warning: complex integer types are a GNU extension [-Wgnu-complex-integer]" \ 24 | -------------------------------------------------------------------------------- /test/cases/implicit main return zero.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /test/cases/implicitly unsigned literal.c: -------------------------------------------------------------------------------- 1 | _Static_assert(-9223372036854775808LL > 0, "lhs should be unsigned"); 2 | long long x = 9223372036854775808LL; 3 | _Static_assert(0xFFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFE + 1, ""); 4 | 5 | #define EXPECTED_ERRORS \ 6 | "implicitly unsigned literal.c:1:17: warning: integer literal is too large to be represented in a signed integer type, interpreting as unsigned [-Wimplicitly-unsigned-literal]" \ 7 | "implicitly unsigned literal.c:2:15: warning: integer literal is too large to be represented in a signed integer type, interpreting as unsigned [-Wimplicitly-unsigned-literal]" \ 8 | -------------------------------------------------------------------------------- /test/cases/include pragma.c: -------------------------------------------------------------------------------- 1 | #include _Pragma("once") 2 | 3 | #define EXPECTED_ERRORS "include pragma.c:1:10: error: expected \"FILENAME\" or " \ 4 | 5 | -------------------------------------------------------------------------------- /test/cases/include/correct_guard.h: -------------------------------------------------------------------------------- 1 | #ifndef CORRECT_GUARD_H 2 | #define CORRECT_GUARD_H 3 | int x = 42; 4 | #endif // CORRECT_GUARD_H 5 | -------------------------------------------------------------------------------- /test/cases/include/embed byte: -------------------------------------------------------------------------------- 1 | A -------------------------------------------------------------------------------- /test/cases/include/embed data: -------------------------------------------------------------------------------- 1 | Hello, World! -------------------------------------------------------------------------------- /test/cases/include/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vexu/arocc/7339f1b1f1450a769be2aaa2ff9d2a17a728f135/test/cases/include/empty -------------------------------------------------------------------------------- /test/cases/include/global_var.h: -------------------------------------------------------------------------------- 1 | int multiple = 10; 2 | -------------------------------------------------------------------------------- /test/cases/include/global_var_once.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | int once = 10; 3 | -------------------------------------------------------------------------------- /test/cases/include/global_var_once_pragma_operator.h: -------------------------------------------------------------------------------- 1 | _Pragma("once") 2 | int once = 10; 3 | -------------------------------------------------------------------------------- /test/cases/include/incorrect_guard.h: -------------------------------------------------------------------------------- 1 | #ifndef INCORRECT_GUARD_H 2 | // missing #define INCORRECT_GUARD_H 3 | int x = 42; 4 | #endif // INCORRECT_GUARD_H 5 | -------------------------------------------------------------------------------- /test/cases/include/ms-ext/include other.h: -------------------------------------------------------------------------------- 1 | #include "include/other.h" 2 | -------------------------------------------------------------------------------- /test/cases/include/my_include.h: -------------------------------------------------------------------------------- 1 | #define FOO 1 2 | 3 | #include_next // test/cases/include/next/my_include.h 4 | #include_next // test/cases/include/next/other.h 5 | 6 | #if __has_include_next() 7 | #error "Should not exist" 8 | #endif 9 | 10 | #if __has_include_next() 11 | #define HAS_INCLUDE_NEXT_WORKED 1 12 | #endif 13 | 14 | #if __has_include_next("global_var.h") 15 | #error "Should not find this with include_next" 16 | #endif 17 | -------------------------------------------------------------------------------- /test/cases/include/next/my_include.h: -------------------------------------------------------------------------------- 1 | #define BAR 2 2 | -------------------------------------------------------------------------------- /test/cases/include/next/other.h: -------------------------------------------------------------------------------- 1 | #if defined(OTHER_INCLUDED) 2 | #error should not have been included yet 3 | #endif 4 | #define NEXT_OTHER_INCLUDED 1 5 | -------------------------------------------------------------------------------- /test/cases/include/other.h: -------------------------------------------------------------------------------- 1 | #define OTHER_INCLUDED 1 2 | -------------------------------------------------------------------------------- /test/cases/include/test_helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define EXPECT_TYPE(EXPR, TYPE) _Static_assert(__builtin_types_compatible_p(__typeof__(EXPR), TYPE), "") 4 | 5 | #define CAT(X, Y) XCAT(X, Y) 6 | #define XCAT(X, Y) X ## Y 7 | 8 | #define STR(X) XSTR(X) 9 | #define XSTR(X) #X 10 | -------------------------------------------------------------------------------- /test/cases/include/two spaces/three spaces.h: -------------------------------------------------------------------------------- 1 | #define THREE_SPACES_H 1 2 | -------------------------------------------------------------------------------- /test/cases/incorrect guard.c: -------------------------------------------------------------------------------- 1 | #include "incorrect_guard.h" 2 | #include "incorrect_guard.h" 3 | 4 | #define EXPECTED_ERRORS \ 5 | "incorrect_guard.h:3:5: error: redefinition of 'x'" \ 6 | "incorrect_guard.h:3:5: note: previous definition is here" \ 7 | 8 | -------------------------------------------------------------------------------- /test/cases/incorrect macro arg count.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define TWO_ARGS(A, B) A B 4 | 5 | TWO_ARGS() 6 | TWO_ARGS(A) 7 | TWO_ARGS(A, B, C) 8 | TWO_ARGS(,,,) 9 | 10 | #define EXPECTED_ERRORS "incorrect macro arg count.c:5:1: error: expected 2 argument(s) got 1" \ 11 | "incorrect macro arg count.c:6:1: error: expected 2 argument(s) got 1" \ 12 | "incorrect macro arg count.c:7:1: error: expected 2 argument(s) got 3" \ 13 | "incorrect macro arg count.c:8:1: error: expected 2 argument(s) got 4" \ 14 | 15 | -------------------------------------------------------------------------------- /test/cases/incorrect typeof usage.c: -------------------------------------------------------------------------------- 1 | void foo(void) { 2 | unsigned typeof(int) x; 3 | typeof(int) typeof(int) y; 4 | typeof() z; 5 | typeof(int) unsigned w; 6 | } 7 | 8 | #define EXPECTED_ERRORS "incorrect typeof usage.c:2:5: error: 'unsigned typeof' is invalid" \ 9 | "incorrect typeof usage.c:3:5: error: cannot combine with previous 'typeof' specifier" \ 10 | "incorrect typeof usage.c:4:12: error: expected expression" \ 11 | "incorrect typeof usage.c:5:17: error: 'unsigned typeof' is invalid" \ 12 | 13 | -------------------------------------------------------------------------------- /test/cases/indirect macro invocation wrong arg count.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | #define h(x) x(0) 3 | #define s() 4 | h(s) 5 | -------------------------------------------------------------------------------- /test/cases/int128.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 --target=x86_64-linux -Wno-c23-extensions -ffreestanding 2 | #include 3 | _Static_assert(sizeof(int128_t) == __SIZEOF_INT128__); 4 | _Static_assert(INT128_WIDTH == 128); 5 | _Static_assert(UINT128_MAX == 340282366920938463463374607431768211455WBU); 6 | _Static_assert(INT128_MAX == 170141183460469231731687303715884105727WB); 7 | _Static_assert(INT128_MIN == -170141183460469231731687303715884105728WB); 8 | _Static_assert(INT128_C(-170141183460469231731687303715884105728) == -170141183460469231731687303715884105728wb); 9 | _Static_assert(UINT128_C(340282366920938463463374607431768211455) == 340282366920938463463374607431768211455uwb); 10 | -------------------------------------------------------------------------------- /test/cases/integer conversions 32bit.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86-linux-gnu -Wno-c23-extensions 2 | #include "include/test_helpers.h" 3 | 4 | void foo(void) { 5 | EXPECT_TYPE(1U + 1L, unsigned long); 6 | } 7 | -------------------------------------------------------------------------------- /test/cases/integer conversions.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu -Wno-c23-extensions 2 | #include "include/test_helpers.h" 3 | 4 | void foo(void) { 5 | _BitInt(8) x = 0; 6 | EXPECT_TYPE(x + 1, int); 7 | 8 | _BitInt(32) y = 0; 9 | EXPECT_TYPE(y + 1, int); 10 | 11 | _BitInt(33) z = 0; 12 | EXPECT_TYPE(z + 1, _BitInt(33)); 13 | 14 | _Complex unsigned cx = 0; 15 | EXPECT_TYPE(cx + 1L, _Complex long); 16 | 17 | _Complex int cy = 0; 18 | EXPECT_TYPE(cy + 4294967296wb, _Complex _BitInt(34)); 19 | } 20 | -------------------------------------------------------------------------------- /test/cases/integer literal promotion warning clang.c: -------------------------------------------------------------------------------- 1 | //aro-args --emulate=clang 2 | 3 | _Static_assert(__builtin_types_compatible_p(typeof(18446744073709550592), unsigned long long), ""); 4 | 5 | #define EXPECTED_ERRORS "integer literal promotion warning clang.c:3:52: warning: integer literal is too large to be represented in a signed integer type, interpreting as unsigned [-Wimplicitly-unsigned-literal]" 6 | -------------------------------------------------------------------------------- /test/cases/integer literal promotion warning gcc 32.c: -------------------------------------------------------------------------------- 1 | //aro-args --emulate=gcc --target=riscv32-linux-gnu 2 | 3 | _Static_assert(__builtin_types_compatible_p(typeof(18446744073709550592), long long int), ""); 4 | 5 | #define EXPECTED_ERRORS "integer literal promotion warning gcc 32.c:3:52: warning: integer literal is too large to be represented in a signed integer type, interpreting as unsigned [-Wimplicitly-unsigned-literal]" 6 | 7 | -------------------------------------------------------------------------------- /test/cases/integer literal promotion warning gcc 64.c: -------------------------------------------------------------------------------- 1 | //aro-args --emulate=gcc --target=x86_64-linux-gnu 2 | 3 | _Static_assert(__builtin_types_compatible_p(typeof(18446744073709550592), __int128), ""); 4 | 5 | #define EXPECTED_ERRORS "integer literal promotion warning gcc 64.c:3:52: warning: integer literal is too large to be represented in a signed integer type, interpreting as unsigned [-Wimplicitly-unsigned-literal]" 6 | 7 | -------------------------------------------------------------------------------- /test/cases/intmax_t.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | 3 | #include "test_helpers.h" 4 | 5 | _Static_assert(__INTMAX_MAX__ == 9223372036854775807L, ""); 6 | _Static_assert(__INTMAX_WIDTH__ == 64, ""); 7 | EXPECT_TYPE(__INTMAX_TYPE__, long); 8 | EXPECT_TYPE(CAT(0, __INTMAX_C_SUFFIX__), long); 9 | 10 | _Static_assert(__UINTMAX_MAX__ == 18446744073709551615UL, ""); 11 | _Static_assert(__UINTMAX_WIDTH__ == 64, ""); 12 | EXPECT_TYPE(__UINTMAX_TYPE__, unsigned long); 13 | EXPECT_TYPE(CAT(0, __UINTMAX_C_SUFFIX__), unsigned long); 14 | -------------------------------------------------------------------------------- /test/cases/intptr_t.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | 3 | #include "test_helpers.h" 4 | 5 | _Static_assert(__INTPTR_MAX__ == 9223372036854775807L, ""); 6 | _Static_assert(__INTPTR_WIDTH__ == 64, ""); 7 | EXPECT_TYPE(__INTPTR_TYPE__, long); 8 | 9 | _Static_assert(__UINTPTR_MAX__ == 18446744073709551615UL, ""); 10 | _Static_assert(__UINTPTR_WIDTH__ == 64, ""); 11 | EXPECT_TYPE(__UINTPTR_TYPE__, unsigned long); 12 | -------------------------------------------------------------------------------- /test/cases/invalid _BitInt pointer.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | 3 | _BitInt(1) *e= __real__ e; 4 | -------------------------------------------------------------------------------- /test/cases/invalid attributes.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | 3 | struct S { 4 | __attribute__((__aligned__(x(long)))) long a; 5 | __attribute__((packed)) b; 6 | }; 7 | 8 | struct S2 { 9 | __attribute__((__aligned__(char: 1))) long a; 10 | __attribute__((packed)) b; 11 | }; 12 | 13 | void foo(void) { 14 | } 15 | -------------------------------------------------------------------------------- /test/cases/invalid continuation byte at eof.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vexu/arocc/7339f1b1f1450a769be2aaa2ff9d2a17a728f135/test/cases/invalid continuation byte at eof.c -------------------------------------------------------------------------------- /test/cases/invalid epoch.c: -------------------------------------------------------------------------------- 1 | //aro-env SOURCE_DATE_EPOCH=abc 2 | 3 | #define EXPECTED_ERRORS "error: environment variable SOURCE_DATE_EPOCH must expand to a non-negative integer less than or equal to 253402300799" \ 4 | 5 | -------------------------------------------------------------------------------- /test/cases/invalid k&r functions.c: -------------------------------------------------------------------------------- 1 | int invalid1() 2 | int invalid2(x) 3 | 4 | #define EXPECTED_ERRORS "functions.c:1:14: error: expected function body after function declaration" \ 5 | "functions.c:2:14: warning: parameter 'x' was not declared, defaults to 'int' [-Wimplicit-int]" \ 6 | "functions.c:2:16: error: expected function body after function declaration" 7 | -------------------------------------------------------------------------------- /test/cases/keyword hidden by macro.c: -------------------------------------------------------------------------------- 1 | //aro-args -pedantic 2 | #define int foo 3 | #define include hello 4 | #include 5 | #define if then 6 | #define alignof _Alignof 7 | 8 | unsigned x; // only here to suppress -Wempty-translation-unit 9 | 10 | #define EXPECTED_ERRORS "keyword hidden by macro.c:2:9: warning: keyword is hidden by macro definition [-Wkeyword-macro]" \ 11 | "keyword hidden by macro.c:5:9: warning: keyword is hidden by macro definition [-Wkeyword-macro]" \ 12 | 13 | -------------------------------------------------------------------------------- /test/cases/kr_def_deprecated.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | int foo(a, int b, char c, d) 3 | int a; short d; 4 | { 5 | return a; 6 | } 7 | 8 | int baz() { 9 | return bar(1); 10 | // TODO no return-type warning 11 | } 12 | 13 | #define EXPECTED_ERRORS "kr_def_deprecated.c:2:9: error: unknown type name 'a'" \ 14 | "kr_def_deprecated.c:2:27: error: unknown type name 'd'" \ 15 | "kr_def_deprecated.c:2:28: error: expected function body after function declaration" \ 16 | "kr_def_deprecated.c:4:1: error: expected external declaration" \ 17 | "kr_def_deprecated.c:9:12: error: use of undeclared identifier 'bar'" \ 18 | "kr_def_deprecated.c:11:1: warning: non-void function 'baz' does not return a value [-Wreturn-type]" \ 19 | -------------------------------------------------------------------------------- /test/cases/labeled return.c: -------------------------------------------------------------------------------- 1 | int foo(int x) { 2 | bar: 3 | return x; 4 | } 5 | -------------------------------------------------------------------------------- /test/cases/latin1.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vexu/arocc/7339f1b1f1450a769be2aaa2ff9d2a17a728f135/test/cases/latin1.c -------------------------------------------------------------------------------- /test/cases/layout overflow.c: -------------------------------------------------------------------------------- 1 | //aro-args -fdeclspec 2 | 3 | struct S { 4 | char x[2305843009213693952ULL -1]; 5 | char y[2305843009213693952ULL -1]; 6 | }; 7 | 8 | 9 | struct __declspec(align(268435456)) S1 { 10 | char one; 11 | char two[2]; 12 | char eight[8]; 13 | char four[4]; 14 | }; 15 | 16 | struct S2 { 17 | __attribute__((aligned(268435456))) int x; 18 | }; 19 | 20 | union U { 21 | int a; 22 | char bytes[3333333333333333333]; 23 | }; 24 | 25 | 26 | #define EXPECTED_ERRORS "layout overflow.c:3:8: error: type 'struct S' is too large" \ 27 | "layout overflow.c:22:15: error: array is too large" \ 28 | 29 | -------------------------------------------------------------------------------- /test/cases/lazy macro.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define REC_EMPTY 4 | #define REC_DEFER(op) op REC_EMPTY 5 | 6 | #define REC_0_HOOK() REC_0 7 | #define REC_1 REC_DEFER(REC_0_HOOK)() 8 | 9 | REC_1 10 | -------------------------------------------------------------------------------- /test/cases/least and fast int.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 --target=x86_64-macos -ffreestanding 2 | 3 | #include 4 | 5 | _Static_assert(INT_LEAST8_MAX == INT8_MAX); 6 | _Static_assert(INT_LEAST8_MIN == INT8_MIN); 7 | _Static_assert(UINT_LEAST8_MAX == UINT8_MAX); 8 | _Static_assert(INT_FAST8_MAX == INT8_MAX); 9 | _Static_assert(INT_FAST8_MIN == INT8_MIN); 10 | _Static_assert(UINT_FAST8_MAX == UINT8_MAX); 11 | _Static_assert(INT_FAST8_WIDTH == INT8_WIDTH); 12 | 13 | _Static_assert(INT_LEAST16_MAX == INT16_MAX); 14 | _Static_assert(INT_LEAST16_MIN == INT16_MIN); 15 | _Static_assert(UINT_LEAST16_MAX == UINT16_MAX); 16 | _Static_assert(INT_FAST16_MAX == INT16_MAX); 17 | _Static_assert(INT_FAST16_MIN == INT16_MIN); 18 | _Static_assert(UINT_FAST16_MAX == UINT16_MAX); 19 | _Static_assert(INT_FAST16_WIDTH == INT16_WIDTH); 20 | 21 | _Static_assert(INT_LEAST32_MAX == INT32_MAX); 22 | _Static_assert(INT_LEAST32_MIN == INT32_MIN); 23 | _Static_assert(UINT_LEAST32_MAX == UINT32_MAX); 24 | _Static_assert(INT_FAST32_MAX == INT32_MAX); 25 | _Static_assert(INT_FAST32_MIN == INT32_MIN); 26 | _Static_assert(UINT_FAST32_MAX == UINT32_MAX); 27 | _Static_assert(INT_FAST32_WIDTH == INT32_WIDTH); 28 | 29 | _Static_assert(INT_LEAST64_MAX == INT64_MAX); 30 | _Static_assert(INT_LEAST64_MIN == INT64_MIN); 31 | _Static_assert(UINT_LEAST64_MAX == UINT64_MAX); 32 | _Static_assert(INT_FAST64_MAX == INT64_MAX); 33 | _Static_assert(INT_FAST64_MIN == INT64_MIN); 34 | _Static_assert(UINT_FAST64_MAX == UINT64_MAX); 35 | _Static_assert(INT_FAST64_WIDTH == INT64_WIDTH); 36 | -------------------------------------------------------------------------------- /test/cases/limits header.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu -std=c23 2 | 3 | #include 4 | 5 | _Static_assert(CHAR_BIT == 8); 6 | 7 | _Static_assert(BOOL_WIDTH == 8); 8 | _Static_assert(CHAR_WIDTH == 8); 9 | _Static_assert(SCHAR_WIDTH == 8); 10 | _Static_assert(UCHAR_WIDTH == 8); 11 | _Static_assert(SHRT_WIDTH == 16); 12 | _Static_assert(INT_WIDTH == 32); 13 | _Static_assert(UINT_WIDTH == 32); 14 | _Static_assert(LONG_WIDTH == 64); 15 | _Static_assert(ULONG_WIDTH == 64); 16 | 17 | _Static_assert(UCHAR_MAX == 255); 18 | _Static_assert(SCHAR_MAX == 127); 19 | _Static_assert(USHRT_MAX == 65535); 20 | _Static_assert(SHRT_MAX == 32767); 21 | _Static_assert(INT_MAX == 2147483647); 22 | _Static_assert(LONG_MAX == 9223372036854775807L); 23 | 24 | _Static_assert(CHAR_MIN == -128); 25 | _Static_assert(SCHAR_MIN == -128); 26 | _Static_assert(SHRT_MIN == -32768); 27 | _Static_assert(INT_MIN == -2147483648); 28 | _Static_assert(LONG_MIN == -9223372036854775807L - 1L); 29 | _Static_assert(LLONG_MIN == -9223372036854775807L - 1L); 30 | 31 | _Static_assert(UINT_MAX == 4294967295U); 32 | _Static_assert(ULONG_MAX == 18446744073709551615UL); 33 | _Static_assert(ULLONG_MAX == 18446744073709551615UL); 34 | -------------------------------------------------------------------------------- /test/cases/line counter.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #define FOO __LINE__ __COUNTER__ 3 | FOO 4 | FOO FOO 5 | -------------------------------------------------------------------------------- /test/cases/linux __float128.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | void foo(void) { 3 | __float128 q = 0.0; 4 | _Float128 q2 = 0.0; 5 | 6 | q = 1.0q; 7 | q = 1.0f128; 8 | 9 | _Complex __float128 q3; 10 | q3 = 1.0Qi; 11 | q3 = 1.0iQ; 12 | q3 = 1.0f128i; 13 | q3 = 1.0IF128; 14 | } 15 | 16 | _Static_assert(1.F128 + 2.F128 == 3.F128, ""); 17 | -------------------------------------------------------------------------------- /test/cases/macro argument evaluation.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #define FOO(X) X##OK 3 | #define BAR FOO 4 | 5 | #define A 1 6 | 7 | #if BAR(A) 8 | #error Should not error 9 | #endif 10 | 11 | BAR(A) 12 | 13 | #define AOK 1 14 | #if BAR(A) 15 | #error Should error 16 | #endif 17 | 18 | BAR(A) 19 | 20 | #define EXPECTED_ERRORS "macro argument evaluation.c:15:2: error: Should error" \ 21 | 22 | -------------------------------------------------------------------------------- /test/cases/macro backtrace limit.c: -------------------------------------------------------------------------------- 1 | //aro-args -fmacro-backtrace-limit=1 2 | #define FOO(X) X 3 | FOO(2) 4 | 5 | #define EXPECTED_ERRORS "macro backtrace limit.c:3:1: error: expected external declaration" \ 6 | "note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)" \ 7 | "macro backtrace limit.c:3:5: note: expanded from here" \ 8 | 9 | -------------------------------------------------------------------------------- /test/cases/macro backtrace.c: -------------------------------------------------------------------------------- 1 | #define a 1 ## 2 2 | #define b a 3 | #define c b 4 | #define d c 5 | #define e d 6 | #define f e 7 | #define g f 8 | #define h g 9 | #define i h 10 | #define j i 11 | #define k j 12 | a 13 | b 14 | c 15 | d 16 | e 17 | f 18 | g 19 | h 20 | i 21 | j 22 | k 23 | 24 | #define EXPECTED_ERRORS "macro backtrace.c:12:1: error: expected external declaration" \ 25 | "macro backtrace.c:1:11: note: expanded from here" \ 26 | ":1:1: note: expanded from here" \ 27 | -------------------------------------------------------------------------------- /test/cases/macro expansion disabled.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define EMPTY() 4 | #define LOOP_INDIRECTION() LOOP 5 | #define LOOP(x) x LOOP_INDIRECTION EMPTY()() (x) 6 | LOOP(1) 7 | 8 | #define DEFER(id) id EMPTY() 9 | #define EXPAND(...) __VA_ARGS__ 10 | 11 | #define A() 123 12 | EXPAND(DEFER(A)()) 13 | -------------------------------------------------------------------------------- /test/cases/macro expansion exhaustion.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define CREATE_CALL F 4 | #define F(x) (x + 2) 5 | 6 | CREATE_CALL(2) 7 | -------------------------------------------------------------------------------- /test/cases/macro expansion to defined parsed.c: -------------------------------------------------------------------------------- 1 | //aro-args -Wexpansion-to-defined 2 | #define DEFINED defined 3 | 4 | void foo(void) { 5 | int DEFINED = 0; 6 | defined = 1; 7 | } 8 | -------------------------------------------------------------------------------- /test/cases/macro keyword normalization.c: -------------------------------------------------------------------------------- 1 | #define p(x) int x; 2 | p(elif) 3 | 4 | int endif; 5 | -------------------------------------------------------------------------------- /test/cases/macro re-expansion.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define f(a) a 4 | #define z z[0] 5 | 6 | #define h(x) f(x(1)) 7 | #define s(x) z 8 | 9 | #define K h(s) 10 | 11 | #define H h 12 | 13 | #define L H 14 | 15 | #define SS (s) 16 | 17 | #define INCOMPLETE f(1 18 | #define g(a, b) a##b 19 | #define INCOMPLETE2 g(1 20 | 21 | #define Z1 z Z2 22 | #define Z2 z Z1 23 | 24 | #define THETA(x) x f 25 | #define TAU(x) x TAU 26 | #define OMEGA(x) TAU(x)(1) THETA(x) 27 | 28 | f(f(z)) 29 | h(s) 30 | K 31 | H(s) 32 | L(s) 33 | H SS 34 | INCOMPLETE) 35 | INCOMPLETE2,3) 36 | Z1 37 | TAU(1)(2) 38 | OMEGA(1)(z) 39 | -------------------------------------------------------------------------------- /test/cases/macro redefinition.c: -------------------------------------------------------------------------------- 1 | #define FOO 1 2 | #define FOO 2 3 | #define FOO 3 4 | #define FOO 3 5 | 6 | #define BAR 1 /* fjfao */ /* fjfao */ 2 7 | #define BAR 1 2 8 | 9 | #define BAZ + /* fjfao */ /* fjfao */ / 10 | #define BAZ +/ 11 | 12 | #define QUX 1 /* FJDLKS */ 13 | #define QUX 1 14 | 15 | #define EXPECTED_ERRORS "macro redefinition.c:2:9: warning: 'FOO' macro redefined [-Wmacro-redefined]" \ 16 | "macro redefinition.c:1:9: note: previous definition is here" \ 17 | "macro redefinition.c:3:9: warning: 'FOO' macro redefined [-Wmacro-redefined]" \ 18 | "macro redefinition.c:2:9: note: previous definition is here" \ 19 | "macro redefinition.c:10:9: warning: 'BAZ' macro redefined [-Wmacro-redefined]" \ 20 | "macro redefinition.c:9:9: note: previous definition is here" \ 21 | -------------------------------------------------------------------------------- /test/cases/macro self definition.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #define FOO FOO 3 | 4 | FOO 5 | 6 | #define BAR BAZ 7 | #define BAZ BAR 8 | 9 | BAR 10 | BAZ 11 | -------------------------------------------------------------------------------- /test/cases/macro token pasting order.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define CAT(a, ...) a ## __VA_ARGS__ 4 | #define M(val) val 5 | #define TEST(c) CAT(TEST_, c) 6 | #define abc 1 7 | 8 | TEST(M(0)) 9 | CAT(TEST_, M(0)) 10 | CAT(ab, c) 11 | CAT(a b, c) 12 | -------------------------------------------------------------------------------- /test/cases/macro unbalanced parens call.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define FIRST(x) x 4 | #define SECOND FIRST 5 | #define THIRD SECOND( FIRST 6 | THIRD 42) 7 | -------------------------------------------------------------------------------- /test/cases/macro whitespace.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #define FOO 1 /* fjfao */ /* fjfao */ 2 3 | 4 | #define BAR + /* fjfao */ /* fjfao */ / 5 | 6 | #define BAZ 1 /* FJDLKS */ 7 | 8 | #define QUX /**/2 9 | 10 | #define MULTI /* 11 | */3 12 | 13 | #define XSTR(s) #s 14 | #define STR(s) XSTR(s) 15 | STR(FOO) 16 | STR(BAR) 17 | STR(BAZ) 18 | STR(1 19 | 2) 20 | STR(QUX) 21 | STR(MULTI) 22 | STR(/* 23 | */5) 24 | STR(/**/6) 25 | 26 | #define x foo bar 27 | x 28 | -------------------------------------------------------------------------------- /test/cases/main wrong return type.c: -------------------------------------------------------------------------------- 1 | float main(void) { 2 | 3 | } 4 | 5 | #define EXPECTED_ERRORS "main wrong return type.c:1:7: warning: return type of 'main' is not 'int' [-Wmain-return-type]" \ 6 | "main wrong return type.c:3:1: warning: non-void function 'main' does not return a value [-Wreturn-type]" \ 7 | 8 | -------------------------------------------------------------------------------- /test/cases/member expr.c: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | int a; 3 | } a; 4 | 5 | void foo(void) { 6 | int a; 7 | a->a; 8 | } 9 | void bar(void) { 10 | a->a; 11 | } 12 | void baz(void) { 13 | a->b; 14 | } 15 | void quux(struct Foo *a) { 16 | a.b; 17 | int b, *c; 18 | b.a; 19 | c.a; 20 | c->a; 21 | } 22 | 23 | char *quuux(char *arg) { 24 | return arg + a.a; 25 | } 26 | 27 | struct Bar { 28 | struct { 29 | union { 30 | int x; 31 | }; 32 | }; 33 | } *b; 34 | 35 | int f1(void) { 36 | return b->x; 37 | } 38 | 39 | struct Foo c[1]; 40 | int f2(void) { 41 | return c->a; 42 | } 43 | 44 | #define EXPECTED_ERRORS "member expr.c:7:8: error: member reference base type 'int' is not a structure or union" \ 45 | "member expr.c:10:8: error: member reference type 'struct Foo' is not a pointer; did you mean to use '.'?" \ 46 | "member expr.c:13:8: error: member reference type 'struct Foo' is not a pointer; did you mean to use '.'?" \ 47 | "member expr.c:13:8: error: no member named 'b' in 'struct Foo'" \ 48 | "member expr.c:16:7: error: member reference type 'struct Foo *' is a pointer; did you mean to use '->'?" \ 49 | "member expr.c:16:7: error: no member named 'b' in 'struct Foo'" \ 50 | "member expr.c:18:7: error: member reference base type 'int' is not a structure or union" \ 51 | "member expr.c:19:7: error: member reference base type 'int *' is not a structure or union" \ 52 | "member expr.c:20:8: error: member reference base type 'int *' is not a structure or union" \ 53 | -------------------------------------------------------------------------------- /test/cases/misplaced attribute.c: -------------------------------------------------------------------------------- 1 | __attribute__ ((aligned (8))) struct S { short f[3]; }; 2 | __attribute__ ((packed)) union U { int x; }; 3 | __attribute__ ((aligned)) enum E { e }; 4 | 5 | #define EXPECTED_ERRORS \ 6 | "misplaced attribute.c:1:18: warning: attribute 'aligned' is ignored, place it after \"struct\" to apply attribute to type declaration [-Wignored-attributes]" \ 7 | "misplaced attribute.c:2:18: warning: attribute 'packed' is ignored, place it after \"union\" to apply attribute to type declaration [-Wignored-attributes]" \ 8 | "misplaced attribute.c:3:18: warning: attribute 'aligned' is ignored, place it after \"enum\" to apply attribute to type declaration [-Wignored-attributes]" \ 9 | -------------------------------------------------------------------------------- /test/cases/missing newline before eof.c: -------------------------------------------------------------------------------- 1 | #pragma GCC diagnostic warning "-Wnewline-eof" 2 | #define EXPECTED_ERRORS "missing newline before eof.c:5:8: warning: no newline at end of file [-Wnewline-eof]" \ 3 | "missing newline before eof.c:5:8: error: expected ';' before end of file" 4 | 5 | int foo -------------------------------------------------------------------------------- /test/cases/missing type specifier.c: -------------------------------------------------------------------------------- 1 | //aro-args 2 | #define EXPECTED_ERRORS \ 3 | "missing type specifier.c:4:8: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]" 4 | static x = 5; 5 | -------------------------------------------------------------------------------- /test/cases/ms-extensions.c: -------------------------------------------------------------------------------- 1 | //aro-args -fms-extensions -Wno-microsoft-include 2 | 3 | #include "include\other.h" 4 | 5 | #ifndef OTHER_INCLUDED 6 | #error backslash in include should work 7 | #endif 8 | 9 | #undef OTHER_INCLUDED 10 | #include "include/ms-ext/include other.h" 11 | 12 | #ifndef OTHER_INCLUDED 13 | #error Microsoft search rule should work 14 | #endif 15 |  16 | don't mind me ;) 17 | -------------------------------------------------------------------------------- /test/cases/msp430 builtin types.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=msp430-other-none 2 | #include 3 | #include 4 | 5 | #if !defined(MSP430) or !defined(__MSP430__) 6 | #error "Missing target macros" 7 | #endif 8 | 9 | _Static_assert(sizeof(int) == 2, "Wrong int size"); 10 | _Static_assert(sizeof(long double) == 8, "Wrong long double size"); 11 | _Static_assert(sizeof(char *) == 2, "Wrong pointer size"); 12 | _Static_assert((char)-1 >= 0, "char should be unsigned"); 13 | _Static_assert(sizeof(ptrdiff_t) == 2, "Wrong ptrdiff_t size"); 14 | _Static_assert(sizeof(size_t) == 2, "Wrong size_t size"); 15 | _Static_assert(sizeof(wchar_t) == 2, "Wrong wchar_t size"); 16 | _Static_assert(_Alignof(char *) == 2, "wrong pointer alignment"); 17 | _Static_assert(_Alignof(int) == 2, "wrong int alignment"); 18 | _Static_assert(_Alignof(long) == 2, "wrong long alignment"); 19 | _Static_assert(_Alignof(long long) == 2, "wrong long long alignment"); 20 | _Static_assert(_Alignof(float) == 2, "wrong float alignment"); 21 | _Static_assert(_Alignof(double) == 2, "wrong double alignment"); 22 | _Static_assert(_Alignof(long double) == 2, "wrong long double alignment"); 23 | 24 | void foo(int x, ... ) 25 | { 26 | va_list list; 27 | char *foo = list; 28 | } 29 | -------------------------------------------------------------------------------- /test/cases/msvc attribute keywords.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86-windows-msvc 2 | int __unaligned * __unaligned a; 3 | int __unaligned b; 4 | int _cdecl foo(); 5 | int *__stdcall bar(); 6 | 7 | int baz(int __unaligned [], int [__unaligned]); 8 | int qux(int __stdcall [], int [__cdecl]); 9 | 10 | void quux(void (__cdecl *fn_ptr)(void)); 11 | 12 | unsigned __int64 l; 13 | unsigned long __int64 l; 14 | 15 | #define EXPECTED_ERRORS \ 16 | ".c:8:13: warning: '__stdcall' only applies to function types; type here is 'int *' [-Wignored-attributes]" \ 17 | ".c:8:32: error: expected ']', found '__cdecl'" \ 18 | ".c:8:31: note: to match this '{'" \ 19 | ".c:10:17: warning: '__cdecl' only applies to function types; type here is 'void (*)(void)' [-Wignored-attributes]" \ 20 | -------------------------------------------------------------------------------- /test/cases/msvc boolean bitfield.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-windows-msvc 2 | 3 | typedef struct { 4 | _Bool a: 4; 5 | _Bool : 2; 6 | _Bool c: 2; 7 | } S; 8 | 9 | _Static_assert(sizeof(S) == 1, ""); 10 | _Static_assert(_Alignof(S) == 1, ""); 11 | -------------------------------------------------------------------------------- /test/cases/msvc flexible array in union.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-windows-msvc 2 | 3 | union Foo { 4 | int x; 5 | float y[]; 6 | long z; 7 | }; 8 | 9 | union Bar { 10 | int x[]; 11 | float y[]; 12 | }; 13 | -------------------------------------------------------------------------------- /test/cases/msvc macros.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-windows-msvc 2 | __pragma(once) 3 | #define PRAGMA(x) __pragma(x) 4 | 5 | PRAGMA(message "foo") 6 | 7 | int __identifier(int); 8 | 9 | __identifier() 10 | __identifier(1) 11 | __identifier(a b) 12 | 13 | #define EXPECTED_ERRORS \ 14 | "msvc macros.c:5:1: note: #pragma message: foo" \ 15 | "msvc macros.c:9:1: error: expected identifier argument" \ 16 | "msvc macros.c:10:14: error: cannot convert a number to an identifier" \ 17 | "msvc macros.c:11:16: error: missing ')', after identifier" \ 18 | -------------------------------------------------------------------------------- /test/cases/msvc zero size array.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-windows-msvc 2 | 3 | typedef int J[]; 4 | 5 | #pragma pack(1) 6 | struct J_packed { 7 | J a; 8 | }; 9 | 10 | _Static_assert(sizeof(J) == 0, "incorrect size"); 11 | _Static_assert(_Alignof(J) == 4, "incorrect alignment"); 12 | 13 | struct J_size { 14 | char a[sizeof(J)+1]; 15 | char b; 16 | }; 17 | 18 | _Static_assert(sizeof(struct J_size) == 2, "incorrect size"); 19 | _Static_assert(_Alignof(struct J_size) == 1, "incorrect alignment"); 20 | 21 | struct J_extra_alignment { 22 | char a; 23 | J b; 24 | }; 25 | struct J_extra_alignment var83; 26 | 27 | _Static_assert(sizeof(J) == 0, ""); 28 | _Static_assert(_Alignof(J) == 4, ""); 29 | 30 | #define EXPECTED_ERRORS "msvc zero size array.c:10:16: warning: sizeof returns 0" \ 31 | "msvc zero size array.c:14:12: warning: sizeof returns 0" \ 32 | "msvc zero size array.c:27:16: warning: sizeof returns 0" \ 33 | 34 | -------------------------------------------------------------------------------- /test/cases/multiline comment.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | /* comment **/ 3 | 4 | int I_exist; 5 | 6 | /* 7 | int I_dont; 8 | */ 9 | 10 | /* */int x; 11 | /* 12 | */int y; 13 | 14 | int foo/**/; int/* 15 | */bar; 16 | -------------------------------------------------------------------------------- /test/cases/nameless param.c: -------------------------------------------------------------------------------- 1 | int xyz(float); 2 | 3 | void foo(int) { 4 | return; 5 | } 6 | 7 | void bar(float, char) { 8 | return; 9 | } 10 | 11 | #define EXPECTED_ERRORS "nameless param.c:3:13: warning: omitting the parameter name in a function definition is a C23 extension [-Wc23-extensions]" \ 12 | "nameless param.c:7:15: warning: omitting the parameter name in a function definition is a C23 extension [-Wc23-extensions]" \ 13 | "nameless param.c:7:21: warning: omitting the parameter name in a function definition is a C23 extension [-Wc23-extensions]" \ 14 | -------------------------------------------------------------------------------- /test/cases/native half type.c: -------------------------------------------------------------------------------- 1 | //aro-args -fnative-half-type --target=x86_64-linux-gnu 2 | void foo(void) { 3 | __fp16 x = 1.0f; 4 | __fp16 y = 2.0f; 5 | x = x + y; 6 | } 7 | -------------------------------------------------------------------------------- /test/cases/negative and too big shift count.c: -------------------------------------------------------------------------------- 1 | void foo(void) { 2 | int a = 0b11 << -32; 3 | int b = 0b11 << 32; 4 | } 5 | 6 | #define EXPECTED_ERRORS "negative and too big shift count.c:2:16: warning: shift count is negative [-Wshift-count-negative]" \ 7 | "negative and too big shift count.c:2:16: warning: overflow in expression; result is '2147483647' [-Winteger-overflow]" \ 8 | "negative and too big shift count.c:3:16: warning: shift count >= width of type [-Wshift-count-overflow]" \ 9 | "negative and too big shift count.c:3:16: warning: overflow in expression; result is '0' [-Winteger-overflow]" 10 | -------------------------------------------------------------------------------- /test/cases/nested #ifs.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define FOO 4 | #ifdef FOO 5 | #ifdef FOO 6 | #else 7 | #endif 8 | #endif 9 | -------------------------------------------------------------------------------- /test/cases/nested attributes.c: -------------------------------------------------------------------------------- 1 | typedef int __attribute__((aligned(1))) ALIGN_1; 2 | typedef ALIGN_1 __attribute__((unused)) UNUSED; 3 | _Static_assert(_Alignof(UNUSED) == 1, ""); 4 | 5 | typedef int __attribute__((aligned(16))) __attribute__((aligned(1))) ALIGN_16; 6 | _Static_assert(_Alignof(ALIGN_16) == 16, ""); 7 | 8 | typedef ALIGN_16 __attribute__((aligned(1))) LOWERED_ALIGNMENT; 9 | _Static_assert(_Alignof(LOWERED_ALIGNMENT) == 1, ""); 10 | 11 | typedef ALIGN_1 __attribute__((aligned(16))) RAISED_ALIGNMENT; 12 | _Static_assert(_Alignof(RAISED_ALIGNMENT) == 16, ""); 13 | 14 | __auto_type ARRAY = (__attribute__((aligned(16))) int[]) {1, 2, 3}; 15 | _Static_assert(_Alignof(__typeof__(ARRAY)) == _Alignof(int *), ""); 16 | -------------------------------------------------------------------------------- /test/cases/nested invalid struct layout.c: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | Bar bar; 3 | }; 4 | 5 | struct Baz { 6 | struct Foo foo; 7 | }; 8 | 9 | #define EXPECTED_ERRORS "nested invalid struct layout.c:2:5: error: unknown type name 'Bar'" 10 | 11 | -------------------------------------------------------------------------------- /test/cases/nested macro call.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define A(x) x 4 | #define B(x) A(x) 5 | 6 | B(B(x)) 7 | A(B(x)) 8 | -------------------------------------------------------------------------------- /test/cases/nested unterminated macro gcc.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P --emulate=gcc 2 | #define str(s) # s 3 | #define xstr(s) str(s) 4 | #define INCFILE(n) str(strcmp( 5 | xstr(INCFILE(2)) INCFILE(2)) 6 | 7 | #define EXPECTED_ERRORS \ 8 | "nested unterminated macro gcc.c:5:6: error: unterminated function macro argument list" \ 9 | "nested unterminated macro gcc.c:4:20: note: expanded from here" \ 10 | "nested unterminated macro gcc.c:5:18: error: unterminated function macro argument list" \ 11 | "nested unterminated macro gcc.c:4:20: note: expanded from here" \ 12 | -------------------------------------------------------------------------------- /test/cases/nested unterminated macro.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #define str(s) # s 3 | #define xstr(s) str(s) 4 | #define INCFILE(n) str(strcmp( 5 | xstr(INCFILE(2)) INCFILE(2)) 6 | 7 | #define EXPECTED_ERRORS \ 8 | "nested unterminated macro.c:5:6: error: unterminated function macro argument list" \ 9 | "nested unterminated macro.c:4:20: note: expanded from here" \ 10 | "nested unterminated macro.c:5:18: error: unterminated function macro argument list" \ 11 | "nested unterminated macro.c:4:20: note: expanded from here" \ 12 | -------------------------------------------------------------------------------- /test/cases/newline splicing.c: -------------------------------------------------------------------------------- 1 | #de\ 2 | fine st\ 3 | r(x) #\ 4 | x 5 | void foo(void) { 6 | const char bar[] = str("\ 7 | "); 8 | _Static_assert(sizeof(bar) == 3, "wrong size"); 9 | const char baz[] = str(a.\ 10 | b); 11 | _Static_assert(sizeof(baz) == 4, "wrong size"); 12 | 13 | int ab\ 14 | c = 5; 15 | abc = 10; 16 | a\ 17 | bc = 5; 18 | 19 | char q\ 20 | ux[] = "\ 21 | ab\ 22 | c"; 23 | _Stat\ 24 | ic_assert(siz\ 25 | eof(qu\ 26 | x) =\ 27 | = 4, "wrong size"); 28 | 29 | } 30 | 31 | int trailing\ 32 | ws = 1; 33 | 34 | #define EXPECTED_ERRORS "newline splicing.c:31:14: warning: backslash and newline separated by space [-Wbackslash-newline-escape]" \ 35 | -------------------------------------------------------------------------------- /test/cases/nl in macro param.c: -------------------------------------------------------------------------------- 1 | #define F(x) x 2 | 3 | int foo(void) { 4 | return F(1 + 5 | 2); 6 | } 7 | -------------------------------------------------------------------------------- /test/cases/no declarations.c: -------------------------------------------------------------------------------- 1 | #pragma GCC diagnostic warning "-Wempty-translation-unit" 2 | #define EXPECTED_ERRORS "no declarations.c:2:58: warning: ISO C requires a translation unit to contain at least one declaration [-Wempty-translation-unit]" 3 | -------------------------------------------------------------------------------- /test/cases/no declspec.c: -------------------------------------------------------------------------------- 1 | //aro-args -fno-declspec --target=x86_64-linux 2 | __declspec(align(4)) int foo; 3 | 4 | #if __has_declspec_attribute(noreturn) 5 | #error "__has_declspec_attribute macro should not work without -fdeclspec" 6 | #endif 7 | 8 | #if __has_declspec_attribute(x) 9 | #error "__has_declspec_attribute macro should not work without -fdeclspec" 10 | #endif 11 | 12 | #define EXPECTED_ERRORS \ 13 | "no declspec.c:2:1: error: '__declspec' attributes are not enabled; use '-fdeclspec' or '-fms-extensions' to enable support for __declspec attributes" \ 14 | -------------------------------------------------------------------------------- /test/cases/no dollars in identifiers.c: -------------------------------------------------------------------------------- 1 | //aro-args -fno-dollars-in-identifiers 2 | #define foo$ bar 3 | void fib() { 4 | int foo$; 5 | } 6 | 7 | #define EXPECTED_ERRORS ":2:12: warning: ISO C99 requires whitespace after the macro name [-Wc99-extensions]" \ 8 | ":4:7: error: expected identifier or '('" \ 9 | ":2:12: note: expanded from here" \ 10 | -------------------------------------------------------------------------------- /test/cases/no inline asm.c: -------------------------------------------------------------------------------- 1 | //aro-args -fno-gnu-inline-asm 2 | 3 | __asm__("foo"); 4 | __asm__(""); 5 | 6 | #define EXPECTED_ERRORS "no inline asm.c:3:8: error: GNU-style inline assembly is disabled" \ 7 | 8 | -------------------------------------------------------------------------------- /test/cases/non string attribute.c: -------------------------------------------------------------------------------- 1 | enum E { 2 | is_deprecated_with_msg __attribute__((deprecated("I am deprecated" = 5 ))), 3 | }; 4 | 5 | #define EXPECTED_ERRORS "non string attribute.c:2:71: error: expression is not assignable" \ 6 | "non string attribute.c:2:53: error: attribute 'deprecated' requires an ordinary string" \ 7 | 8 | -------------------------------------------------------------------------------- /test/cases/nullability.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | int *_Nonnull _Nonnull a; 3 | int _Nonnull *b; 4 | int _Nonnull _Nullable c; 5 | int _Nullable d(void); 6 | 7 | #pragma GCC diagnostic warning "-Wnullability-extension" 8 | int *_Null_unspecified e(void); 9 | #pragma GCC diagnostic pop 10 | 11 | typedef struct __sFILE { 12 | int (* _Nullable _close)(void *); 13 | } FILE; 14 | 15 | #define EXPECTED_ERRORS \ 16 | "nullability.c:2:15: warning: duplicate nullability specifier '_Nonnull' [-Wnullability]" \ 17 | "nullability.c:3:5: error: nullability specifier cannot be applied to non-pointer type 'int'" \ 18 | "nullability.c:4:14: error: nullaibility specifier '_Nullable' conflicts with existing specifier '_Nonnull'" \ 19 | "nullability.c:4:5: error: nullability specifier cannot be applied to non-pointer type 'int'" \ 20 | "nullability.c:5:5: error: nullability specifier cannot be applied to non-pointer type 'int'" \ 21 | "nullability.c:8:6: warning: type nullability specifier '_Null_unspecified' is a Clang extension [-Wnullability-extension]" \ 22 | -------------------------------------------------------------------------------- /test/cases/numbers.c: -------------------------------------------------------------------------------- 1 | int a = 0b; 2 | int b = 0x; 3 | int c = 0b12; 4 | int d = 0b1.2; 5 | double e = 019.5; 6 | double f = 0x12.e; 7 | int g = 0128; 8 | int h = 0iull; 9 | int i = 1e; 10 | double j = 0x1p; 11 | int k = 123LLuf; 12 | float l = 12e+2f; 13 | float m = 12E-2f; 14 | float n = 0x12P+2; 15 | float o = 0x12p-2; 16 | _Static_assert(0xE+0xC == 0xE + 0xC, ""); 17 | double p = 0x1.ep-1; 18 | double q = 0x1.eP-1; 19 | double r = 0x1.Ep-1; 20 | double s = 0x1.EP-1; 21 | double t = 1.ep-1; 22 | double u = 1.pp-1; 23 | 24 | #define EXPECTED_ERRORS "numbers.c:1:9: error: invalid suffix 'b' on integer constant" \ 25 | "numbers.c:2:9: error: invalid suffix 'x' on integer constant" \ 26 | "numbers.c:3:9: error: invalid digit '2' in binary constant" \ 27 | "numbers.c:4:9: error: invalid suffix '.2' on integer constant" \ 28 | "numbers.c:6:12: error: hexadecimal floating constant requires an exponent" \ 29 | "numbers.c:7:9: error: invalid digit '8' in octal constant" \ 30 | "numbers.c:9:9: error: exponent has no digits" \ 31 | "numbers.c:10:12: error: exponent has no digits" \ 32 | "numbers.c:11:9: error: invalid suffix 'LLuf' on integer constant" \ 33 | "numbers.c:16:16: error: invalid suffix '+0xC' on integer constant" \ 34 | "numbers.c:21:12: error: exponent has no digits" \ 35 | "numbers.c:22:12: error: invalid suffix 'pp-1' on floating constant" \ 36 | 37 | -------------------------------------------------------------------------------- /test/cases/object macro expands to function macro.c: -------------------------------------------------------------------------------- 1 | #define FOO(X) X##OK 2 | #define BAR FOO 3 | #define BAZ BAR 4 | 5 | #define A 1 6 | #if BAZ (A) 7 | #endif 8 | -------------------------------------------------------------------------------- /test/cases/object macro expansion.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define x a 4 | x 5 | #define a 1 6 | x 7 | #define y define 8 | y 9 | 10 | #define __restrict restrict 11 | 12 | #define empty 13 | empty 14 | -------------------------------------------------------------------------------- /test/cases/object macro token pasting.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define x a##1 4 | x 5 | #define a 1 6 | x 7 | -------------------------------------------------------------------------------- /test/cases/offsetof.c: -------------------------------------------------------------------------------- 1 | int a = __builtin_offsetof(int, a); 2 | struct A; 3 | int b = __builtin_offsetof(struct A, a); 4 | struct A{ 5 | int *a; 6 | }; 7 | int b = __builtin_offsetof(struct A, b); 8 | int b = __builtin_offsetof(struct A, a[1]); 9 | 10 | struct Foo { 11 | char a; 12 | } __attribute__((packed)); 13 | _Static_assert(__builtin_offsetof(struct Foo, a) == 0, "field Foo.a wrong bit offset"); 14 | _Static_assert(__builtin_bitoffsetof(struct Foo, a) == 0, "field Foo.a wrong bit offset"); 15 | 16 | #define EXPECTED_ERRORS "offsetof.c:1:28: error: offsetof requires struct or union type, 'int' invalid" \ 17 | "offsetof.c:3:28: error: offsetof of incomplete type 'struct A'" \ 18 | "offsetof.c:7:38: error: no member named 'b' in 'struct A'" \ 19 | "offsetof.c:8:39: error: offsetof requires array type, 'int *' invalid" \ 20 | -------------------------------------------------------------------------------- /test/cases/packed member address.c: -------------------------------------------------------------------------------- 1 | struct __attribute__((packed)) Foo { 2 | int x; 3 | }; 4 | struct Foo foo; 5 | int *p = &foo.x; 6 | 7 | 8 | #define EXPECTED_ERRORS "packed member address.c:5:10: warning: taking address of packed member 'x' of class or structure 'Foo' may result in an unaligned pointer value [-Waddress-of-packed-member]" 9 | -------------------------------------------------------------------------------- /test/cases/paste operator whitespace.c: -------------------------------------------------------------------------------- 1 | //aro-args -P -E 2 | #define F(X) (X##Y) 3 | F(A) -------------------------------------------------------------------------------- /test/cases/pic1.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu -fpic 2 | 3 | _Static_assert(__pic__ == 1, ""); 4 | _Static_assert(__PIC__ == 1, ""); 5 | #if defined __pie__ || defined __PIE__ 6 | #error __pie__ and __PIE__ should not be defined 7 | #endif 8 | -------------------------------------------------------------------------------- /test/cases/pic2.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu -fPIC 2 | 3 | _Static_assert(__pic__ == 2, ""); 4 | _Static_assert(__PIC__ == 2, ""); 5 | #if defined __pie__ || defined __PIE__ 6 | #error __pie__ and __PIE__ should not be defined 7 | #endif 8 | -------------------------------------------------------------------------------- /test/cases/pie1.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu -fpie 2 | 3 | _Static_assert(__pic__ == 1, ""); 4 | _Static_assert(__PIC__ == 1, ""); 5 | _Static_assert(__pie__ == 1, ""); 6 | _Static_assert(__PIE__ == 1, ""); 7 | -------------------------------------------------------------------------------- /test/cases/pie2.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu -fPIE 2 | 3 | _Static_assert(__pic__ == 2, ""); 4 | _Static_assert(__PIC__ == 2, ""); 5 | _Static_assert(__pie__ == 2, ""); 6 | _Static_assert(__PIE__ == 2, ""); 7 | -------------------------------------------------------------------------------- /test/cases/placeholder tokens pasting.c: -------------------------------------------------------------------------------- 1 | //aro-args -P -E 2 | 3 | #define CAT(a, b) a##b 4 | #define CAT2(a, b) (a##b) 5 | 6 | x CAT(,)x 7 | CAT(,y) 8 | 9 | x CAT2(,)x 10 | CAT2(,y) 11 | CAT2(x,) 12 | -------------------------------------------------------------------------------- /test/cases/pointer subtraction.c: -------------------------------------------------------------------------------- 1 | #include 2 | ptrdiff_t foo(int x) { 3 | char c[2] = {0, 0}; 4 | const char *p = &c[1]; 5 | return p - &c[0]; 6 | } 7 | -------------------------------------------------------------------------------- /test/cases/pragma changes warning to error in parser.c: -------------------------------------------------------------------------------- 1 | #pragma GCC diagnostic error "-Wint-conversion" 2 | void foo(void) { 3 | int *x = 5; 4 | } 5 | 6 | #define EXPECTED_ERRORS "pragma changes warning to error in parser.c:3:11: error: implicit integer to pointer conversion from 'int' to 'int *' [-Werror,-Wint-conversion]" 7 | -------------------------------------------------------------------------------- /test/cases/pragma during parsing.c: -------------------------------------------------------------------------------- 1 | void foo(void) { 2 | #pragma GCC diagnostic error "-Wint-conversion" 3 | int *x = 5; 4 | #pragma GCC diagnostic ignored "-Wint-conversion" 5 | } 6 | 7 | #define EXPECTED_ERRORS "pragma during parsing.c:3:14: error: implicit integer to pointer conversion from 'int' to 'int *' [-Werror,-Wint-conversion]" 8 | -------------------------------------------------------------------------------- /test/cases/pragma once.c: -------------------------------------------------------------------------------- 1 | #include "include/global_var.h" 2 | #include "include/global_var.h" 3 | 4 | #include "include/global_var_once.h" 5 | #include "include/global_var_once.h" 6 | 7 | #define EXPECTED_ERRORS "global_var.h:1:5: error: redefinition of 'multiple'" \ 8 | "global_var.h:1:5: note: previous definition is here" 9 | -------------------------------------------------------------------------------- /test/cases/pragma poison.c: -------------------------------------------------------------------------------- 1 | #define foo bar 2 | #pragma GCC poison "bar" foo 3 | #pragma GCC poison bar 4 | 5 | int foo; 6 | int bar; 7 | 8 | #define baz(x) 9 | 10 | baz(bar) 11 | 12 | #pragma GCC poison baz 13 | 14 | #define EXPECTED_ERRORS "pragma poison.c:2:20: error: can only poison identifier tokens" \ 15 | "pragma poison.c:6:5: error: attempt to use a poisoned identifier" \ 16 | "pragma poison.c:10:5: error: attempt to use a poisoned identifier" \ 17 | "pragma poison.c:12:20: warning: poisoning existing macro" \ 18 | -------------------------------------------------------------------------------- /test/cases/pragma warning and error.c: -------------------------------------------------------------------------------- 1 | #pragma GCC 2 | 3 | #pragma GCC warning 4 | 5 | #pragma GCC warning non_string 6 | 7 | #pragma GCC warning "A warning" 8 | 9 | #pragma GCC warning ("Another" " warning") 10 | 11 | #pragma GCC error 12 | 13 | #pragma GCC error non_string 14 | 15 | #pragma GCC error ("An error") 16 | 17 | #pragma GCC error "Another" " error" 18 | 19 | #if 0 20 | #pragma GCC error "Should not happen" 21 | #endif 22 | 23 | #define P(s) _Pragma(#s) 24 | 25 | #define foo(x) P(message #x) 26 | foo(bar 1) 27 | foo(baz 2) 28 | 29 | #warning foo \ 30 | bar 31 | 32 | #define EXPECTED_ERRORS "pragma warning and error.c:3:13: error: pragma warning requires string literal" \ 33 | "pragma warning and error.c:5:13: error: pragma warning requires string literal" \ 34 | "pragma warning and error.c:7:13: warning: A warning [-W#pragma-messages]" \ 35 | "pragma warning and error.c:9:13: warning: Another warning [-W#pragma-messages]" \ 36 | "pragma warning and error.c:11:13: error: pragma error requires string literal" \ 37 | "pragma warning and error.c:13:13: error: pragma error requires string literal" \ 38 | "pragma warning and error.c:15:13: error: An error" \ 39 | "pragma warning and error.c:17:13: error: Another error" \ 40 | "pragma warning and error.c:26:1: note: #pragma message: bar 1" \ 41 | "pragma warning and error.c:27:1: note: #pragma message: baz 2" \ 42 | "pragma warning and error.c:29:2: warning: foo bar [-W#warnings]" \ 43 | -------------------------------------------------------------------------------- /test/cases/pragma without terminating newline.c: -------------------------------------------------------------------------------- 1 | #pragma GCC poison foo -------------------------------------------------------------------------------- /test/cases/predefined macros.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c99 2 | void foo(void) { 3 | _Static_assert(__STDC_VERSION__ == 199901, "__STDC_VERSION__ is incorrect"); 4 | (void)__DATE__; 5 | (void)__TIME__; 6 | } 7 | -------------------------------------------------------------------------------- /test/cases/preserve comments in macros.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P -CC 2 | #define a() 1 /*foo*/ ## /*bar*/ 2 3 | a() 4 | 5 | #define b 1 /*foo*/ ## /*bar*/ 2 6 | b 7 | 8 | #define c() 1 /*foo*/ 9 | c() 10 | 11 | #define d 1 /*foo*/ 12 | d 13 | 14 | #define e(p) p ## 1 15 | 16 | e(hello/*foo*/) 17 | 18 | #define EXPECTED_ERRORS \ 19 | "preserve comments in macros.c:2:15: error: pasting formed '/*foo*//*bar*/', an invalid preprocessing token" \ 20 | "preserve comments in macros.c:5:13: error: pasting formed '/*foo*//*bar*/', an invalid preprocessing token" \ 21 | "preserve comments in macros.c:14:14: error: pasting formed '/*foo*/1', an invalid preprocessing token" \ 22 | "preserve comments in macros.c:16:8: note: expanded from here" \ 23 | -------------------------------------------------------------------------------- /test/cases/preserve comments.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P -C 2 | #define a() 1 /*foo*/ ## /*bar*/ 2 3 | a() 4 | 5 | #define b 1 /*foo*/ ## /*bar*/ 2 6 | b 7 | 8 | #define c() 1 /*foo*/ 9 | c() 10 | 11 | #define d 1 /*foo*/ 12 | d 13 | 14 | #define e(p) p ## 1 15 | 16 | e(hello/*foo*/) 17 | -------------------------------------------------------------------------------- /test/cases/promotion edge cases.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | struct S { 3 | unsigned x: 3; 4 | long y: 5; 5 | }; 6 | void foo(void) { 7 | char c = 0; 8 | double d = 2.0; 9 | d = d + c; // promote char to int then to double 10 | struct S s = { .x = 1U, .y = 1L}; 11 | int x = s.x + 1; // unsigned bitfield promotes to int if it fits 12 | int y = s.y + 1; // long bitfield promotes to int if it fits 13 | __fp16 fp16 = 0.0f; 14 | fp16 = fp16 + fp16; // __fp16 casts to float for arithmetic 15 | } 16 | -------------------------------------------------------------------------------- /test/cases/recursive call non-expanded parens.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #define foo(X) 1 bar 3 | #define bar(X) 2 foo 4 | 5 | foo(X)(Y)(Z) 6 | -------------------------------------------------------------------------------- /test/cases/recursive func macro.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define F(x) G(x) 4 | #define G(x) F(x) 5 | 6 | F(1) 7 | -------------------------------------------------------------------------------- /test/cases/recursive object macro.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define y x 4 | #define x y 5 | x 6 | 7 | #undef y 8 | #undef x 9 | 10 | #define x x 11 | x 12 | -------------------------------------------------------------------------------- /test/cases/redefine invalid typedef.c: -------------------------------------------------------------------------------- 1 | typedef float *invalid1 __attribute__((vector_size(8))); 2 | typedef float invalid1; 3 | 4 | #define EXPECTED_ERRORS "redefine invalid typedef.c:1:40: error: invalid vector element type 'float *'" \ 5 | 6 | -------------------------------------------------------------------------------- /test/cases/redefine typedef.c: -------------------------------------------------------------------------------- 1 | typedef int MyInt; 2 | int foo(MyInt MyInt) { 3 | return MyInt; 4 | } 5 | 6 | int MyInt; 7 | 8 | enum E { 9 | Foo, 10 | }; 11 | 12 | typedef int Foo; 13 | 14 | #define EXPECTED_ERRORS "redefine typedef.c:6:5: error: redefinition of 'MyInt' as different kind of symbol" \ 15 | "redefine typedef.c:1:13: note: previous definition is here" \ 16 | "redefine typedef.c:12:13: error: redefinition of 'Foo' as different kind of symbol" \ 17 | "redefine typedef.c:9:2: note: previous definition is here" \ 18 | 19 | -------------------------------------------------------------------------------- /test/cases/repeated preprocessor tokens.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | 3 | #define h(x)0(x(0)0 4 | #define s() 5 | #define K h( 6 | #define H h 7 | #define L H 8 | #define SS 9 | K H()L(s)H SS) 10 | -------------------------------------------------------------------------------- /test/cases/self_include.c: -------------------------------------------------------------------------------- 1 | #define EXPECTED_ERRORS "self_include.c:2:10: error: #include nested too deeply" 2 | #include "self_include.c" 3 | -------------------------------------------------------------------------------- /test/cases/shufflevector.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu -Wno-unused 2 | typedef int i2v __attribute__((__vector_size__(4 * 2))); 3 | typedef int i4v __attribute__((__vector_size__(4 * 4))); 4 | 5 | void foo(i2v a, i2v b, i4v c) { 6 | i4v d = __builtin_shufflevector(a, b, 0, 1, 2, 3); 7 | i2v e = __builtin_shufflevector(a, b, -1, 3); 8 | i4v f = __builtin_shufflevector(a, b, 1, 1); 9 | __builtin_shufflevector(a, c); 10 | __builtin_shufflevector(1, b); 11 | __builtin_shufflevector(a, 1); 12 | __builtin_shufflevector(a, b, -2, 5); 13 | } 14 | 15 | #define EXPECTED_ERRORS "shufflevector.c:8:13: error: initializing 'i4v' (vector of 4 'int' values) from incompatible type '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)" \ 16 | "shufflevector.c:9:5: error: first two arguments to '__builtin_shufflevector' must have the same type" \ 17 | "shufflevector.c:10:29: error: first argument to __builtin_shufflevector must be a vector type" \ 18 | "shufflevector.c:11:32: error: second argument to __builtin_shufflevector must be a vector type" \ 19 | "shufflevector.c:12:35: error: index for __builtin_shufflevector must be positive or -1" \ 20 | "shufflevector.c:12:39: error: index for __builtin_shufflevector must be less than the total number of vector elements" \ 21 | -------------------------------------------------------------------------------- /test/cases/signed char.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=aarch64-linux-gnu -fsigned-char -Wno-integer-overflow 2 | 3 | #if defined __CHAR_UNSIGNED__ 4 | #error char should be signed 5 | #endif 6 | 7 | _Static_assert((char)-1 == -1, "char should be signed"); 8 | _Static_assert((char)0xFF == -1, "char should be signed"); 9 | 10 | #if '\0' - 1 > 0 11 | #error "preprocessor char literal is unsigned when it should be signed" 12 | #endif 13 | 14 | #if u'\0' - 1 < 0 15 | #error "preprocessor u8 char literal is signed when it should be unsigned" 16 | #endif 17 | -------------------------------------------------------------------------------- /test/cases/signed remainder.c: -------------------------------------------------------------------------------- 1 | _Static_assert(5 % -2 == 1, "failed"); 2 | _Static_assert(-10 % -4 == -2, "failed"); 3 | _Static_assert(10 % -1 == 0, "failed"); 4 | _Static_assert(-10 % -1 == 0, "failed"); 5 | _Static_assert(10U % -1 == 10, "failed"); 6 | _Static_assert(10U % -1 == 10, "failed"); 7 | _Static_assert((-9223372036854775807LL - 1LL) % -1 != 0, "failed"); 8 | 9 | #if (-9223372036854775807LL - 1LL) % -1 != 0 10 | #error Should not get here 11 | #endif 12 | 13 | #define EXPECTED_ERRORS "signed remainder.c:7:16: error: static assertion expression is not an integral constant expression" \ 14 | -------------------------------------------------------------------------------- /test/cases/sizeof variably modified types.c: -------------------------------------------------------------------------------- 1 | void foo(int x) { 2 | int arr[x]; 3 | _Static_assert(sizeof(arr) > 0, "sizeof VLA"); 4 | int (*pointer)[x] = &arr; 5 | _Static_assert(sizeof(pointer) == sizeof(int *), "pointer size"); 6 | _Static_assert(sizeof(*pointer) > 0, "sizeof variably-modified type"); 7 | } 8 | 9 | #define EXPECTED_ERRORS \ 10 | "sizeof variably modified types.c:3:20: error: static assertion expression is not an integral constant expression" \ 11 | "sizeof variably modified types.c:6:20: error: static assertion expression is not an integral constant expression" \ 12 | 13 | -------------------------------------------------------------------------------- /test/cases/source epoch.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | //aro-env SOURCE_DATE_EPOCH=0 3 | 4 | __DATE__ 5 | __TIME__ 6 | __TIMESTAMP__ 7 | -------------------------------------------------------------------------------- /test/cases/spliced newline in char literal.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | '\\ 3 | 4 | -------------------------------------------------------------------------------- /test/cases/spliced newline in string literal.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | 3 | "\\ 4 | 5 | -------------------------------------------------------------------------------- /test/cases/standard attributes.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | 3 | #pragma GCC diagnostic ignored "-Wgnu-alignof-expression" 4 | 5 | #if __has_c_attribute(foo) || __has_c_attribute(foo::bar) 6 | #error fail 7 | #endif 8 | 9 | #if !__has_c_attribute(deprecated) || !__has_c_attribute(gnu::__aligned__) 10 | #error fail 11 | #endif 12 | 13 | void foo(void) { 14 | [[deprecated]] int x; 15 | x = 5; 16 | } 17 | 18 | [[nodiscard]] int bar(void) { 19 | [[__gnu__::__aligned__(16)]] int x; 20 | _Static_assert(_Alignof(x) == 16, "incorrect alignment"); 21 | return 5; 22 | } 23 | 24 | #define EXPECTED_ERRORS "standard attributes.c:15:5: warning: 'x' is deprecated [-Wdeprecated-declarations]" \ 25 | "standard attributes.c:14:7: note: 'x' has been explicitly marked deprecated here" \ 26 | -------------------------------------------------------------------------------- /test/cases/standard-concatenation-strings-example.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define str(s) # s 4 | #define xstr(s) str(s) 5 | #define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \ 6 | x ## s, x ## t) 7 | #define INCFILE(n) vers ## n 8 | #define glue(a, b) a ## b 9 | #define xglue(a, b) glue(a, b) 10 | #define HIGHLOW "hello" 11 | #define LOW LOW ", world" 12 | debug(1, 2); 13 | fputs(str(strncmp("abc\0d", "abc", '\4') // this goes away 14 | == 0) str(: @\n), s); 15 | xstr(INCFILE(2).h) 16 | xstr(INCFILE(2) . h) 17 | str(INCFILE(2).h) 18 | str(INCFILE(2) . h) 19 | glue(HIGH, LOW); 20 | xglue(HIGH, LOW) 21 | -------------------------------------------------------------------------------- /test/cases/standard-placeholder-example.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | // example from the C18 standard draft, 6.10.3.5, example 5 3 | #define t(x,y,z) x ## y ## z 4 | int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), 5 | t(10,,), t(,11,), t(,,12), t(,,) }; 6 | -------------------------------------------------------------------------------- /test/cases/standard-redefinition-reexamination-example.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | // example from the C18 standard draft, 6.10.3.5, example 3 3 | #define x 3 4 | #define f(a) f(x * (a)) 5 | #undef x 6 | #define x 2 7 | #define g f 8 | #define z z[0] 9 | #define h g(\~{ } 10 | #define m(a) a(w) 11 | #define w 0,1 12 | #define t(a) a 13 | #define p() int 14 | #define q(x) x 15 | #define r(x,y) x ## y 16 | #define str(x) # x 17 | f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); 18 | g(x+(3,4)-w) | h 5) & m 19 | (f)^m(m); 20 | p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; 21 | char c[2][6] = { str(hello), str() }; 22 | -------------------------------------------------------------------------------- /test/cases/static assert messages.c: -------------------------------------------------------------------------------- 1 | void foo(int x) { 2 | _Static_assert(x, "not allowed"); 3 | _Static_assert(1); 4 | _Static_assert(0); 5 | } 6 | 7 | void bar(void) { 8 | _Static_assert(1, "ok", "not ok"); 9 | } 10 | 11 | _Static_assert(1 == 0, "They are not equal!"); 12 | 13 | #define EXPECTED_ERRORS "static assert messages.c:2:20: error: static assertion expression is not an integral constant expression" \ 14 | "static assert messages.c:3:5: warning: '_Static_assert' with no message is a C23 extension [-Wc23-extensions]" \ 15 | "static assert messages.c:4:5: warning: '_Static_assert' with no message is a C23 extension [-Wc23-extensions]" \ 16 | "static assert messages.c:4:5: error: static assertion failed" \ 17 | "static assert messages.c:8:27: error: expected ')', found ','" \ 18 | "static assert messages.c:8:19: note: to match this '('" \ 19 | "static assert messages.c:11:1: error: static assertion failed \"They are not equal!\"" \ 20 | -------------------------------------------------------------------------------- /test/cases/stdarg.c: -------------------------------------------------------------------------------- 1 | #include 2 | void foo(int a, ...) { 3 | va_list va, new; 4 | va_start(va, a); 5 | int arg = va_arg(va, int); 6 | va_copy(va, new); 7 | va_end(va); 8 | } 9 | void bar(int a, int b, ...) { 10 | va_list va; 11 | va_start(va, a); 12 | } 13 | void baz(int a) { 14 | va_list va; 15 | va_start(va, a); 16 | } 17 | va_list va; 18 | int a = va_start(va, 1); 19 | int b = __builtin_va_end; 20 | int c = __builtin_foo(); 21 | 22 | #define EXPECTED_ERRORS "stdarg.c:11:5: warning: second argument to 'va_start' is not the last named parameter [-Wvarargs]" \ 23 | "stdarg.h:12:52: note: expanded from here" \ 24 | "stdarg.c:11:18: note: expanded from here" \ 25 | "stdarg.c:15:5: error: 'va_start' used in a function with fixed args" \ 26 | "stdarg.h:12:29: note: expanded from here" \ 27 | "stdarg.c:18:9: error: 'va_start' cannot be used outside a function" \ 28 | "stdarg.h:12:29: note: expanded from here" \ 29 | "stdarg.c:18:9: error: initializing 'int' from incompatible type 'void'" \ 30 | "stdarg.h:12:29: note: expanded from here" \ 31 | "stdarg.c:19:9: error: builtin function must be directly called" \ 32 | "stdarg.c:20:9: error: use of unknown builtin '__builtin_foo' [-Wimplicit-function-declaration]" \ 33 | -------------------------------------------------------------------------------- /test/cases/stdckdint_ast.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | #include 3 | 4 | void foo(void) { 5 | char x = 0; 6 | unsigned y = 2; 7 | _Bool overflowed; 8 | long res; 9 | 10 | overflowed = ckd_add(&res, x, y); 11 | overflowed = ckd_sub(&res, x, y); 12 | overflowed = ckd_mul(&res, x, y); 13 | } 14 | -------------------------------------------------------------------------------- /test/cases/stringify backslashes.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | 3 | #define str(s) #s 4 | x[str() 5 | x[str(\) 6 | x[str(\\) 7 | x[str(\\\) 8 | x[str(\\\\) 9 | -------------------------------------------------------------------------------- /test/cases/stringify invalid escape.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define str(s) # s 4 | x[str(\) 5 | 6 | #define EXPECTED_ERRORS \ 7 | "stringify invalid escape.c:4:7: warning: invalid string literal, ignoring final '\\'" 8 | -------------------------------------------------------------------------------- /test/cases/stringify invalid.c: -------------------------------------------------------------------------------- 1 | #define EXPECTED_ERRORS "stringify invalid.c:9:20: warning: missing terminating '\"' character [-Winvalid-pp-token]" \ 2 | "stringify invalid.c:13:1: error: expected ';', found '}'" 3 | 4 | void foo(void) { 5 | 6 | #define str(s) # s 7 | #define xstr(s) str(s) 8 | 9 | #define INCFILE(n) "ok\ 10 | vers ## n 11 | 12 | xstr(INCFILE(a)) 13 | } 14 | -------------------------------------------------------------------------------- /test/cases/strings.c: -------------------------------------------------------------------------------- 1 | _Static_assert(1, "foo" "\n" "bar"); 2 | _Static_assert(1, "foo" "abc\x606262 "); 3 | _Static_assert(1, "\000062"); 4 | _Static_assert(1, "\U00110000"); 5 | _Static_assert(1, "\u0062"); 6 | 7 | int a = 'abcde'; 8 | 9 | _Static_assert(1, "\uD800"); 10 | _Static_assert(1, "\U0000DFFF"); 11 | _Static_assert(1, "\UFFFFFFFF"); 12 | _Static_assert(1, "\u0060"); 13 | 14 | #pragma GCC diagnostic warning "-Wpedantic" 15 | _Static_assert(1, "aaァ\e[1;"); 16 | #pragma GCC diagnostic pop 17 | 18 | const char *s1 = (const char *)"hello"; 19 | const char *s2 = "hello" + 1; 20 | const char *s3 = "hello" - 1; 21 | 22 | char * const string_array[] = { 23 | "string", 24 | }; 25 | 26 | #define EXPECTED_ERRORS "strings.c:2:29: error: escape sequence out of range" \ 27 | "strings.c:4:19: error: invalid universal character" \ 28 | "strings.c:5:19: error: character 'b' cannot be specified by a universal character name" \ 29 | "strings.c:7:9: warning: multi-character character constant [-Wmultichar]" \ 30 | "strings.c:7:9: warning: character constant too long for its type" \ 31 | "strings.c:9:19: error: invalid universal character" \ 32 | "strings.c:10:19: error: invalid universal character" \ 33 | "strings.c:11:19: error: invalid universal character" \ 34 | "strings.c:15:23: warning: use of non-standard escape character '\\e' [-Wpedantic]" \ 35 | -------------------------------------------------------------------------------- /test/cases/subscript.c: -------------------------------------------------------------------------------- 1 | int foo(int foo[2]) { 2 | int arr[4]; 3 | arr[-4] = 4[arr]; 4 | 1[1] = 2; 5 | arr[arr] = 2; 6 | return foo[2]; 7 | } 8 | 9 | #define EXPECTED_ERRORS "subscript.c:3:8: warning: array index -4 is before the beginning of the array [-Warray-bounds]" \ 10 | "subscript.c:3:16: warning: array index 4 is past the end of the array [-Warray-bounds]" \ 11 | "subscript.c:4:6: error: subscripted value is not an array, pointer or vector" \ 12 | "subscript.c:5:8: error: array subscript is not an integer" \ 13 | "subscript.c:6:15: warning: array index 2 is past the end of the array [-Warray-bounds]" \ 14 | -------------------------------------------------------------------------------- /test/cases/switch unsigned int.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu 2 | int lottery(unsigned int x) { 3 | switch (x) { 4 | case 3: return 0; 5 | case -1: return 3; 6 | case 8 ... 10: return x; 7 | default: return -1; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/cases/tentative array.c: -------------------------------------------------------------------------------- 1 | int arr[]; 2 | 3 | _Static_assert(sizeof arr,""); 4 | 5 | int arr[3]; // TODO should make the warning go away 6 | 7 | #define SKIPPED_TESTS 1 8 | 9 | #define EXPECTED_ERRORS \ 10 | "tentative array.c:1:5: warning: tentative array definition assumed to have one element" \ 11 | "tentative array.c:3:16: error: invalid application of 'sizeof' to an incomplete type 'int []'" \ 12 | 13 | -------------------------------------------------------------------------------- /test/cases/token paste delete comma gnu.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -Wgnu-zero-variadic-macro-arguments -P 2 | 3 | #define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__) 4 | eprintf("foo"); 5 | eprintf("foo",); 6 | eprintf("foo", "bar"); 7 | 8 | #define ZERO_ARGS(...) foo(a, ##__VA_ARGS__) 9 | 10 | ZERO_ARGS() 11 | ZERO_ARGS(b) 12 | 13 | #define foo(a,...) a, ## __VA_ARGS__ 14 | #define bar 15 | 16 | foo(1,bar) 17 | 18 | #define EXPECTED_ERRORS \ 19 | "token paste delete comma gnu.c:3:55: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]" \ 20 | "token paste delete comma gnu.c:3:55: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]" \ 21 | "token paste delete comma gnu.c:8:31: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]" \ 22 | "token paste delete comma gnu.c:8:31: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]" \ 23 | "token paste delete comma gnu.c:13:23: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]" \ 24 | 25 | -------------------------------------------------------------------------------- /test/cases/transparent_union.c: -------------------------------------------------------------------------------- 1 | struct S1{ 2 | int a; 3 | double b; 4 | } __attribute__((transparent_union)); 5 | union U1 { 6 | } __attribute__((transparent_union)); 7 | union U2 { 8 | int a; 9 | double b; 10 | } __attribute__((transparent_union)); 11 | union U3 { 12 | int a; 13 | float b; 14 | } __attribute__((transparent_union)); 15 | 16 | void f1(union U3); 17 | void f2(void) { 18 | f1(1); 19 | } 20 | 21 | union U4 { 22 | int *a; 23 | float *b; 24 | } __attribute__((transparent_union)); 25 | void f3(union U4); 26 | void f4(void) { 27 | f3(1); 28 | f3(0); 29 | } 30 | 31 | #define EXPECTED_ERRORS "transparent_union.c:4:18: warning: 'transparent_union' attribute only applies to unions [-Wignored-attributes]" \ 32 | "transparent_union.c:6:18: warning: transparent union definition must contain at least one field; transparent_union attribute ignored [-Wignored-attributes]" \ 33 | "transparent_union.c:9:12: warning: size of field 'b' (64 bits) does not match the size of the first field in transparent union; transparent_union attribute ignored [-Wignored-attributes]" \ 34 | "transparent_union.c:8:9: note: size of first field is 32" \ 35 | "transparent_union.c:27:8: error: passing 'int' to parameter of incompatible type 'union U4'" \ 36 | "transparent_union.c:25:17: note: passing argument to parameter here" \ 37 | -------------------------------------------------------------------------------- /test/cases/typedef extra specifiers disallowed.c: -------------------------------------------------------------------------------- 1 | typedef long foo; 2 | typedef unsigned foo bar; 3 | 4 | typedef double baz; 5 | typedef long baz; 6 | 7 | #define EXPECTED_ERRORS "typedef extra specifiers disallowed.c:2:18: error: typedef redefinition with different types ('unsigned int' vs 'long')" \ 8 | "typedef extra specifiers disallowed.c:1:14: note: previous definition is here" \ 9 | "typedef extra specifiers disallowed.c:2:22: error: expected ';', found 'an identifier'" \ 10 | "typedef extra specifiers disallowed.c:2:22: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]" \ 11 | "typedef extra specifiers disallowed.c:5:14: error: typedef redefinition with different types ('long' vs 'double')" \ 12 | "typedef extra specifiers disallowed.c:4:16: note: previous definition is here" \ 13 | 14 | -------------------------------------------------------------------------------- /test/cases/typeof incomplete array.c: -------------------------------------------------------------------------------- 1 | typeof(const int[]) arr1 = {1,2}; 2 | _Static_assert(sizeof(arr1) == sizeof(int[2]), ""); 3 | -------------------------------------------------------------------------------- /test/cases/typeof invalid pointer.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | typeof((void)0 + 0) *a = 2; 3 | -------------------------------------------------------------------------------- /test/cases/typeof pointer wrong size.c: -------------------------------------------------------------------------------- 1 | #define NO_ERROR_VALIDATION 2 | 3 | void foo(void) { 4 | char arr[10]; 5 | typeof(const int) *p = arr; 6 | } 7 | -------------------------------------------------------------------------------- /test/cases/typeof quals.c: -------------------------------------------------------------------------------- 1 | void test_typeof_quals(void) { 2 | const int a; 3 | typeof(a) b; 4 | volatile int c; 5 | typeof(c) d; 6 | register int e; 7 | typeof(e) f; 8 | (void)&f; 9 | _Atomic int g; 10 | typeof(g) h; 11 | int *restrict i = 0; 12 | typeof(i) j; 13 | } 14 | 15 | #define EXPECTED_TYPES "const int" "const typeof(: const int)" \ 16 | "volatile int" "volatile typeof(: volatile int)" \ 17 | "int" "typeof(: int)" "void" \ 18 | "_Atomic(int)" "typeof(: _Atomic(int))" \ 19 | "restrict *int" "restrict typeof(: restrict *int)" 20 | -------------------------------------------------------------------------------- /test/cases/typeof_unqual.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 --target=x86_64-linux-gnu 2 | const int a; 3 | typeof(a) b; 4 | typeof_unqual(a) c; 5 | -------------------------------------------------------------------------------- /test/cases/types.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux 2 | int _Alignas(int) _Alignas(float) _Alignas(16) a; 3 | 4 | const volatile int b; 5 | __const __volatile int c; 6 | __const__ __volatile__ int d; 7 | int foo(int *restrict a, int *__restrict b, int *__restrict__ c); 8 | 9 | int bar(int n, int bar[n]); 10 | 11 | typedef void baz; 12 | 13 | _Noreturn void abort(void); 14 | 15 | typedef int A; 16 | typedef A B; 17 | typedef A C; 18 | typedef C B; 19 | 20 | typedef int I[2]; 21 | void qux(I const a, const I b) { 22 | b += 1; 23 | a += 1; 24 | } 25 | 26 | enum E { 27 | D = (char) 2, 28 | E = (long) 3, 29 | }; 30 | -------------------------------------------------------------------------------- /test/cases/u8 character constant.c: -------------------------------------------------------------------------------- 1 | const unsigned char c = u8'A'; 2 | _Static_assert(c == 'A', ""); 3 | #pragma GCC diagnostic ignored "-Wc23-extensions" 4 | _Static_assert(u8'\xff' == 0xFF, ""); 5 | 6 | const unsigned char c2 = u8'™'; 7 | const unsigned char c3 = u8'£'; // Unicode codepoint 0xA3 8 | const unsigned char c4 = u8'AA'; 9 | 10 | #if u8'A' 11 | #else 12 | #error Character constant should be true in preprocessor 13 | #endif 14 | 15 | #define EXPECTED_ERRORS \ 16 | "u8 character constant.c:1:25: warning: UTF-8 character literal is a C23 extension [-Wc23-extensions]" \ 17 | "u8 character constant.c:6:26: error: character too large for enclosing character literal type" \ 18 | "u8 character constant.c:7:26: error: character too large for enclosing character literal type" \ 19 | "u8 character constant.c:8:26: error: Unicode character literals may not contain multiple characters" \ 20 | 21 | -------------------------------------------------------------------------------- /test/cases/ucn identifiers.c: -------------------------------------------------------------------------------- 1 | #define \U0001F525 42 2 | _Static_assert(🔥 == 42, ""); 3 | 4 | #define FOO \u4F60 ## \u597D 5 | 6 | #define INCOMPLETE_UCN \u4F ## 60 7 | 8 | int foo(void) { 9 | int FOO = 0; 10 | \u4F60\u597D = 5; 11 | int \u0061 = 0x61; 12 | int ABC\U00000001 = 0x01; 13 | return 你好; 14 | } 15 | 16 | struct S { 17 | int 你好; 18 | int a\u4F60\u597D; 19 | }; 20 | 21 | int bar(int x) { 22 | struct S s; 23 | s.\u4F60\u597D = x; 24 | s.a\u4F60\u597D = x; 25 | return s.你好; 26 | } 27 | 28 | int \UFFFFFFFF = 42; 29 | 30 | #define EXPECTED_ERRORS "ucn identifiers.c:6:24: warning: incomplete universal character name; treating as '\\' followed by identifier [-Wunicode]" \ 31 | "ucn identifiers.c:11:9: error: character 'a' cannot be specified by a universal character name" \ 32 | "ucn identifiers.c:12:9: error: universal character name refers to a control character" \ 33 | "ucn identifiers.c:28:7: error: invalid universal character" \ 34 | 35 | -------------------------------------------------------------------------------- /test/cases/unaligned u16 string literal.c: -------------------------------------------------------------------------------- 1 | struct S { 2 | int x; 3 | }; 4 | 5 | void foo(void) { 6 | struct S s; 7 | s.y; 8 | } 9 | 10 | _Static_assert(u"A"); 11 | 12 | #define NO_ERROR_VALIDATION 13 | -------------------------------------------------------------------------------- /test/cases/unavailable results.c: -------------------------------------------------------------------------------- 1 | #pragma GCC diagnostic push 2 | #pragma GCC diagnostic ignored "-Wunused-value" 3 | void foo(void) { 4 | 1.0f == 1.0f; 5 | (double)1 + 1U == 2.0; 6 | (_Complex float)1 + 2U; 7 | 1U + (int *)1; 8 | 1U + &2; 9 | } 10 | #pragma GCC diagnostic pop 11 | 12 | #define EXPECTED_ERRORS "unavailable results.c:8:10: error: cannot take the address of an rvalue" \ 13 | -------------------------------------------------------------------------------- /test/cases/undef.c: -------------------------------------------------------------------------------- 1 | //aro-args -undef --target=x86_64-linux-gnu 2 | 3 | #if defined(linux) || defined(__linux) || defined(__linux__) 4 | #error Should not be defined 5 | #endif 6 | -------------------------------------------------------------------------------- /test/cases/undefined macro.c: -------------------------------------------------------------------------------- 1 | #pragma GCC diagnostic warning "-Wundef" 2 | 3 | #if FOO 4 | #error "Error" 5 | #endif 6 | 7 | #define FOO BAR 8 | 9 | #if FOO 10 | #error "Error" 11 | #endif 12 | 13 | #if undefined(foo) 14 | #error bad 15 | #endif 16 | 17 | #define EXPECTED_ERRORS "undefined macro.c:3:5: warning: 'FOO' is not defined, evaluates to 0 [-Wundef]" \ 18 | "undefined macro.c:9:5: warning: 'BAR' is not defined, evaluates to 0 [-Wundef]" \ 19 | "undefined macro.c:7:13: note: expanded from here" \ 20 | "undefined macro.c:13:5: warning: 'undefined' is not defined, evaluates to 0 [-Wundef]" \ 21 | "undefined macro.c:13:5: error: function-like macro 'undefined' is not defined" \ 22 | -------------------------------------------------------------------------------- /test/cases/unexpected pragmas.c: -------------------------------------------------------------------------------- 1 | // This tests that pragmas in locations where the parser does not check for them 2 | // do not cause undefined behavior. See https://github.com/Vexu/arocc/issues/82 3 | // Parser improvements may reduce or eliminate the errors reported. 4 | 5 | int foo, 6 | #pragma bar bar 7 | int baz; 8 | #pragma qux 9 | 10 | #define EXPECTED_ERRORS "unexpected pragmas.c:6:2: error: expected identifier or '('" 11 | -------------------------------------------------------------------------------- /test/cases/unexpected_type_name.c: -------------------------------------------------------------------------------- 1 | typedef int foo; 2 | void bar(void) { 3 | int a = foo; 4 | } 5 | 6 | #define EXPECTED_ERRORS "unexpected_type_name.c:3:13: error: unexpected type name 'foo': expected expression" \ 7 | 8 | -------------------------------------------------------------------------------- /test/cases/unknown pragmas.c: -------------------------------------------------------------------------------- 1 | #pragma GCC diagnostic warning "-Wunknown-pragmas" 2 | 3 | #pragma unknown_option 4 | 5 | #pragma GCC unknown_option 6 | 7 | #pragma GCC diagnostic unknown_option_again 8 | 9 | #define EXPECTED_ERRORS \ 10 | "unknown pragmas.c:3:9: warning: unknown pragma ignored [-Wunknown-pragmas]" \ 11 | "unknown pragmas.c:5:13: warning: pragma GCC expected 'error', 'warning', 'diagnostic', 'poison' [-Wunknown-pragmas]" \ 12 | "unknown pragmas.c:7:24: warning: pragma GCC diagnostic expected 'error', 'warning', 'ignored', 'fatal', 'push', or 'pop' [-Wunknown-pragmas]" \ 13 | -------------------------------------------------------------------------------- /test/cases/unmatched macro paren.c: -------------------------------------------------------------------------------- 1 | #define f(x) x 2 | 3 | f(1 4 | 5 | #define EXPECTED_ERRORS "unmatched macro paren.c:3:1: error: unterminated function macro argument list" \ 6 | -------------------------------------------------------------------------------- /test/cases/unreachable code.c: -------------------------------------------------------------------------------- 1 | int test(int a){ 2 | switch(a) { 3 | default: break; 4 | } 5 | return 1; 6 | } 7 | int test1(int a){ 8 | switch(a) { 9 | break; 10 | a=1; 11 | } 12 | return 1; 13 | } 14 | int test2(int a){ 15 | switch(a) { 16 | return 1; 17 | a=1; 18 | } 19 | return 1; 20 | } 21 | int compound_stmt(int a){ 22 | { 23 | a=1; 24 | return 1; 25 | a=2; 26 | } 27 | } 28 | int if_then_else(int a){ 29 | if(a) 30 | return 1; 31 | else 32 | return 2; 33 | return 3; 34 | } 35 | #define EXPECTED_ERRORS "unreachable code.c:10:3: warning: unreachable code [-Wunreachable-code]" \ 36 | "unreachable code.c:17:3: warning: unreachable code [-Wunreachable-code]" \ 37 | "unreachable code.c:25:3: warning: unreachable code [-Wunreachable-code]" \ 38 | "unreachable code.c:33:2: warning: unreachable code [-Wunreachable-code]" 39 | -------------------------------------------------------------------------------- /test/cases/unreachable.c: -------------------------------------------------------------------------------- 1 | //aro-args -std=c23 2 | #include 3 | void foo(void) { 4 | unreachable(); 5 | } 6 | -------------------------------------------------------------------------------- /test/cases/unsigned char.c: -------------------------------------------------------------------------------- 1 | //aro-args --target=x86_64-linux-gnu -funsigned-char -Wno-integer-overflow 2 | 3 | _Static_assert(__CHAR_UNSIGNED__ == 1, ""); 4 | _Static_assert((char)-1 == 0xFF, "char should be unsigned"); 5 | 6 | #if '\0' - 1 < 0 7 | #error "preprocessor char literal is signed when it should be unsigned" 8 | #endif 9 | 10 | #if u'\0' - 1 < 0 11 | #error "preprocessor u8 char literal is signed when it should be unsigned" 12 | #endif 13 | -------------------------------------------------------------------------------- /test/cases/unspecified expansion.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | // This can either expand as 2*f(9) or as 2*9*g (see 6.10.3.4 in the standard) 3 | // We follow gcc and clang in expanding it to 2*9*g 4 | 5 | #define f(a) a*g 6 | #define g(a) f(a) 7 | 8 | f(2)(9) 9 | -------------------------------------------------------------------------------- /test/cases/unterminated char literal.c: -------------------------------------------------------------------------------- 1 | #define A 'b 2 | #define B '' 3 | #define C(X) '' 4 | #define D(X) 'A 5 | 6 | #define EXPECTED_ERRORS "unterminated char literal.c:1:11: warning: missing terminating ' character [-Winvalid-pp-token]" \ 7 | "unterminated char literal.c:2:11: warning: empty character constant [-Winvalid-pp-token]" \ 8 | "unterminated char literal.c:3:14: warning: empty character constant [-Winvalid-pp-token]" \ 9 | "unterminated char literal.c:4:14: warning: missing terminating ' character [-Winvalid-pp-token]" \ 10 | "unterminated char literal.c:16:10: warning: empty character constant [-Winvalid-pp-token]" \ 11 | "unterminated char literal.c:17:10: warning: missing terminating ' character [-Winvalid-pp-token]" \ 12 | "unterminated char literal.c:16:10: error: empty character constant" \ 13 | "unterminated char literal.c:17:10: error: missing terminating ' character" \ 14 | "unterminated char literal.c:17:11: error: expected ';' before end of file" \ 15 | 16 | char c = u8''; 17 | char d = ' -------------------------------------------------------------------------------- /test/cases/unterminated comment in preprocessor expression.c: -------------------------------------------------------------------------------- 1 | #define EXPECTED_ERRORS "unterminated comment in preprocessor expression.c:7:5: error: invalid token at start of a preprocessor expression" \ 2 | "unterminated comment in preprocessor expression.c:7:1: error: unterminated conditional directive" \ 3 | "unterminated comment in preprocessor expression.c:7:1: error: unterminated conditional directive" 4 | 5 | #if /* 6 | 7 | -------------------------------------------------------------------------------- /test/cases/unterminated comment.c: -------------------------------------------------------------------------------- 1 | #define EXPECTED_ERRORS "unterminated comment.c:4:7: error: unterminated comment" \ 2 | "unterminated comment.c:4:6: error: expected ';' before end of file" \ 3 | 4 | int x /** -------------------------------------------------------------------------------- /test/cases/unterminated macro function at eof gcc.c: -------------------------------------------------------------------------------- 1 | //aro-args -E --emulate=gcc -P 2 | #define EXPECTED_ERRORS "unterminated macro function at eof gcc.c:5:1: error: unterminated function macro argument list" \ 3 | 4 | #define foo(X) X 5 | foo(1, 6 | -------------------------------------------------------------------------------- /test/cases/unterminated macro function at eof.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | #define EXPECTED_ERRORS "unterminated macro function at eof.c:5:1: error: unterminated function macro argument list" \ 3 | 4 | #define foo(X) X 5 | foo(1, 6 | -------------------------------------------------------------------------------- /test/cases/unterminated string literal.c: -------------------------------------------------------------------------------- 1 | #define EXPECTED_ERRORS "unterminated string literal.c:6:12: warning: missing terminating '\"' character [-Winvalid-pp-token]" \ 2 | "unterminated string literal.c:7:20: warning: missing terminating '\"' character [-Winvalid-pp-token]" \ 3 | "unterminated string literal.c:8:12: warning: missing terminating '\"' character [-Winvalid-pp-token]" \ 4 | 5 | 6 | char A[] = "hello 7 | char B[] = "hello" "world 8 | char C[] = " -------------------------------------------------------------------------------- /test/cases/var args macro functions.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define foo(a,...) #__VA_ARGS__ 4 | foo(1,2,3,4,5,6) 5 | 6 | #define bar(a,...) bar __VA_ARGS__ 7 | #define baz(a,...) baz bar(__VA_ARGS__) 8 | baz(1,2,3,4) 9 | -------------------------------------------------------------------------------- /test/cases/vla.c: -------------------------------------------------------------------------------- 1 | //aro-args -Wvla 2 | void foo(int x) { 3 | int arr[x]; 4 | } 5 | 6 | struct S { 7 | int x; 8 | int y[x]; 9 | }; 10 | 11 | void bar(int x) { 12 | int arr[2][3][x]; 13 | } 14 | 15 | #define EXPECTED_ERRORS "vla.c:3:13: warning: variable length array used [-Wvla]" \ 16 | "vla.c:8:11: error: use of undeclared identifier 'x'" \ 17 | "vla.c:12:19: warning: variable length array used [-Wvla]" \ 18 | -------------------------------------------------------------------------------- /test/cases/void star.c: -------------------------------------------------------------------------------- 1 | #define NULL 0 2 | extern int func(int *); 3 | extern int func1(void *); 4 | int * foo(void) { 5 | int *a = NULL; 6 | func(NULL); 7 | return NULL; 8 | } 9 | int *bar(void *a) { 10 | int *b = a; 11 | func(a); 12 | return a; 13 | } 14 | void *baz(int *a) { 15 | void *b = a; 16 | func(a); 17 | return a; 18 | } 19 | -------------------------------------------------------------------------------- /test/cases/warn unused result.c: -------------------------------------------------------------------------------- 1 | typedef int (*fnptr)(int, int); 2 | 3 | 4 | int foo() __attribute__((warn_unused_result)) { 5 | return 0; 6 | } 7 | 8 | fnptr make_fn(int a, int b) { 9 | return 0; 10 | } 11 | 12 | void bar(fnptr ptr) { 13 | foo(); 14 | (foo)(); 15 | (foo - 16)(); 16 | (foo + 16)(); 17 | (*****foo)(); 18 | make_fn(1, 2)(2, 2); 19 | } 20 | 21 | struct S { 22 | int __attribute__((warn_unused_result))(*close)(void); 23 | }; 24 | 25 | void baz(struct S *s){ 26 | (bar(0), s->close)(); 27 | } 28 | 29 | 30 | #define EXPECTED_ERRORS "warn unused result.c:13:4: warning: ignoring return value of 'foo', declared with 'warn_unused_result' attribute [-Wunused-result]" \ 31 | "warn unused result.c:14:4: warning: ignoring return value of 'foo', declared with 'warn_unused_result' attribute [-Wunused-result]" \ 32 | "warn unused result.c:17:4: warning: ignoring return value of 'foo', declared with 'warn_unused_result' attribute [-Wunused-result]" \ 33 | "warn unused result.c:26:5: warning: ignoring return value of 'close', declared with 'warn_unused_result' attribute [-Wunused-result]" \ 34 | 35 | -------------------------------------------------------------------------------- /test/cases/whitespace macro arguments.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define h() 1 4 | #define g(x) x 5 | #define f(x, y) g(y) x 6 | 7 | #define p(...) h(__VA_ARGS__) 8 | #define q(e, ...) f(e, __VA_ARGS__) 9 | 10 | h() 11 | g() 12 | f(1,) 13 | f(1,q) 14 | f(,) 15 | p() 16 | q(3, 2) 17 | q(, 3) 18 | -------------------------------------------------------------------------------- /test/cases/zero argument macro.c: -------------------------------------------------------------------------------- 1 | //aro-args -E -P 2 | 3 | #define NO_ARGUMENTS() 4 | 5 | NO_ARGUMENTS() 6 | NO_ARGUMENTS( ) 7 | NO_ARGUMENTS( 8 | 9 | ) 10 | NO_ARGUMENTS(1) 11 | 12 | #define EXPECTED_ERRORS "zero argument macro.c:10:1: error: expected 0 argument(s) got 1" \ 13 | 14 | -------------------------------------------------------------------------------- /test/cases/zero length array.c: -------------------------------------------------------------------------------- 1 | //aro-args -Wzero-length-array 2 | 3 | struct S { 4 | int x; 5 | int y[0]; 6 | }; 7 | 8 | void foo(void) { 9 | struct S s; 10 | s.y[2] = 5; 11 | int z[0]; 12 | z[5] = 2; 13 | } 14 | 15 | #define EXPECTED_ERRORS "zero length array.c:5:10: warning: zero size arrays are an extension [-Wzero-length-array]" \ 16 | "zero length array.c:11:10: warning: zero size arrays are an extension [-Wzero-length-array]" \ 17 | 18 | -------------------------------------------------------------------------------- /test/cases/zero length multidimensional array.c: -------------------------------------------------------------------------------- 1 | int foo[1][0]; 2 | int bar[0][0]; 3 | int baz[1][0][0]; 4 | int qux[1][1][0]; 5 | -------------------------------------------------------------------------------- /test/fuzz/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | __AFL_FUZZ_INIT(); 3 | 4 | void compile_c_buf(unsigned char *buf, int len); 5 | 6 | int main(void) { 7 | 8 | #ifdef __AFL_HAVE_MANUAL_CONTROL 9 | __AFL_INIT(); 10 | #endif 11 | 12 | unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; // must be after __AFL_INIT 13 | // and before __AFL_LOOP! 14 | 15 | while (__AFL_LOOP(10000)) { 16 | 17 | int len = __AFL_FUZZ_TESTCASE_LEN; // don't use the macro directly in a 18 | // call! 19 | 20 | compile_c_buf(buf, len); 21 | } 22 | 23 | return 0; 24 | 25 | } 26 | --------------------------------------------------------------------------------