├── LICENSE ├── README.md ├── build_msvc.bat ├── examples ├── Readme.md ├── cJSON.bat ├── cake.bat ├── curl.bat ├── freetype.bat ├── glfw.bat ├── libpng.bat ├── miniaudio.bat ├── miniz.bat ├── neovim.bat ├── nuklear.bat ├── raylib.bat ├── tinycc.bat ├── zlib.bat └── zydis.bat ├── implicit ├── include │ ├── emmintrin.h │ ├── excpt.h │ ├── immintrin.h │ ├── intrin.h │ ├── intrinsic.c │ ├── iso646.h │ ├── limits.h │ ├── mmintrin.h │ ├── nmmintrin.h │ ├── oldnames.c │ ├── pmmintrin.h │ ├── runtime.c │ ├── setjmp.c │ ├── setjmp.h │ ├── smmintrin.h │ ├── stdarg.h │ ├── stdatomic.c │ ├── stdatomic.h │ ├── stdbool.h │ ├── stdint.h │ ├── tmmintrin.h │ ├── vcruntime.h │ ├── vcruntime_new_debug.h │ ├── vcruntime_startup.h │ ├── vcruntime_string.h │ ├── wmmintrin.h │ ├── x86intrin.h │ └── xmmintrin.h ├── pre_WinMain.c ├── pre_main.c ├── pre_main_no_args.c ├── pre_wWinMain.c ├── pre_wmain.c └── pre_wmain_no_args.c ├── meta_programs ├── hlc.cli └── parse_cli.c ├── src ├── ar.c ├── ast.c ├── cli.c ├── coff_writer.c ├── diagnostic.c ├── emit_inline_asm_block.c ├── emit_x64.c ├── explain.c ├── main.c ├── obj_writer.c ├── options.h ├── parse.c ├── parse_asm_block.c ├── preprocess.c ├── stb_sprintf.h ├── std.c ├── timing.c └── windows.c ├── test_runner.c └── tests ├── broken ├── _start_with_ExitProcess_should_not_warn_for_no_return_a_value.c ├── big_struct.c ├── filling_in_bounds_for_array_of_unknown_size.c ├── intrinsic.c ├── non_constant_initializer_in_pruned_function.c ├── out_of_order_typedef_and_abstract_function_declarator.c ├── self_include.c ├── unresolved_type_as_second_in_declaration_list_makes_the_first_one_be_defined_twice.c └── using_the_size_of_an_array_of_unknown_size_before_it_is_filled_in.c ├── compile ├── LLONG_MAX_should_be_signed.c ├── _Generic_with_function_or_array.c ├── __LINE__should_be_correct.c ├── __has_include.c ├── accept_defines_with_the_open_paren_on_the_next_line.c ├── accept_typedef_to_void_as_empty_parameter_list.c ├── address_of_array.c ├── anonymous_struct_initialize.c ├── argument_expansion_and_rescanning.c ├── array_of_unknown_size_and_unresolved_type.c ├── array_of_unknown_size_array_initializer.c ├── array_ordering_which_causes_a_bunch_of_sleeps.c ├── assignment_to_incomplete_pointer_with_mismatching_type.c ├── bitfields_and_anonymous_struct_members.c ├── bitfields_and_varargs_functions.c ├── both_branches_of_if_return_a_value.c ├── brace_enclosed_string_literal_array_initializers.c ├── call_tree.c ├── calling_comma_expression.c ├── cast_struct_to_itself.c ├── comparing_pointers_of_different_types.c ├── complex_constant_initializers.c ├── concatinate_macro_called_with_a_newline.c ├── concatinate_macro_called_with_a_newline_but_also_stringify_it.c ├── constant_offset.c ├── custom_main.c ├── declarators.c ├── defined_type_for_comparison_operations_should_be_small.c ├── disabled_invalid_preprocessor_directive.c ├── disabled_static_elif_tests.c ├── dllimport_referanced_by_global.c ├── dont_warn_on_assignment_type_mismatch_when_its_fine.c ├── double_array_and_index_initialzer.c ├── double_array_subscript.c ├── double_braced_scalar_initializers.c ├── double_include_of_pathed_system_include.c ├── double_typedef_to_unresolved.c ├── easy.c ├── elif_inside_if0_block_should_not_complain_about_junk.c ├── empty_hashes.c ├── empty_hashhash.c ├── endif_last_thing_in_the_file.c ├── escaping_should_happend_before_concatination.c ├── extenal_variable_inside_function_compiling_to_object.c ├── extern_const_declspec.c ├── extern_dllexport_declarations_of_unresolved_type_which_has_its_address_taken.c ├── extraneous_semicolons.c ├── forgetting_to_return_a_value.c ├── function_containing_noreturn_call_must_not_return_a_value.c ├── function_declaration_with_argument_of_unresolved_type_gets_defined.c ├── function_in_if.c ├── function_like_macro_in_argument_list_of_other_macro_that_is_not_expanded_in_the_arguments_but_only_during_rescanning.c ├── function_like_macro_with_space_parameter_list.c ├── function_pointer_deref.c ├── function_pointer_deref_address.c ├── gcc_extension_for_removing_comma_for_empty__VA_ARGS__.c ├── globally_referenced_enum_member_compile_to_object.c ├── grab_bag.c ├── hashhash.c ├── hello_world.c ├── if_with_scope_returns_a_value_only_in_one_branch.c ├── implicit_float_to_int_in_initializer.c ├── include_and_defines.c ├── include_math.c ├── include_system_include_that_includes_a_relative_include.c ├── includes_pragma_once_header_with_both_system_and_relative_path_include.c ├── incomplete_struct_match.c ├── infinite_loop_counts_as_returning_value.c ├── initialized_dllexport.c ├── initializer_of_empty_structure.c ├── initializers.c ├── inline_intrinsic_function_with_a_bunch_of_arguments.c ├── invalid_directives_disabled_by_static_if.c ├── keyword_in_defined.c ├── legal_redeclaration_of_enum.c ├── legal_unresolved_types.c ├── local_function_should_not_complain_about_redeclarations.c ├── many_lf_enum.c ├── member_access_after_array_access_of_later_struct_argument.c ├── member_designator_in_initializer_list_has_to_modify_what_the_current_object_is.c ├── multiply_by_zero_should_compile.c ├── need_to_escape_when_stringifying.c ├── noreturn_function_returns_a_value.c ├── one_case_in_switch_statement_forgets_to_return_a_value.c ├── only_one_branch_of_an_if_returns_a_value.c ├── only_warn_on_redeclartion_with_mismatching_dllexport_or_selectany_attribute.c ├── order_of_array_declarators.c ├── patch_to_static_variable_obj.c ├── pointer_casts_in_addition_in_static_initializer.c ├── pointer_literal_to_submember.c ├── pointer_plus_bitfield.c ├── pointer_to_undeclared_struct_in_struct.c ├── pragma_comment_lib.c ├── pragma_comment_lib_in_obj.c ├── predeclaration_of_non_defined_dll_export_function.c ├── really_large_array_subscripts.c ├── redefine_alignas_macro.c ├── redefine_macro_should_only_warn.c ├── referencing_an_external_structure_of_unresolved_type_by_address_should_work_in_object_file.c ├── register_sized_struct_in_conditional_expression_gets_membered.c ├── returns_a_value_in_a_subscope.c ├── self_referanced_struct_and_typedef.c ├── separator_in_number.c ├── shadowing_global_struct_at_local_scope.c ├── signed_and_unsigned_integer_literals_in_static_if.c ├── sizeof_full_bitfield.c ├── sizeof_global_in_array_length_inside_structure_at_global_scope.c ├── sizeof_on_array_of_unknown_size_array_literal.c ├── sleeping_on_typedef_to_already_defined_struct.c ├── sleeping_type.c ├── sleeping_unresolved_array.c ├── static_array_of_enum_size.c ├── static_if_and_ternaries.c ├── static_if_space_before_directive_that_follows_a_directive.c ├── static_thread_local_variable_with_patch.c ├── string_literal_column_tests.c ├── string_literal_in_constant_expression.c ├── string_question_mark_and_implcit_conversion_to_bool.c ├── subscript_with_bitfield_assignment.c ├── switch_statement_returns_value.c ├── switch_with_default_case_does_return_a_value.c ├── system_include_dir_for_relative_include_test │ ├── relative_include.h │ └── system_include.h ├── test_for_broken_declaration_regrowing_function.c ├── this_is_a_dll_because_of_DllMain.c ├── this_is_a_dll_with_no_entry_point_as_determined_by_the_out_file_extension.c ├── trailling_comma_in_function_calls.c ├── type_stack_grow.c ├── typedef_to_struct_that_gets_filled_in_in_another_typedef.c ├── typedef_to_unresolved_pointer_type.c ├── uintmax_without_suffix_should_still_be_bigger_than_intmax.c ├── unary_plus_on_float_literal_should_still_be_constant.c ├── unfilled_external_at_block_scope_when_compiling_to_object.c ├── unnamed_parameters_in_function_definition.c ├── unreferenced_external_variable_of_undefined_struct_type.c ├── unreferenced_static_inline_references_external_undefined_globals_variable.c ├── unresolved_pointer_dereferance.c ├── unresolved_return_type.c ├── unresolved_type_at_local_scope.c ├── unresolved_types_that_are_later_filled_in_should_work_at_global_scope.c ├── using_defined_outside_of_static_if.c ├── using_typedef_to_array_of_unknown_size_multiple_times.c ├── void_pointer_tests.c ├── void_typed_ternary.c ├── warn_on_extern_declaration_into_inline_declaration.c ├── warn_on_redeclaring_a_function_to_be_static_after_there_was_already_an_external_declaration.c ├── weird_argument_in_function_declarator.c ├── windows_defines.c └── zero_sized_struct.c ├── error ├── __FUNCTION__outside_function.c ├── another_static_if_fail_check_that_is_just_not_supposed_to_assert.c ├── array_of_unknown_size_in_sub_struct_with_members_after_it.c ├── assignment_of_array_of_unknown_size.c ├── backslash_at_the_end_of_the_file.c ├── case_more_then_once.c ├── cast_int_to_struct.c ├── cast_to_function_type.c ├── cast_to_unresolved_struct.c ├── circular_dependency.c ├── compile_time_div_or_mod_by_zero.c ├── compound_assignment_for_bool_with_rhs_of_string_type.c ├── declaration_of_unresolved_type.c ├── deeply_nested_struct.c ├── defined_type_should_always_be_big_enough_for_value_incorrect_printlike_warning.c ├── defining_local_unresolved_struct_in_subscope.c ├── disabled_if_should_not_complain_about_junk.c ├── dllimport_and_dllexport_at_global_scope.c ├── dllimport_and_dllexport_at_local_scope.c ├── dot_expression_should_not_set_lhs_expression_flag.c ├── double_default.c ├── double_sleep.c ├── elif_after_else.c ├── endif_header.h ├── error_in_expression_within_struct_initializer_resetting_should_exit_statement.c ├── escaped_string_literals_should_increment_the_line_count.c ├── extern.c ├── extern_variable_was_never_filled_in.c ├── file_ends_in_macro_expansion.c ├── flexible_array_member_initialization.c ├── float_literals_suffixes_and_a_number_at_the_end.c ├── function_calls_are_not_lhs_expressions.c ├── function_in_struct.c ├── function_scope_array_size_overflow.c ├── function_type_compount_literal.c ├── half_parenthesized_comma_expression_in_static_if.c ├── hash_before_non_argument.c ├── hash_if.c ├── hashes1.c ├── hashes2.c ├── hashes3.c ├── hashes4.c ├── hashes5.c ├── hashes6.c ├── hashes7.c ├── hashes8.c ├── include_open_index.c ├── including_endif_header.c ├── initializing_array_of_empty_struct.c ├── initializing_empty_struct.c ├── initializing_nested_compound_using_designator_has_to_increment_member_index_by_more_than_one.c ├── inline_data_declaration.c ├── integer_promotion_and_bool.c ├── invalid_array_and_function_declarators.c ├── invalid_declarator_of_pointer_type.c ├── label_redefinition.c ├── link_to_non_existant_library.c ├── local_extern_declaration_with_wrong_type_should_error.c ├── macro_expansion_in_include_directive_eats_the_rest_of_the_file_then_errors.c ├── main_sleeping_on_itself.c ├── main_without_ending_closed_curly.c ├── member_is_not_in_struct_within_struct_literal.c ├── member_redefinition.c ├── mod_by_zero_in_static_if.c ├── never_filled_in_extern_variable_in_block_scope_should_avoid_undeclared_identifiers.c ├── non_constant_array_length_inside_structure_at_global_scope.c ├── non_defined_entry_point.c ├── not_a_type_error_in_generic.c ├── pointer_arithmetic_on_function_type.c ├── pointer_deref_to_incomplete_array.c ├── redeclaration_of_structure_one_with_pointer_to_int_one_with_pointer_to_void.c ├── redeclaring_enum_value.c ├── redeclaring_variable_as_typedef.c ├── redefining_defined.c ├── rogue_semicolon.c ├── should_report_undeclared_identifiers_in_structures.c ├── sleeping_on_ident_after_struct_has_been_defined.c ├── static_else_last_thing_in_the_file.c ├── static_if_last_thing_in_the_file.c ├── struct_self_inclusion.c ├── typedef_and_anonymous_use.c ├── typedef_to_array_of_unknown_size_should_not_get_overwritten_by_sized_typedef.c ├── typedef_to_itself.c ├── u64_values_in_static_if.c ├── unary_plus_on_pointers.c ├── unbounded_static_if_recursion.c ├── unended_cast_to_function.c ├── unnamed_int_declaration_in_structure.c ├── unresolved_anonymous_union.c ├── unresolved_array.c ├── unresolved_array_in_struct.c ├── unresolved_struct_inclusion.c ├── unresolved_type_in_struct_in_function_declaration.c ├── using_expression_of_type_void_as_an_argument_to_varargs_function.c ├── using_wrong_tag_to_access_compound.c ├── va_start_errors.c ├── very_large_bitfield.c ├── very_negative_bitfield.c ├── void_declaration.c ├── void_pointer_arithmetic.c ├── void_semi_in_struct.c ├── void_type_in_struct.c └── we_should_not_be_able_to_index_a_pointer_to_an_unresolved_struct.c ├── linkage ├── array_initializer_is_in_different_file │ ├── header.h │ ├── main.c │ └── other.c ├── arrays_of_unknown_size_filled_in_in_first │ ├── main.c │ └── other.c ├── crt_and_dll │ ├── arst │ ├── opens_a_file.c │ └── reads_the_file.c ├── dllexport_only_defined_in_one │ ├── header.h │ ├── main.c │ └── other.c ├── dllimport_and_dllexport │ ├── main.c │ ├── other.dll │ └── other.lib ├── locally_extern_declared_variable │ ├── main.c │ └── other.c ├── predefined_inline_asm_function │ ├── main.c │ └── other.c ├── simple_static │ ├── main.c │ └── other.c ├── sizeof_array_of_unknown_size_which_gets_filled_in_other_compilation_unit │ ├── main.c │ └── other.c ├── static_function_pointer_array_that_references_external_function │ ├── main.c │ └── other.c ├── struct_literals_should_not_have_the_open_curly_as_their_symbol.c ├── the_body_of_an_inline_extern_function_included_in_two_compilation_units_should_not_be_parsed_twice │ ├── file_one_which_includes_the_header.c │ ├── file_two_which_includes_the_header.c │ └── header_with_an_inline_function_that_has_a_static_buffer.h ├── type_index_for_undefined_struct_as_argument_for_function_pointer │ ├── main.c │ └── other.c ├── uninitialized_dllexport_variable_should_be_automatic.c └── where_is_main │ ├── main.c │ └── other.c ├── run ├── _Bool.c ├── alloca.c ├── array_designator_next_current_object.c ├── array_of_unknown_size_compound_literal_current_object.c ├── array_of_unknown_size_is_never_filled_in.c ├── arrays_and_logical_and.c ├── arrays_of_unknown_size_initialized_by_string_literals.c ├── assigning_to_a_function_pointer.c ├── big_return_type_and_first_float_argument.c ├── bitfield_arguments_to_local_function.c ├── bitfields.c ├── cast_to_float_in_initializer.c ├── checking_predefines_from_the_commandline.c ├── comma_expression_that_end_in_a_function_should_still_evaluate_their_lhs.c ├── comparing_double_to_float_literal.c ├── deref_call.c ├── do_while_false.c ├── float_test.c ├── function_returns_a_function_ptr_returns_a_funtion_pointer.c ├── function_that_is_only_referenced_by_a_global_declaration.c ├── handle_escaped_percent_correctly_in_printlike_function.c ├── hex_escape_sequences_and_character_literal_sizes.c ├── implicit_return_zero_for_main.c ├── implicitly_dllimport_functions.c ├── inc_dec_Bool.c ├── increment_and_decrement_on_an_empty_struct.c ├── initialized_array_of_unions_containing_just_a_flexible_array_member.c ├── initialized_flexible_array_members.c ├── initializer_of_struct_which_contains_unnamed_member.c ├── initializers_need_to_patch_outer_type_as_well.c ├── integer_promotion_for_unary_operators_on_integer_literals.c ├── intrinsic_argument_to_varargs_procedure.c ├── intrinsic_function_argument.c ├── intrinsic_test.c ├── local_extern_compound.c ├── local_function_declaration_later_function_definition.c ├── lzcnt.c ├── member_offset_in_initializer_of_array.c ├── minus_one_pointer_literal.c ├── negative_subscript.c ├── oddly_sized_struct_types.c ├── offsets_on_anonymous_substructs.c ├── packed.c ├── patches_into_flexible_array_member.c ├── pointer_arithmetic_with_minus_one.c ├── pointers_to_arrays_of_unknown_size.c ├── redeclaring_in_same_scope_and_regrowing_the_declaration_table.c ├── static_address_of_static_variable.c ├── static_initializers_to_string_literal.c ├── static_reference_of_dll_import_function_needs_stub_compile_to_object.c ├── static_reference_of_dllimport_function_needs_stub.c ├── string_initializer_in_function.c ├── stringify_tests.c ├── test.c ├── test.h ├── test_unicode_in_string_literals.c ├── the_infinite_function_call.c ├── tls.c ├── varargs_with_floating_point_immediate.c └── we_have_to_have_a_pre_main_file_even_for_main_without_arguments.c └── stdlib ├── setjmp.c ├── stdatomic.c ├── stddef.c └── using_stdup_from_oldnames.c /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 PascalBeyer 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_msvc.bat: -------------------------------------------------------------------------------- 1 | 2 | @echo off 3 | 4 | echo Compiling with msvc 5 | IF NOT EXIST build mkdir build 6 | 7 | rem *******************************************WARNINGS***************************************************** 8 | rem set warning_options= /w 9 | set warning_options= -Wall -wd4201 -wd4820 -wd4711 -wd4200 -wd4204 -wd4214 -wd4324 -wd5045 -wd4061 -wd4221 10 | rem ******************************************************************************************************** 11 | 12 | set compiler_flags= -Od -nologo -fp:fast -GR- -EHa- -Zo -Oi -D_Debug %warning_options% -FC -Z7 -GS- -Gs9999999 /diagnostics:column /TC 13 | 14 | set linker_flags= -HEAP:0,0 -STACK:0x100000,0x100000 -incremental:no -opt:ref Advapi32.lib kernel32.lib ucrt.lib /NODEFAULTLIB /ENTRY:_start /SUBSYSTEM:console /NOLOGO /DEBUG 15 | 16 | cl %compiler_flags% src/main.c /Fo:build/hlc.obj /link %linker_flags% /pdb:build/hlc.pdb /out:hlc.exe 17 | -------------------------------------------------------------------------------- /examples/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # Examples 3 | 4 | For now this folder only contains a pile of .bat scripts that compile real world projects. 5 | For these scripts it is usuallly necessary to have 6 | 7 | 1) A version on visual studio for `link.exe` and sometimes as a c++ compiler. 8 | 2) cmake 9 | 3) ninja 10 | 11 | The build scipts of the various projects might also need other interpreters like python but I dunno. 12 | 13 | In the future, this folder should also contain examples/tutorials on how to use the hlc specific features. 14 | 15 | -------------------------------------------------------------------------------- /examples/cJSON.bat: -------------------------------------------------------------------------------- 1 | 2 | git clone --recursive --depth 1 --branch v1.7.18 https://github.com/DaveGamble/cJSON.git 3 | cd cJSON || exit /b 1 4 | 5 | git clean -xdf 6 | 7 | mkdir build 8 | cd build 9 | 10 | REM Use -D CMAKE_BUILD_TYPE=Release because one of the tests is stupid an checks that a member is null after the struct has been freed 11 | cmake .. -G Ninja -D CMAKE_C_COMPILER="%~dp0..\hlc.exe" -D CMAKE_BUILD_TYPE=Release || exit /b 1 12 | ninja || exit /b 1 13 | ninja test || exit /b 1 14 | 15 | cd ..\.. 16 | -------------------------------------------------------------------------------- /examples/cake.bat: -------------------------------------------------------------------------------- 1 | git clone --recursive --depth 1 https://github.com/thradams/cake.git 2 | cd cake\src || exit /b 1 3 | git clean -xdf 4 | git checkout * 5 | 6 | hlc build.c || exit /b 1 7 | build.exe || exit /b 1 8 | 9 | cd ..\.. 10 | 11 | -------------------------------------------------------------------------------- /examples/curl.bat: -------------------------------------------------------------------------------- 1 | 2 | git clone --recursive --depth 1 --branch curl-8_11_0 https://github.com/curl/curl.git 3 | cd curl || exit /b 1 4 | 5 | git clean -xdf 6 | git checkout * 7 | 8 | echo #include ^ // for _InterlockedExchange and _InterlockedCompareExchange >> src/tool_doswin.c 9 | 10 | mkdir build 11 | cd build 12 | 13 | cmake .. -G Ninja -D CMAKE_C_COMPILER="%~dp0..\hlc.exe" || exit /b 1 14 | ninja || exit /b 1 15 | 16 | copy src\curl.exe lib || exit /b 1 17 | lib\curl.exe google.com || exit /b 1 18 | 19 | cd ..\.. 20 | 21 | -------------------------------------------------------------------------------- /examples/freetype.bat: -------------------------------------------------------------------------------- 1 | 2 | 3 | git clone --recursive --depth 1 --branch VER-2-13-3 https://github.com/freetype/freetype.git 4 | cd freetype || exit /b 1 5 | 6 | git clean -xdf 7 | git checkout * 8 | 9 | mkdir build 10 | cd build 11 | 12 | cmake .. -G Ninja -D CMAKE_C_COMPILER="%~dp0..\hlc.exe" || exit /b 1 13 | ninja || exit /b 1 14 | 15 | cd ..\.. 16 | 17 | -------------------------------------------------------------------------------- /examples/glfw.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | git clone --recursive --depth 1 --branch 3.4 https://github.com/glfw/glfw.git 4 | cd glfw || exit /b 1 5 | 6 | git checkout * 7 | git clean -xdf 8 | 9 | mkdir build 10 | cd build 11 | cmake .. -G Ninja -D CMAKE_C_COMPILER="%~dp0..\hlc.exe" || exit /b 1 12 | ninja || exit /b 1 13 | cd ..\.. 14 | -------------------------------------------------------------------------------- /examples/libpng.bat: -------------------------------------------------------------------------------- 1 | 2 | if not exist zlib ( 3 | echo Error: Need to build zlib first 4 | exit /b 1 5 | ) 6 | 7 | git clone --recursive --depth 1 --branch libpng16 https://github.com/pnggroup/libpng.git 8 | cd libpng || exit /b 1 9 | 10 | git clean -xdf 11 | 12 | where awk.exe > NUL 13 | if %errorlevel% == 0 ( 14 | echo ***** Warning: For whatever reason the build fails for me if it can find awk. 15 | pause 16 | ) 17 | 18 | cmake . -G Ninja -D CMAKE_C_COMPILER="%~dp0..\hlc.exe" -B build -D ZLIB_LIBRARY="%~dp0zlib\build\zlibstaticd.lib" -D ZLIB_INCLUDE_DIR="%~dp0zlib" || exit /b 1 19 | cd build 20 | ninja || exit /b 1 21 | ninja test || exit /b 1 22 | 23 | cd ..\.. 24 | -------------------------------------------------------------------------------- /examples/miniaudio.bat: -------------------------------------------------------------------------------- 1 | 2 | git clone --recursive --depth 1 --branch 0.11.21 https://github.com/mackron/miniaudio.git 3 | cd miniaudio || exit /b 1 4 | 5 | git clean -xdf 6 | 7 | cd examples || exit /b 1 8 | hlc simple_playback_sine.c || exit /b 1 9 | 10 | cd ..\.. 11 | -------------------------------------------------------------------------------- /examples/miniz.bat: -------------------------------------------------------------------------------- 1 | 2 | git clone --recursive --depth 1 --branch 3.0.2 https://github.com/richgel999/miniz.git 3 | cd miniz || exit /b 1 4 | 5 | git clean -xdf 6 | 7 | cmake . -G Ninja -D CMAKE_C_COMPILER="C:\Projects\Headerless-C-Compiler\hlc.exe" -B build || exit /b 1 8 | cd build || exit /b 1 9 | 10 | ninja || exit /b 1 11 | 12 | cd ..\bin || exit /b 1 13 | 14 | example1.exe || exit /b 1 15 | example2.exe || exit /b 1 16 | 17 | cd ..\.. 18 | 19 | -------------------------------------------------------------------------------- /examples/neovim.bat: -------------------------------------------------------------------------------- 1 | 2 | git clone --recursive --depth 1 --branch v0.10.3 https://github.com/neovim/neovim.git 3 | cd neovim || exit /b 1 4 | 5 | git checkout * 6 | 7 | IF NOT EXIST .deps ( 8 | :: We currently cannot compile the dependencies. 9 | :: So we use MSVC instead and only compile them once. 10 | cmake -S cmake.deps -B .deps -G Ninja || exit /b 1 11 | cmake --build .deps || exit /b 1 12 | ) 13 | 14 | IF EXIST build ( 15 | cmake --build build --target clean 16 | ) ELSE ( 17 | cmake -B build -G Ninja -D CMAKE_C_COMPILER="%~dp0..\hlc.exe" || exit /b 1 18 | ) 19 | 20 | 21 | echo #include ^ // Their include is in the wrong spot. >> src/nvim/math.c 22 | 23 | cmake --build build || exit /b 1 24 | 25 | cd .. 26 | -------------------------------------------------------------------------------- /examples/nuklear.bat: -------------------------------------------------------------------------------- 1 | 2 | git clone --recursive --depth 1 --branch 4.12.0 https://github.com/Immediate-Mode-UI/Nuklear.git 3 | 4 | cd nuklear || exit /b 1 5 | git clean -xdf || exit /b 1 6 | 7 | cd demo\d3d11 || exit /b 1 8 | echo hlc %%* > cl.bat || exit /b 1 9 | call build.bat || exit /b 1 10 | 11 | cd ..\..\.. 12 | 13 | -------------------------------------------------------------------------------- /examples/raylib.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | git clone --recursive --depth 1 --branch 5.0 https://github.com/raysan5/raylib.git 4 | cd raylib || exit /b 1 5 | 6 | git clean -xdf 7 | 8 | mkdir build 9 | cd build 10 | 11 | cmake .. -G Ninja -D CMAKE_C_COMPILER="C:\Projects\Headerless-C-Compiler\hlc.exe" || exit /b 1 12 | ninja || exit /b 1 13 | 14 | :: cd ..\.. 15 | 16 | -------------------------------------------------------------------------------- /examples/tinycc.bat: -------------------------------------------------------------------------------- 1 | 2 | git clone --recursive --depth 1 --branch mob https://github.com/TinyCC/tinycc.git 3 | cd tinycc\win32 || exit /b 1 4 | 5 | git clean -xdf 6 | 7 | set TCC_C=..\tcc.c 8 | build-tcc.bat -c hlc.exe -t 64 || exit /b 1 9 | 10 | cd ..\.. 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/zlib.bat: -------------------------------------------------------------------------------- 1 | git clone --recursive --depth 1 --branch v1.3.1 https://github.com/madler/zlib.git 2 | cd zlib || exit /b 1 3 | 4 | git clean -xdf 5 | 6 | cmake . -G Ninja -D CMAKE_C_COMPILER="%~dp0..\hlc.exe" -B build || exit /b 1 7 | cmake --build build || exit /b 1 8 | 9 | copy build\zconf.h . || exit /b 1 10 | build\example || exit /b 1 11 | 12 | cd .. 13 | -------------------------------------------------------------------------------- /examples/zydis.bat: -------------------------------------------------------------------------------- 1 | git clone --recursive --depth 1 --branch v4.1.0 https://github.com/zyantific/zydis.git 2 | cd zydis || exit /b 1 3 | 4 | git clean -xdf 5 | 6 | cmake -G Ninja -D CMAKE_C_COMPILER="%~dp0..\hlc.exe" -B build || exit /b 1 7 | 8 | cd build || exit /b 1 9 | ninja || exit /b 1 10 | ninja test || exit /b 1 11 | cd ..\.. 12 | -------------------------------------------------------------------------------- /implicit/include/emmintrin.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | -------------------------------------------------------------------------------- /implicit/include/excpt.h: -------------------------------------------------------------------------------- 1 | 2 | typedef enum _EXCEPTION_DISPOSITION 3 | { 4 | ExceptionContinueExecution, 5 | ExceptionContinueSearch, 6 | ExceptionNestedException, 7 | ExceptionCollidedUnwind 8 | } EXCEPTION_DISPOSITION; 9 | 10 | 11 | enum{ 12 | EXCEPTION_CONTINUE_SEARCH = 0, 13 | EXCEPTION_EXECUTE_HANDLER = 1, 14 | EXCEPTION_CONTINUE_EXECUTION = -1, 15 | }; 16 | -------------------------------------------------------------------------------- /implicit/include/immintrin.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | // #include 6 | -------------------------------------------------------------------------------- /implicit/include/intrin.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | // #include amd intrinsics 6 | -------------------------------------------------------------------------------- /implicit/include/iso646.h: -------------------------------------------------------------------------------- 1 | #define and && 2 | #define and_eq &= 3 | #define bitand & 4 | #define bitor | 5 | #define compl ~ 6 | #define not ! 7 | #define not_eq != 8 | #define or || 9 | #define or_eq |= 10 | #define xor ^ 11 | #define xor_eq ^= 12 | -------------------------------------------------------------------------------- /implicit/include/limits.h: -------------------------------------------------------------------------------- 1 | #define CHAR_BIT 8 2 | #define MB_LEN_MAX 5 3 | 4 | #define SCHAR_MAX 127 5 | #define CHAR_MAX 127 6 | #define SHRT_MAX 32767 7 | #define INT_MAX 2147483647 8 | #define LLONG_MAX 9223372036854775807LL 9 | 10 | #define SCHAR_MIN (-127-1) 11 | #define CHAR_MIN (-127-1) 12 | #define SHRT_MIN (-32767-1) 13 | #define INT_MIN (-2147483647-1) 14 | #define LLONG_MIN (-9223372036854775807LL-1) 15 | 16 | #define UCHAR_MAX 255ui8 17 | #define USHRT_MAX 65535ui16 18 | #define UINT_MAX 4294967295ui32 19 | #define ULLONG_MAX 18446744073709551615ui64 20 | 21 | // @note: For now assume windows and we don't care about int vs long. 22 | #define LONG_MIN INT_MIN 23 | #define LONG_MAX INT_MAX 24 | #define ULONG_MAX UINT_MAX 25 | 26 | // Microsoft specific 27 | // see https://learn.microsoft.com/en-us/cpp/c-runtime-library/data-type-constants?view=msvc-170 28 | #define _I8_MAX 127i8 29 | #define _I8_MIN (-127i8-1) 30 | 31 | #define _I16_MAX 32767i16 32 | #define _I16_MIN (-32767i16-1) 33 | 34 | #define _I32_MAX 2147483647i32 35 | #define _I32_MIN (-2147483647i32-1) 36 | 37 | #define _I64_MAX 9223372036854775807 38 | #define _I64_MIN (-9223372036854775807-1) 39 | 40 | #define _UI8_MAX 0xffui8 41 | #define _UI16_MAX 0xffffui16 42 | #define _UI32_MAX 0xffffffffui32 43 | #define _UI64_MAX 0xffffffffffffffffui64 44 | -------------------------------------------------------------------------------- /implicit/include/mmintrin.h: -------------------------------------------------------------------------------- 1 | 2 | // @cleanup: For now there is no include granularity for intrinsics. 3 | #pragma compilation_unit("intrinsic.c") 4 | 5 | -------------------------------------------------------------------------------- /implicit/include/nmmintrin.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | -------------------------------------------------------------------------------- /implicit/include/pmmintrin.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | -------------------------------------------------------------------------------- /implicit/include/setjmp.c: -------------------------------------------------------------------------------- 1 | 2 | struct __declspec(align(16)) aligned_char{ 3 | unsigned char a; 4 | }; 5 | 6 | typedef struct aligned_char jmp_buf[256]; 7 | 8 | #ifdef __HLC_COMPILE_TO_OBJECT__ 9 | int setjmp(jmp_buf environment_buffer, char *frame); 10 | _Noreturn void longjmp(jmp_buf environment_buffer, int return_value); 11 | #else 12 | 13 | int setjmp(jmp_buf environment_buffer){ 14 | int return_value; 15 | 16 | // The return address in Windows x64 calling convension is 8 bytes after (in stack order) the first argument. 17 | // Hence we can calculate it here. This is really aweful. 18 | volatile __int64 *pointer_to_return_address = (__int64 *)&environment_buffer - 1; 19 | __int64 return_address = *pointer_to_return_address; 20 | 21 | __asm__{ 22 | 23 | // Store all of the non-volatile registers. 24 | mov rcx, environment_buffer 25 | mov rdx, return_address 26 | 27 | mov [rcx + 0x00], rbp 28 | mov [rcx + 0x08], rbx 29 | mov [rcx + 0x10], rsp 30 | mov [rcx + 0x18], rsi 31 | mov [rcx + 0x20], rdi 32 | mov [rcx + 0x28], r12 33 | mov [rcx + 0x30], r13 34 | mov [rcx + 0x38], r14 35 | mov [rcx + 0x40], r15 36 | 37 | bytes {0f ae 59 50} // stmxcsr dword ptr [rcx+0x50] 38 | bytes {9b d9 79 54} // fstcw word ptr [rcx+0x54] 39 | 40 | mov word ptr [rcx + 0x56], 0 41 | mov [rcx + 0x58], rdx 42 | 43 | movups [rcx + 0x60], xmm6 44 | movups [rcx + 0x70], xmm7 45 | movups [rcx + 0x80], xmm8 46 | movups [rcx + 0x90], xmm9 47 | movups [rcx + 0xa0], xmm10 48 | movups [rcx + 0xb0], xmm11 49 | movups [rcx + 0xc0], xmm12 50 | movups [rcx + 0xd0], xmm13 51 | movups [rcx + 0xe0], xmm14 52 | movups [rcx + 0xf0], xmm15 53 | 54 | // Return 0 from the initial call. 55 | xor eax, eax 56 | 57 | bytes{ 58 | 4c 8d 05 04 00 00 00 // lea r8, long_jmp_target 59 | 4c 89 41 48 // mov [rcx + 0x48], r8 60 | } 61 | 62 | mov return_address, rdx 63 | mov return_value, eax 64 | } 65 | 66 | // @note: The original pointer_to_return_address is not valid anymore. 67 | // We have to reload it. 68 | pointer_to_return_address = (__int64 *)&environment_buffer - 1; 69 | *pointer_to_return_address = return_address; 70 | 71 | return return_value; 72 | } 73 | 74 | _Noreturn void longjmp(jmp_buf environment_buffer, int return_value){ 75 | 76 | __asm__{ 77 | mov rcx, environment_buffer 78 | 79 | // load the return value already, because it might be on the stack. 80 | mov eax, return_value 81 | 82 | mov rbp, [rcx + 0x00] 83 | mov rbx, [rcx + 0x08] 84 | mov rsp, [rcx + 0x10] 85 | mov rsi, [rcx + 0x18] 86 | mov rdi, [rcx + 0x20] 87 | mov r12, [rcx + 0x28] 88 | mov r13, [rcx + 0x30] 89 | mov r14, [rcx + 0x38] 90 | mov r15, [rcx + 0x40] 91 | 92 | bytes {0f ae 51 50} // ldmxcsr DWORD PTR [rcx+0x50] 93 | bytes {d9 69 54} // fldcw WORD PTR [rcx+0x54] 94 | 95 | mov rdx, [rcx + 0x58] 96 | 97 | movups xmm6, [rcx + 0x60] 98 | movups xmm7, [rcx + 0x70] 99 | movups xmm8, [rcx + 0x80] 100 | movups xmm9, [rcx + 0x90] 101 | movups xmm10, [rcx + 0xa0] 102 | movups xmm11, [rcx + 0xb0] 103 | movups xmm12, [rcx + 0xc0] 104 | movups xmm13, [rcx + 0xd0] 105 | movups xmm14, [rcx + 0xe0] 106 | movups xmm15, [rcx + 0xf0] 107 | 108 | // jump to the saved rip. 109 | bytes {ff 61 48} // jmp QWORD PTR [rcx+0x48] 110 | } 111 | 112 | // squelch the noreturn function returning waring please! 113 | __declspec(inline_asm) _Noreturn void do_not_warn_for_noreturn_please(){ } 114 | do_not_warn_for_noreturn_please(); 115 | } 116 | 117 | #endif 118 | -------------------------------------------------------------------------------- /implicit/include/setjmp.h: -------------------------------------------------------------------------------- 1 | 2 | #ifdef __HLC_COMPILE_TO_OBJECT__ 3 | // @cleanup: Microsotf passes rsp as the second parameter (somemthing like __read_rsp()), 4 | // but for me that crashes somewhere inside RtlUnwindEx. 5 | // It seems it does not do unwinding if the second parameter is 0. 6 | // - Pascal Beyer 10.11.2024 7 | #define setjmp(env) setjmp(env, 0) 8 | #endif 9 | 10 | #pragma compilation_unit("setjmp.c") 11 | 12 | 13 | -------------------------------------------------------------------------------- /implicit/include/smmintrin.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | -------------------------------------------------------------------------------- /implicit/include/stdarg.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // Windows x64 calling convention has the arguments 5 | // linearly each in an 8-byte slot. If an argument 6 | // does not "fit" the 8-byte slot, either because it is 7 | // too large or because its size is not a power of two, 8 | // it passed as a pointer. 9 | // 10 | // va_start: Get the argument immediately after the 'format' argument. 11 | // va_arg: Advance the argument by 8 and use either one or two indirections. 12 | // va_copy: Just copy the pointer. 13 | // va_end: Do nothing! 14 | // 15 | 16 | typedef struct __va_list{ 17 | __int64 unused; 18 | } *va_list; 19 | 20 | #define va_start(ap, parmN) ((ap) = ((va_list)&(parmN) + 1)) 21 | #define va_arg(ap, type) ((sizeof(type) > 8 || (sizeof(type) & (sizeof(type)-1))) \ 22 | ? **(type**)(((ap) += 1) - 1) \ 23 | : *(type *)(((ap) += 1) - 1)) 24 | #define va_copy(dest, src) ((dest) = (src)) 25 | #define va_end(ap) ((void)(ap)) 26 | 27 | -------------------------------------------------------------------------------- /implicit/include/stdbool.h: -------------------------------------------------------------------------------- 1 | #define bool _Bool 2 | #define true 1 3 | #define false 0 4 | #define __bool_true_false_are_defined 1 5 | -------------------------------------------------------------------------------- /implicit/include/stdint.h: -------------------------------------------------------------------------------- 1 | 2 | typedef unsigned __int8 uint8_t; 3 | typedef unsigned __int16 uint16_t; 4 | typedef unsigned __int32 uint32_t; 5 | typedef unsigned __int64 uint64_t; 6 | 7 | typedef signed __int8 int8_t; 8 | typedef signed __int16 int16_t; 9 | typedef signed __int32 int32_t; 10 | typedef signed __int64 int64_t; 11 | 12 | typedef signed __int8 int_least8_t; 13 | typedef signed __int16 int_least16_t; 14 | typedef signed __int32 int_least32_t; 15 | typedef signed __int64 int_least64_t; 16 | 17 | typedef unsigned __int8 uint_least8_t; 18 | typedef unsigned __int16 uint_least16_t; 19 | typedef unsigned __int32 uint_least32_t; 20 | typedef unsigned __int64 uint_least64_t; 21 | 22 | typedef signed __int8 int_fast8_t; 23 | typedef signed __int16 int_fast16_t; 24 | typedef signed __int32 int_fast32_t; 25 | typedef signed __int64 int_fast64_t; 26 | 27 | typedef unsigned __int8 uint_fast8_t; 28 | typedef unsigned __int16 uint_fast16_t; 29 | typedef unsigned __int32 uint_fast32_t; 30 | typedef unsigned __int64 uint_fast64_t; 31 | 32 | typedef unsigned __int64 uintptr_t; 33 | typedef signed __int64 intptr_t; 34 | 35 | typedef unsigned __int64 uintmax_t; 36 | typedef signed __int64 intmax_t; 37 | 38 | #define INT8_MAX 127 39 | #define INT16_MAX 32767 40 | #define INT32_MAX 2147483647 41 | #define INT64_MAX 9223372036854775807LL 42 | 43 | #define UINT8_MAX 255 44 | #define UINT16_MAX 65535 45 | #define UINT32_MAX 4294967295 46 | #define UINT64_MAX 18446744073709551615 47 | 48 | #define INT8_MIN (-127-1) 49 | #define INT16_MIN (-32767-1) 50 | #define INT32_MIN (-2147483647-1) 51 | #define INT64_MIN (-9223372036854775807LL-1) 52 | 53 | #define INT_FAST8_MAX INT8_MAX 54 | #define INT_FAST16_MAX INT16_MAX 55 | #define INT_FAST32_MAX INT32_MAX 56 | #define INT_FAST64_MAX INT64_MAX 57 | 58 | #define UINT_FAST8_MAX UINT8_MAX 59 | #define UINT_FAST16_MAX UINT16_MAX 60 | #define UINT_FAST32_MAX UINT32_MAX 61 | #define UINT_FAST64_MAX UINT64_MAX 62 | 63 | #define INT_FAST8_MIN INT8_MIN 64 | #define INT_FAST16_MIN INT16_MIN 65 | #define INT_FAST32_MIN INT32_MIN 66 | #define INT_FAST64_MIN INT64_MIN 67 | 68 | #define INT_LEAST8_MAX INT8_MAX 69 | #define INT_LEAST16_MAX INT16_MAX 70 | #define INT_LEAST32_MAX INT32_MAX 71 | #define INT_LEAST64_MAX INT64_MAX 72 | 73 | #define UINT_LEAST8_MAX UINT8_MAX 74 | #define UINT_LEAST16_MAX UINT16_MAX 75 | #define UINT_LEAST32_MAX UINT32_MAX 76 | #define UINT_LEAST64_MAX UINT64_MAX 77 | 78 | #define INT_LEAST8_MIN INT8_MIN 79 | #define INT_LEAST16_MIN INT16_MIN 80 | #define INT_LEAST32_MIN INT32_MIN 81 | #define INT_LEAST64_MIN INT64_MIN 82 | 83 | #define INTMAX_MAX INT64_MAX 84 | #define INTMAX_MIN INT64_MIN 85 | #define UINTMAX_MAX UINT64_MAX 86 | 87 | #define INTPTR_MAX INT64_MAX 88 | #define INTPTR_MIN INT64_MIN 89 | #define UINTPTR_MAX UINT64_MAX 90 | 91 | #define PTRDIFF_MAX INT64_MAX 92 | #define PTRDIFF_MIN INT64_MIN 93 | 94 | #define SIZE_MAX UINT64_MAX 95 | 96 | #define WCHAR_MIN 0 97 | #define WCHAR_MAX UINT16_MAX 98 | 99 | #define WINT_MIN 0 100 | #define WINT_MAX UINT32_MAX 101 | 102 | #define INT8_C(a) a 103 | #define INT16_C(a) a 104 | #define INT32_C(a) a 105 | #define INT64_C(a) a##ll 106 | 107 | #define UINT8_C(a) a 108 | #define UINT16_C(a) a 109 | #define UINT32_C(a) a##u 110 | #define UINT64_C(a) a##llu 111 | 112 | #define INTMAX_C(a) a##ll 113 | #define UINTMAX_C(a) a##llu 114 | -------------------------------------------------------------------------------- /implicit/include/tmmintrin.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | -------------------------------------------------------------------------------- /implicit/include/vcruntime.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #define __CRTDECL 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #define _CRT_BEGIN_C_HEADER 11 | #define _CRT_END_C_HEADER 12 | 13 | #define _CRT_INSECURE_DEPRECATE(...) 14 | #define _CRT_DEPRECATE_TEXT(...) 15 | #define _CRT_INSECURE_DEPRECATE_MEMORY(...) 16 | 17 | #define __crt_va_start va_start 18 | #define __crt_va_end va_end 19 | 20 | #define _CRT_WIDE_INTERNAL(a) L##a 21 | #define _CRT_WIDE(a) _CRT_WIDE_INTERNAL(a) 22 | 23 | #ifdef __HLC_COMPILE_TO_OBJECT__ 24 | 25 | #ifdef _DLL 26 | #define _VCRTIMP __declspec(dllimport) 27 | #else 28 | #define _VCRTIMP 29 | #endif 30 | 31 | #else // !__HLC_COMPILE_TO_OBJECT__ 32 | 33 | // We want to import all things when we compiling to an exe. 34 | // Otherwise, let the normal crt code paths decide. 35 | #define _ACRTIMP __declspec(dllimport) 36 | #define _VCRTIMP __declspec(dllimport) 37 | #define _DCRTIMP __declspec(dllimport) 38 | #endif 39 | 40 | #define __crt_countof(array) (sizeof(array) / sizeof((array)[0])) 41 | 42 | typedef unsigned short wchar_t; 43 | typedef unsigned __int64 size_t; 44 | typedef __int64 ptrdiff_t; 45 | typedef __int64 intptr_t; 46 | 47 | -------------------------------------------------------------------------------- /implicit/include/vcruntime_new_debug.h: -------------------------------------------------------------------------------- 1 | 2 | // ? 3 | -------------------------------------------------------------------------------- /implicit/include/vcruntime_startup.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | typedef enum _crt_argv_mode{ 4 | _crt_argv_no_arguments, 5 | _crt_argv_unexpanded_arguments, 6 | _crt_argv_expanded_arguments, 7 | } _crt_argv_mode; 8 | -------------------------------------------------------------------------------- /implicit/include/vcruntime_string.h: -------------------------------------------------------------------------------- 1 | 2 | #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES 3 | #pragma compilation_unit("oldnames.c") 4 | #endif 5 | 6 | #pragma compilation_unit("runtime.c") 7 | -------------------------------------------------------------------------------- /implicit/include/wmmintrin.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | -------------------------------------------------------------------------------- /implicit/include/x86intrin.h: -------------------------------------------------------------------------------- 1 | 2 | // @cleanup: For now there is no include granularity for intrinsics. 3 | #pragma compilation_unit("intrinsic.c") 4 | -------------------------------------------------------------------------------- /implicit/include/xmmintrin.h: -------------------------------------------------------------------------------- 1 | 2 | #define _MM_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w)) 3 | 4 | #include 5 | -------------------------------------------------------------------------------- /implicit/pre_WinMain.c: -------------------------------------------------------------------------------- 1 | 2 | #pragma comment(lib, "kernel32") 3 | 4 | static typedef void * HANDLE; 5 | static typedef struct HINSTANCE__ *HINSTANCE; 6 | static typedef HINSTANCE HMODULE; 7 | static typedef char *LPSTR; 8 | static typedef unsigned int DWORD; 9 | static typedef unsigned short WORD; 10 | static typedef unsigned char *LPBYTE; 11 | 12 | struct _STARTUPINFOA { 13 | DWORD cb; 14 | LPSTR lpReserved; 15 | LPSTR lpDesktop; 16 | LPSTR lpTitle; 17 | DWORD dwX; 18 | DWORD dwY; 19 | DWORD dwXSize; 20 | DWORD dwYSize; 21 | DWORD dwXCountChars; 22 | DWORD dwYCountChars; 23 | DWORD dwFillAttribute; 24 | DWORD dwFlags; 25 | WORD wShowWindow; 26 | WORD cbReserved2; 27 | LPBYTE lpReserved2; 28 | HANDLE hStdInput; 29 | HANDLE hStdOutput; 30 | HANDLE hStdError; 31 | }; 32 | 33 | __declspec(dllimport) LPSTR GetCommandLineA(void); 34 | __declspec(dllimport) HMODULE GetModuleHandleA(LPSTR lpModuleName); 35 | __declspec(dllimport) __declspec(noreturn) void ExitProcess(unsigned int uExitCode); 36 | __declspec(dllimport) void GetStartupInfoA(struct _STARTUPINFOA *lpStartupInfo); 37 | 38 | int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd); 39 | 40 | void _start(void){ 41 | struct _STARTUPINFOA StartupInfo; 42 | GetStartupInfoA(&StartupInfo); 43 | 44 | HINSTANCE hInstance = GetModuleHandleA(0); // @cleanup: __ImageBase? 45 | HINSTANCE hPrevInstance = 0; // "This parameter is always NULL." 46 | char *lpCmdLine = GetCommandLineA(); 47 | int nShowCmd = (StartupInfo.dwFlags & /*STARTF_USESHOWWINDOW*/1) ? StartupInfo.wShowWindow : /*SW_SHOWDEFAULT*/10; 48 | 49 | int ExitCode = WinMain(hInstance, hPrevInstance, lpCmdLine, nShowCmd); 50 | ExitProcess(ExitCode); 51 | } 52 | -------------------------------------------------------------------------------- /implicit/pre_main_no_args.c: -------------------------------------------------------------------------------- 1 | // 2 | // Unfortunally, Windows does not draw a distinction between the main 3 | // thread and any other thread. This means when the main thread exits its 4 | // start routine, the process will not exit, only `ExitThread` is called. 5 | // Hence, we need to provide this `pre_main_no_args.c` file, to exit the 6 | // process when it returns from `main`. 7 | // 8 | 9 | #pragma comment(lib, "kernel32") 10 | __declspec(dllimport) __declspec(noreturn) void ExitProcess(unsigned int uExitCode); 11 | 12 | int main(); 13 | 14 | int _start(void){ 15 | 16 | int exit_code = main(); 17 | 18 | ExitProcess((unsigned int)exit_code); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /implicit/pre_wWinMain.c: -------------------------------------------------------------------------------- 1 | 2 | #pragma comment(lib, "kernel32") 3 | 4 | static typedef unsigned short wchar_t; 5 | static typedef void * HANDLE; 6 | static typedef struct HINSTANCE__ *HINSTANCE; 7 | static typedef HINSTANCE HMODULE; 8 | static typedef wchar_t *LPSTR; 9 | static typedef unsigned int DWORD; 10 | static typedef unsigned short WORD; 11 | static typedef unsigned char *LPBYTE; 12 | 13 | struct _STARTUPINFOW { 14 | DWORD cb; 15 | LPSTR lpReserved; 16 | LPSTR lpDesktop; 17 | LPSTR lpTitle; 18 | DWORD dwX; 19 | DWORD dwY; 20 | DWORD dwXSize; 21 | DWORD dwYSize; 22 | DWORD dwXCountChars; 23 | DWORD dwYCountChars; 24 | DWORD dwFillAttribute; 25 | DWORD dwFlags; 26 | WORD wShowWindow; 27 | WORD cbReserved2; 28 | LPBYTE lpReserved2; 29 | HANDLE hStdInput; 30 | HANDLE hStdOutput; 31 | HANDLE hStdError; 32 | }; 33 | 34 | __declspec(dllimport) LPSTR GetCommandLineW(void); 35 | __declspec(dllimport) HMODULE GetModuleHandleW(LPSTR lpModuleName); 36 | __declspec(dllimport) __declspec(noreturn) void ExitProcess(unsigned int uExitCode); 37 | __declspec(dllimport) void GetStartupInfoW(struct _STARTUPINFOW *lpStartupInfo); 38 | 39 | int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd); 40 | 41 | void _start(void){ 42 | struct _STARTUPINFOW StartupInfo; 43 | GetStartupInfoW(&StartupInfo); 44 | 45 | HINSTANCE hInstance = GetModuleHandleW(0); // @cleanup: __ImageBase? 46 | HINSTANCE hPrevInstance = 0; // "This parameter is always NULL." 47 | wchar_t *lpCmdLine = GetCommandLineW(); 48 | int nShowCmd = (StartupInfo.dwFlags & /*STARTF_USESHOWWINDOW*/1) ? StartupInfo.wShowWindow : /*SW_SHOWDEFAULT*/10; 49 | 50 | int ExitCode = wWinMain(hInstance, hPrevInstance, lpCmdLine, nShowCmd); 51 | ExitProcess(ExitCode); 52 | } 53 | -------------------------------------------------------------------------------- /implicit/pre_wmain_no_args.c: -------------------------------------------------------------------------------- 1 | // 2 | // Unfortunally, Windows does not draw a distinction between the main 3 | // thread and any other thread. This means when the main thread exits its 4 | // start routine, the process will not exit, only `ExitThread` is called. 5 | // Hence, we need to provide this `pre_wmain_no_args.c` file, to exit the 6 | // process when it returns from `wmain`. 7 | // 8 | 9 | #pragma comment(lib, "kernel32") 10 | __declspec(dllimport) __declspec(noreturn) void ExitProcess(unsigned int uExitCode); 11 | 12 | int wmain(void); 13 | 14 | int _start(void){ 15 | 16 | int exit_code = wmain(); 17 | ExitProcess((unsigned int)exit_code); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/options.h: -------------------------------------------------------------------------------- 1 | 2 | #define time_perfomance 0 3 | 4 | #define READ_PDB_AFTER_EMITING_IT 0 5 | #define PRINT_PREPROCESSED_FILE 0 6 | #define DUMP_OUT_PDB 0 7 | #define BUILD_PDB_DUMPER 0 8 | #define DUMP_OBJ 0 9 | 10 | #define PRINT_ADDITIONAL_INCLUDE_DIRECTORIES 0 11 | 12 | #define print_tokenizer_stats 0 13 | 14 | // tokenizer 15 | #define DEBUGGING_MACRO_EXPANSION 0 16 | #define DEBUG_DEFINE_ARGUMENT_SUBSTITUTION 0 17 | #define DEBUGGING_TOKEN_BUCKET_ARRAYS 0 18 | // #define DEFINE_TO_PRINT "__crt_va_start" 19 | 20 | 21 | #define PRINT_COMMAND_LINE 1 22 | #define PRINT_PREDEFINED_MACROS 0 23 | 24 | #define SKIP_pragmas 1 25 | 26 | #define DEBUG_BREAK_ON_ERROR 1 27 | #define DEBUG_BREAK_ON_WARNING 0 28 | 29 | #define LOCAL_ATOM_TABLE 0 30 | 31 | // #define PRINT_SYSTEM_INCLUDE_PATHS 1 32 | -------------------------------------------------------------------------------- /tests/broken/_start_with_ExitProcess_should_not_warn_for_no_return_a_value.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | // broken 3 | 4 | #pragma comment(lib, "kernel32") 5 | 6 | __declspec(dllimport) void ExitProcess(unsigned int uExitCode); 7 | __declspec(dllimport) __declspec(noreturn) void ExitProcess(unsigned int uExitCode); 8 | 9 | int _start(){ 10 | ExitProcess(1337); 11 | // This should NOT warn for not returning a value (but right no (and for now) it does). 12 | } 13 | -------------------------------------------------------------------------------- /tests/broken/big_struct.c: -------------------------------------------------------------------------------- 1 | // broken 2 | 3 | #define LIM1(x) x##0; x##1; x##2; x##3; x##4; x##5; x##6; x##7; x##8; x##9; 4 | #define LIM2(x) LIM1(x##0) LIM1(x##1) LIM1(x##2) LIM1(x##3) LIM1(x##4) \ 5 | LIM1(x##5) LIM1(x##6) LIM1(x##7) LIM1(x##8) LIM1(x##9) 6 | #define LIM3(x) LIM2(x##0) LIM2(x##1) LIM2(x##2) LIM2(x##3) LIM2(x##4) \ 7 | LIM2(x##5) LIM2(x##6) LIM2(x##7) LIM2(x##8) LIM2(x##9) 8 | #define LIM4(x) LIM3(x##0) LIM3(x##1) LIM3(x##2) LIM3(x##3) LIM3(x##4) \ 9 | LIM3(x##5) LIM3(x##6) LIM3(x##7) LIM3(x##8) LIM3(x##9) 10 | #define LIM5(x) LIM4(x##0) LIM4(x##1) LIM4(x##2) LIM4(x##3) LIM4(x##4) \ 11 | LIM4(x##5) LIM4(x##6) LIM4(x##7) LIM4(x##8) LIM4(x##9) 12 | #define LIM6(x) LIM5(x##0) LIM5(x##1) LIM5(x##2) LIM5(x##3) LIM5(x##4) \ 13 | LIM5(x##5) LIM5(x##6) LIM5(x##7) LIM5(x##8) LIM5(x##9) 14 | #define LIM7(x) LIM6(x##0) LIM6(x##1) LIM6(x##2) LIM6(x##3) LIM6(x##4) \ 15 | LIM6(x##5) LIM6(x##6) LIM6(x##7) LIM6(x##8) LIM6(x##9) 16 | 17 | struct q20_struct 18 | { 19 | LIM4 (char m) 20 | }; 21 | 22 | int main(){} 23 | -------------------------------------------------------------------------------- /tests/broken/filling_in_bounds_for_array_of_unknown_size.c: -------------------------------------------------------------------------------- 1 | // broken 2 | #include 3 | 4 | int (*x[])[]; 5 | int (*x[])[5]; 6 | int (*x[4])[]; 7 | int main(void) 8 | { 9 | printf("Length of x = %llu\n", sizeof(x)/sizeof(x[0])); 10 | printf("Length of *x[0] = %llu\n", sizeof(*x[0])/sizeof((*x[0])[0])); 11 | return 0; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /tests/broken/non_constant_initializer_in_pruned_function.c: -------------------------------------------------------------------------------- 1 | // broken 2 | // fail "Initializer is not a constant." 3 | 4 | void foo() { 5 | static short w = (int)&foo; /* initializer not computable */ 6 | } 7 | 8 | int main(){ 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /tests/broken/out_of_order_typedef_and_abstract_function_declarator.c: -------------------------------------------------------------------------------- 1 | // broken 2 | 3 | // This one should be the same as the ones below, 4 | // as this is how I want to handle out-of-order declarations. 5 | // Currently, this is broken though. 6 | int function1(int (typename)); 7 | 8 | typedef int typename; 9 | 10 | // These two declarations are the same, because of how abstract declarators work. 11 | int function1(int (typename)); 12 | int function1(int (*)(typename a)); 13 | 14 | int main(){} 15 | -------------------------------------------------------------------------------- /tests/broken/self_include.c: -------------------------------------------------------------------------------- 1 | // broken 2 | 3 | #include "self_include.c" -------------------------------------------------------------------------------- /tests/broken/unresolved_type_as_second_in_declaration_list_makes_the_first_one_be_defined_twice.c: -------------------------------------------------------------------------------- 1 | // broken 2 | 3 | struct unresolved *unresolved_one = (void *)0x1337133713371337, unresolved_two; 4 | 5 | struct unresolved{ 6 | int a; 7 | }; 8 | 9 | int main(){ 10 | } 11 | -------------------------------------------------------------------------------- /tests/broken/using_the_size_of_an_array_of_unknown_size_before_it_is_filled_in.c: -------------------------------------------------------------------------------- 1 | // broken 2 | // run 3 | 4 | #define assert(a) if(!(a)) return 1; 5 | 6 | int array_of_unknown_size[]; 7 | int what_size_do_I_have[sizeof(array_of_unknown_size)]; 8 | int array_of_unknown_size[4]; 9 | 10 | int main(){ 11 | 12 | assert(sizeof(array_of_unknown_size) == 16); 13 | assert(sizeof(what_size_do_I_have) == 16); 14 | return 0; 15 | } 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/compile/LLONG_MAX_should_be_signed.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int arst[(LLONG_MIN < 0) ? 1 : -1]; 5 | int arst[(-LLONG_MAX < 0) ? 1 : -1]; 6 | 7 | int main(){ 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/_Generic_with_function_or_array.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | int main(void){ 4 | struct { 5 | int a :13; 6 | } bitfield; 7 | _Atomic int atomic_int; 8 | 9 | _Static_assert(_Generic(main, int (*)(void) : 1 ), ""); 10 | _Static_assert(_Generic("abc", char *: 1), ""); 11 | _Static_assert(_Generic(bitfield.a, int: 1), ""); 12 | _Static_assert(_Generic(atomic_int, int: 1), ""); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /tests/compile/__LINE__should_be_correct.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #define CONCAT_INNER(a, b) a ## b 4 | #define CONCAT(a, b) CONCAT_INNER(a, b) 5 | 6 | #define CONCAT_LINE(a) CONCAT(a, __LINE__) 7 | 8 | int main(){ 9 | 10 | int CONCAT_LINE(a) = 1; 11 | 12 | return a10; 13 | } 14 | -------------------------------------------------------------------------------- /tests/compile/__has_include.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #if __has_include("this_is_not_a_valid_include_file.h") 4 | # error We should not have the include file "this_is_not_a_valid_include_file.h". 5 | #endif 6 | 7 | #if !__has_include(__FILE__) 8 | # error We should have the current file as an include file. 9 | #endif 10 | 11 | 12 | #if __has_include() 13 | # error We should not have the include file 14 | #endif 15 | 16 | #if !__has_include() 17 | # error We should have the include file 18 | #endif 19 | 20 | int main(){} 21 | 22 | -------------------------------------------------------------------------------- /tests/compile/accept_defines_with_the_open_paren_on_the_next_line.c: -------------------------------------------------------------------------------- 1 | 2 | #define arst() 1 3 | 4 | 5 | int main(){ 6 | return arst 7 | (); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /tests/compile/accept_typedef_to_void_as_empty_parameter_list.c: -------------------------------------------------------------------------------- 1 | 2 | typedef void VOID; 3 | 4 | int arst(VOID){ 5 | return 0; 6 | } 7 | int main(){ 8 | arst(); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/address_of_array.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | int array[400]; 4 | 5 | int main(){ 6 | // right 7 | int *implicit_pointer = array; 8 | int (*explicit_array_pointer)[400] = &array; 9 | 10 | // wrong 11 | //int *explicit_pointer = &array; 12 | //int (*implicit_array_pointer)[400] = array; 13 | } 14 | -------------------------------------------------------------------------------- /tests/compile/anonymous_struct_initialize.c: -------------------------------------------------------------------------------- 1 | 2 | typedef __int32 DWORD, LONG; 3 | typedef __int64 LONGLONG; 4 | 5 | typedef union _LARGE_INTEGER { 6 | struct { 7 | DWORD LowPart; 8 | LONG HighPart; 9 | }; 10 | 11 | struct { 12 | DWORD LowPart; 13 | LONG HighPart; 14 | } u; 15 | LONGLONG QuadPart; 16 | } LARGE_INTEGER; 17 | 18 | LARGE_INTEGER integer = {{0, 0}}; 19 | 20 | 21 | int main(){} 22 | -------------------------------------------------------------------------------- /tests/compile/argument_expansion_and_rescanning.c: -------------------------------------------------------------------------------- 1 | 2 | struct { 3 | int member; 4 | } a; 5 | 6 | #define member a.member 7 | 8 | #define def(m) m 9 | #define def2(m) m + m 10 | 11 | int main(){ 12 | int b = def(member); 13 | int c = def2(member); 14 | return b + c; 15 | } 16 | -------------------------------------------------------------------------------- /tests/compile/array_of_unknown_size_and_unresolved_type.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | static unresolved array[] = { 4 | 1, 5 | }; 6 | typedef int unresolved; 7 | 8 | int main(){ 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/array_of_unknown_size_array_initializer.c: -------------------------------------------------------------------------------- 1 | enum { 2 | READ, 3 | WRITE, 4 | DISCARD, 5 | OTHER, 6 | NUM, 7 | }; 8 | 9 | static const unsigned int array[] = { 10 | [READ] = 1, 11 | [WRITE] = 2, 12 | [DISCARD] = 3, 13 | [OTHER] = 4, 14 | }; 15 | 16 | typedef int _static_assert[ sizeof(array) / sizeof(*array) == NUM ? 1 : -1]; 17 | 18 | int main(){ 19 | } 20 | -------------------------------------------------------------------------------- /tests/compile/array_ordering_which_causes_a_bunch_of_sleeps.c: -------------------------------------------------------------------------------- 1 | 2 | typedef int (*check)(void); // 1 3 | 4 | check global_functions[1] = { arg1_float_or_nr }; 5 | 6 | check arg1_float_or_nr[1] = { arg_float_or_nr }; 7 | 8 | static int arg_float_or_nr(void){ return 0; } 9 | 10 | int main(){} 11 | -------------------------------------------------------------------------------- /tests/compile/assignment_to_incomplete_pointer_with_mismatching_type.c: -------------------------------------------------------------------------------- 1 | 2 | int main(){ 3 | 4 | struct incomplete *incomplete; 5 | incomplete = (int *)incomplete; 6 | 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile/bitfields_and_anonymous_struct_members.c: -------------------------------------------------------------------------------- 1 | 2 | struct s{ 3 | int a : 1; 4 | struct { int b : 1; }; 5 | int c : 1; 6 | }; 7 | 8 | typedef int a[sizeof(struct s) == 12 ? 1 : -1]; 9 | 10 | int main(){ 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /tests/compile/bitfields_and_varargs_functions.c: -------------------------------------------------------------------------------- 1 | 2 | void varargs(int _, ...){ 3 | 4 | } 5 | 6 | int main(){ 7 | 8 | struct{ 9 | char c : 4; 10 | short s : 4; 11 | int i : 4; 12 | long l : 4; 13 | long long ll : 4; 14 | 15 | unsigned char uc : 4; 16 | unsigned short us : 4; 17 | unsigned int ui : 4; 18 | unsigned long ul : 4; 19 | unsigned long long ull : 4; 20 | } bitfield = {0}; 21 | 22 | varargs(0, bitfield.c, bitfield.s, bitfield.i, bitfield.l, bitfield.ll, bitfield.uc, bitfield.us, bitfield.ui, bitfield.ul, bitfield.ull); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /tests/compile/both_branches_of_if_return_a_value.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | 3 | int returns_values_in_if(int a){ 4 | if(a) return 1; 5 | else { return 0; } 6 | } 7 | 8 | int main(){ 9 | return returns_values_in_if(1); 10 | } 11 | -------------------------------------------------------------------------------- /tests/compile/brace_enclosed_string_literal_array_initializers.c: -------------------------------------------------------------------------------- 1 | 2 | char arst[10] = {"arst"}; 3 | 4 | struct arst{ 5 | char arst[10]; 6 | } a = { 7 | .arst = {"arst"}, 8 | }; 9 | 10 | int main(){ 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tests/compile/call_tree.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | // import does not exitst, but gets stripped, because it is only referanced in static function, 4 | // which is never referanced. 5 | __declspec(dllimport) void undefined_dllimport(); 6 | 7 | static int unreferanced_function(){ 8 | undefined_dllimport(); 9 | return 1; 10 | } 11 | 12 | 13 | // one layer deeper 14 | __declspec(dllimport) void second_undefined_dllimport(); 15 | static void statically_referanced_funcion(){ 16 | second_undefined_dllimport(); 17 | } 18 | 19 | static void second_unreferanced_function(){ 20 | statically_referanced_funcion(); 21 | } 22 | 23 | int main(){ 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /tests/compile/calling_comma_expression.c: -------------------------------------------------------------------------------- 1 | 2 | int function(){ 3 | return 0; 4 | } 5 | 6 | int main(){ 7 | return (1, function)(); 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile/cast_struct_to_itself.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | struct s{ 4 | int a; 5 | int b; 6 | }; 7 | 8 | int main(){ 9 | struct s s = { 1, 2 }; 10 | (struct s)s; 11 | } 12 | -------------------------------------------------------------------------------- /tests/compile/comparing_pointers_of_different_types.c: -------------------------------------------------------------------------------- 1 | 2 | void* my_memmove(void* dest, const void* src, unsigned __int64 count) 3 | { 4 | char *dest_ = dest, *src_ = (char *)src; 5 | if ((char*)src + count > dest && src < dest) 6 | { 7 | dest_ += (src_ += count - 1, count - 1); 8 | while (count--) *dest_-- = *src_--; 9 | } 10 | else while (count--) *dest_++ = *src_++; 11 | return dest; 12 | } 13 | 14 | int main(){ 15 | 16 | } 17 | -------------------------------------------------------------------------------- /tests/compile/complex_constant_initializers.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef INCLUDED 3 | 4 | STORAGE_TYPE int global_array[] = { 1, 2, 3, 4, 5 }; 5 | STORAGE_TYPE int *add_for_global_array = global_array + 1; 6 | STORAGE_TYPE int *sub_for_global_array = global_array - 1; 7 | STORAGE_TYPE int global_variable = 1; 8 | STORAGE_TYPE int *add_for_global_variable = &global_variable + 1; 9 | STORAGE_TYPE int *sub_for_global_variable = &global_variable - 1; 10 | STORAGE_TYPE int *initialized_by_array_literal = (int []){1, 2, 3}; 11 | STORAGE_TYPE int *initialized_by_member_of_struct_literal = (struct {int array[10];}){0}.array; 12 | STORAGE_TYPE int *initialized_by_indexed_array_literal = &(int []){1, 2, 3}[0]; 13 | 14 | #else 15 | 16 | #define STORAGE_TYPE 17 | #define INCLUDED 18 | 19 | #include "complex_constant_initializers.c" 20 | 21 | #undef STORAGE_TYPE 22 | 23 | 24 | int main(){ 25 | 26 | #define STORAGE_TYPE static 27 | #include "complex_constant_initializers.c" 28 | 29 | } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /tests/compile/concatinate_macro_called_with_a_newline.c: -------------------------------------------------------------------------------- 1 | 2 | int a_b; 3 | 4 | #define my_define(id) a_##id 5 | 6 | int main(){ 7 | return my_define( 8 | b); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/concatinate_macro_called_with_a_newline_but_also_stringify_it.c: -------------------------------------------------------------------------------- 1 | 2 | int a_b; 3 | 4 | #define my_define(id) a_##id + #id[0] 5 | 6 | int main(){ 7 | return my_define( 8 | b); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/constant_offset.c: -------------------------------------------------------------------------------- 1 | 2 | struct asd{ 3 | int a; 4 | int array[3]; 5 | }; 6 | 7 | int *asd2 = & ((((struct asd *)0)->array)[1]); 8 | int *asd3 = & (((struct asd *)0)->array[1]); 9 | 10 | int main(){ 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tests/compile/custom_main.c: -------------------------------------------------------------------------------- 1 | // compile -entry custom_main 2 | 3 | 4 | int custom_main(){ 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/declarators.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /* 5 | 6 | declaration: 7 | declaration-specifiers init_declarator_list_opt 8 | 9 | declaration-specifiers: 10 | type, storage-class, function-specifier, type specifier, type qualifier 11 | 12 | inti_declarator_list: 13 | init_declarator 14 | init_0declarator, init_declarator_list 15 | 16 | init_declarator: 17 | declarator 18 | declarator = initializer 19 | */ 20 | 21 | // struct declaration 22 | struct s; 23 | // struct definition 24 | struct s { int a; }; 25 | 26 | // variable declaration 27 | int a; 28 | // variable definition 29 | int a = 1; 30 | 31 | // variable of struct type 32 | struct s a2; 33 | // struct and variable definition 34 | struct s2 { int a; } a3 = { 0 }; 35 | 36 | // extern variable and function declaration 37 | extern int e; 38 | extern int e2(); 39 | 40 | // extern variable definitions 41 | extern int e3 = 1337; 42 | extern int e4(){}; 43 | 44 | // static variable and function declaration 45 | static int si; 46 | static int si2(); 47 | 48 | // static variable definitions 49 | extern int si3 = 1337; 50 | extern int si4(){}; 51 | 52 | // functions with calling convention 53 | int __cdecl si5(); 54 | int __stdcall si6(); 55 | 56 | // pointers with size specifier 57 | int *__ptr32 ptr32; 58 | int *__ptr64 ptr64; 59 | 60 | // functions with declspec 61 | __declspec(dllimport) int import(); 62 | int __declspec(dllexport) _export() {}; 63 | 64 | // aligned type 65 | struct __declspec(align(16)) {int a;} aligned_int; 66 | 67 | 68 | // static function declaration that gets filled in as non-static 69 | int static static_function(void); 70 | 71 | 72 | 73 | // simple type specifier simple identifier, function, declaration 74 | int main(); 75 | // simple type specifier simple identifier, function, defintion 76 | int main(){ 77 | static_function(); 78 | } 79 | 80 | int static_function(void){} 81 | 82 | int (a); 83 | int (b)(int a); 84 | int ((b)(int a)); 85 | -------------------------------------------------------------------------------- /tests/compile/defined_type_for_comparison_operations_should_be_small.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | 3 | int main(){ 4 | unsigned __int64 a; 5 | 6 | int b = 1, c = 2; 7 | // These should not warn for int to u64 as they have "defined type" u8. 8 | a = (b==c); 9 | a = (b!=c); 10 | a = (bc); 12 | a = (b<=c); 13 | a = (b>=c); 14 | a = (b&&c); 15 | a = (b||c); 16 | a = (1 == 2); 17 | a = (1 != 2); 18 | a = (1 <= 2); 19 | a = (1 >= 2); 20 | a = (1 < 2); 21 | a = (1 > 2); 22 | a = (1 && 2); 23 | a = (1 || 2); 24 | return (int)a; 25 | } 26 | -------------------------------------------------------------------------------- /tests/compile/disabled_invalid_preprocessor_directive.c: -------------------------------------------------------------------------------- 1 | 2 | #if 0 3 | # arst 4 | #endif 5 | 6 | int main(){ 7 | return 1; 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile/disabled_static_elif_tests.c: -------------------------------------------------------------------------------- 1 | 2 | #if 1 3 | #elif 1 4 | #error should not fire. 5 | #elif 1 6 | #error should not fire. 7 | #elif 1 8 | #error should not fire. 9 | #else 10 | #error should not fire. 11 | #endif 12 | 13 | #if 0 14 | #if 0 15 | #elif 1 16 | #error should not fire. 17 | #endif 18 | #endif 19 | 20 | #if 0 21 | #if 0 22 | #else 23 | #error should not fire. 24 | #endif 25 | #endif 26 | 27 | #if 0 28 | #if 0 29 | #elif 0 30 | #elif 1 31 | #error should not fire. 32 | #else 33 | #error should not fire. 34 | #endif 35 | #endif 36 | 37 | #if 0 38 | #if 1 39 | #if 0 40 | #elif 1 41 | #error should not fire 42 | #endif 43 | #endif 44 | #endif 45 | 46 | int main(){} 47 | -------------------------------------------------------------------------------- /tests/compile/dllimport_referanced_by_global.c: -------------------------------------------------------------------------------- 1 | // compile -L ucrt.lib 2 | 3 | __declspec(dllimport) float floorf(float); 4 | 5 | int main(){ 6 | 7 | float asd = (&floorf)(1.43f); 8 | 9 | return (int)asd; 10 | } 11 | -------------------------------------------------------------------------------- /tests/compile/dont_warn_on_assignment_type_mismatch_when_its_fine.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | 3 | int main(){ 4 | 5 | __int32 int32 = 1337; 6 | 7 | __int8 int8 = 0; 8 | int8 = int8 + 37; // Should not warn, as s8 + s8 = s8. 9 | 10 | int8 = (int32 % 10); 11 | int8 = (int32 & 0xf); 12 | int8 = !int32; 13 | 14 | int8 = int8 + sizeof(int32); 15 | int8 = int8 + sizeof int32; 16 | int8 = int8 + sizeof(__int32); 17 | 18 | int8 = int8 + _Alignof(int32); 19 | int8 = int8 + _Alignof int32; 20 | int8 = int8 + _Alignof(__int32); 21 | 22 | return int8; 23 | } 24 | -------------------------------------------------------------------------------- /tests/compile/double_array_and_index_initialzer.c: -------------------------------------------------------------------------------- 1 | 2 | int array[1][100] = { 3 | [0][10] = 1, 4 | }; 5 | 6 | int main(){ 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile/double_array_subscript.c: -------------------------------------------------------------------------------- 1 | 2 | int main(){ 3 | { 4 | static char double_array[2][2] = { 5 | {1, 2}, 6 | {3, 4}, 7 | }; 8 | 9 | int i = 0; 10 | int j = 0; 11 | 12 | if(double_array[i][j] != 1) return 1; 13 | 14 | i += 1; 15 | if(double_array[i][j] != 3) return 1; 16 | 17 | j += 1; 18 | if(double_array[i][j] != 4) return 1; 19 | 20 | i -= 1; 21 | if(double_array[i][j] != 2) return 1; 22 | } 23 | 24 | { 25 | static short double_array[2][2] = { 26 | {1, 2}, 27 | {3, 4}, 28 | }; 29 | 30 | int i = 0; 31 | int j = 0; 32 | 33 | if(double_array[i][j] != 1) return 1; 34 | 35 | i += 1; 36 | if(double_array[i][j] != 3) return 1; 37 | 38 | j += 1; 39 | if(double_array[i][j] != 4) return 1; 40 | 41 | i -= 1; 42 | if(double_array[i][j] != 2) return 1; 43 | } 44 | 45 | { 46 | static int double_array[2][2] = { 47 | {1, 2}, 48 | {3, 4}, 49 | }; 50 | 51 | int i = 0; 52 | int j = 0; 53 | 54 | if(double_array[i][j] != 1) return 1; 55 | 56 | i += 1; 57 | if(double_array[i][j] != 3) return 1; 58 | 59 | j += 1; 60 | if(double_array[i][j] != 4) return 1; 61 | 62 | i -= 1; 63 | if(double_array[i][j] != 2) return 1; 64 | } 65 | 66 | { 67 | static __int64 double_array[2][2] = { 68 | {1, 2}, 69 | {3, 4}, 70 | }; 71 | 72 | int i = 0; 73 | int j = 0; 74 | 75 | if(double_array[i][j] != 1) return 1; 76 | 77 | i += 1; 78 | if(double_array[i][j] != 3) return 1; 79 | 80 | j += 1; 81 | if(double_array[i][j] != 4) return 1; 82 | 83 | i -= 1; 84 | if(double_array[i][j] != 2) return 1; 85 | } 86 | 87 | 88 | return 0; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /tests/compile/double_braced_scalar_initializers.c: -------------------------------------------------------------------------------- 1 | 2 | short a = (short){{1}}; 3 | 4 | int main(){ 5 | short b = {{1}}; 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/double_include_of_pathed_system_include.c: -------------------------------------------------------------------------------- 1 | 2 | // @note: we try to find this by _short-name_ which is 'stat.h' 3 | // but we search by 'sys/stat.h' so we cannot find it and thus include it twice... 4 | #include 5 | #include 6 | 7 | int main(){ 8 | 9 | } 10 | 11 | -------------------------------------------------------------------------------- /tests/compile/double_typedef_to_unresolved.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | typedef unresolved a; 4 | typedef unresolved a; 5 | 6 | typedef int unresolved; 7 | 8 | typedef unresolved a; 9 | 10 | int main(){ 11 | } -------------------------------------------------------------------------------- /tests/compile/easy.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | int main(){ 4 | } 5 | -------------------------------------------------------------------------------- /tests/compile/elif_inside_if0_block_should_not_complain_about_junk.c: -------------------------------------------------------------------------------- 1 | // reject "Junk after '#elif'." 2 | 3 | #if 0 4 | #if 1 5 | #elif defined(__HLC__) 6 | #endif 7 | #endif 8 | 9 | int main(){ 10 | 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tests/compile/empty_hashes.c: -------------------------------------------------------------------------------- 1 | 2 | char *asd; 3 | 4 | #define __C(a, b) a##b 5 | #define C(a,b) __C(a, b) 6 | 7 | #define zero_define 8 | 9 | #define __stringfy(a) #a 10 | #define stringfy(a) __stringfy(a) 11 | 12 | 13 | int main(){ 14 | C(zero_define, asd); 15 | C(asd, zero_define); 16 | asd = stringfy(zero_define); 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/compile/empty_hashhash.c: -------------------------------------------------------------------------------- 1 | 2 | #define P1(a,b) a##b 3 | P1(,) 4 | 5 | int main(){} -------------------------------------------------------------------------------- /tests/compile/endif_last_thing_in_the_file.c: -------------------------------------------------------------------------------- 1 | 2 | int main(){} 3 | 4 | #if 0 5 | #endif 6 | -------------------------------------------------------------------------------- /tests/compile/escaping_should_happend_before_concatination.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | int main(){ 4 | "\x90" "1$r"; 5 | 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/extenal_variable_inside_function_compiling_to_object.c: -------------------------------------------------------------------------------- 1 | // compile /c 2 | 3 | int main(){ 4 | extern int a; 5 | } 6 | 7 | int a = 1337; 8 | -------------------------------------------------------------------------------- /tests/compile/extern_const_declspec.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | extern const __declspec(align(8)) int a = 1337; 4 | 5 | int main(){ 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /tests/compile/extern_dllexport_declarations_of_unresolved_type_which_has_its_address_taken.c: -------------------------------------------------------------------------------- 1 | // compile /c 2 | 3 | __declspec(dllexport) extern struct lv_obj_class_t lv_obj_class; 4 | 5 | int *arst = &lv_obj_class; 6 | 7 | int main(){ 8 | 9 | return *arst; 10 | } 11 | -------------------------------------------------------------------------------- /tests/compile/extraneous_semicolons.c: -------------------------------------------------------------------------------- 1 | // check "Extraneous ';' in struct." 2 | // check "Extraneous ';' at global scope." 3 | 4 | ; 5 | 6 | struct hello{ 7 | ; 8 | 9 | int a; 10 | }; 11 | 12 | 13 | int main(){ 14 | struct hello arst = {0}; 15 | 16 | return arst.a; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /tests/compile/forgetting_to_return_a_value.c: -------------------------------------------------------------------------------- 1 | // check "must return a value." 2 | 3 | int *forgets_to_return_a_value(){ 4 | 5 | } 6 | 7 | int main(){ 8 | return *forgets_to_return_a_value(); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/function_containing_noreturn_call_must_not_return_a_value.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | 3 | __declspec(inline_asm) __declspec(noreturn) void __fastfail(unsigned int __exit_code){ 4 | mov ecx, __exit_code 5 | int 0x29 6 | } 7 | 8 | int function(){ 9 | 10 | __fastfail(0); 11 | } 12 | 13 | int main(){ 14 | function(); 15 | } 16 | -------------------------------------------------------------------------------- /tests/compile/function_declaration_with_argument_of_unresolved_type_gets_defined.c: -------------------------------------------------------------------------------- 1 | 2 | int function(unresolved arg); 3 | int function(unresolved arg){ 4 | return arg; 5 | } 6 | 7 | typedef int unresolved; 8 | 9 | int function2(struct unresolved); 10 | int function2(struct unresolved arg){ 11 | return arg.member; 12 | } 13 | 14 | struct unresolved{ 15 | int member; 16 | }; 17 | 18 | int main(){ 19 | function(1); 20 | function2((struct unresolved){1}); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /tests/compile/function_in_if.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | int main(){ 4 | char array[100]; 5 | if(!array) return 1; 6 | if(main) return 1; else return 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/compile/function_like_macro_in_argument_list_of_other_macro_that_is_not_expanded_in_the_arguments_but_only_during_rescanning.c: -------------------------------------------------------------------------------- 1 | 2 | #define lparen ( 3 | #define rparen ) 4 | 5 | #define arst() 6 | 7 | #define a(a, b) a b 8 | 9 | 10 | int main(){ 11 | a(arst lparen, rparen) 12 | } 13 | -------------------------------------------------------------------------------- /tests/compile/function_like_macro_with_space_parameter_list.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #define macro( ) 4 | 5 | int main(){ 6 | macro( ); 7 | } 8 | -------------------------------------------------------------------------------- /tests/compile/function_pointer_deref.c: -------------------------------------------------------------------------------- 1 | 2 | void (*function_pointer)(void); 3 | 4 | int main(){ 5 | function_pointer = main; 6 | (*function_pointer)(); 7 | } 8 | -------------------------------------------------------------------------------- /tests/compile/function_pointer_deref_address.c: -------------------------------------------------------------------------------- 1 | // check "void(*)()" 2 | 3 | int main(){ 4 | void (*ident_0)(); 5 | int *asd = &*ident_0; // '&*ident_0' should be of type 'void (*)()'. 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/gcc_extension_for_removing_comma_for_empty__VA_ARGS__.c: -------------------------------------------------------------------------------- 1 | 2 | #define va_macro(a, ...) a, ## __VA_ARGS__ 3 | #define non_va_macro(a, b) a, ## b 4 | 5 | int function(int a, int b){ 6 | return a + b; 7 | } 8 | 9 | int main(){ 10 | int a = va_macro(1); 11 | int b = va_macro(1,); 12 | int c = function(va_macro(1, 2)); 13 | int d = function(va_macro(1, 2)); 14 | 15 | return a + b + c + d; 16 | } 17 | -------------------------------------------------------------------------------- /tests/compile/globally_referenced_enum_member_compile_to_object.c: -------------------------------------------------------------------------------- 1 | // compile /c 2 | 3 | typedef enum{ 4 | INITIALIZED_ENUM_MEMBER = 1, 5 | } hello; 6 | 7 | hello arst = INITIALIZED_ENUM_MEMBER; 8 | 9 | int main(){ 10 | 11 | } 12 | -------------------------------------------------------------------------------- /tests/compile/hashhash.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #define h0_1() what##up 4 | #define h0_2() what##1 5 | 6 | #define h0_1_no what##no 7 | #define h0_2_no what##0 8 | 9 | #define h1l(a) a##1337 10 | #define h1r(a) asd_##a 11 | #define h2(a, b) a##b 12 | #define h3(a, b, c) a##b##c 13 | 14 | int main(){ 15 | // basic tests 16 | int h0_1(); 17 | (void)whatup; 18 | int h0_2(); 19 | (void)what1; 20 | 21 | #define what xxx 22 | #define up yyy 23 | (void)h0_1(); // this means they are not expanded? 24 | 25 | #define xxxyyy() h0_1 26 | 27 | //h2(xxx,yyy)(); // h0_1 undeclared identifier 28 | 29 | 30 | int h0_1_no; 31 | (void)whatno; 32 | int h0_2_no; 33 | (void)what0; 34 | 35 | int h1l(asd); 36 | (void)asd1337; 37 | int h1r(1337); 38 | (void)asd_1337; 39 | 40 | int h2(asd, das); 41 | (void)asddas; 42 | int h2(asd, 6969); 43 | (void)asd6969; 44 | 45 | int h2(asd, [1337]); 46 | (void) asd; 47 | 48 | int h3(asd, _, 6969); 49 | (void)asd_6969; 50 | 51 | (void)(h3(whatno, -, whatup)); 52 | 53 | int h3(whatno, 1, whatup); 54 | (void)whatno1whatup; 55 | 56 | // non expanded arguments 57 | #define zero_define 58 | int h1l(zero_define); 59 | (void)zero_define1337; 60 | int h1r(zero_define); 61 | (void)asd_zero_define; 62 | 63 | int h2(zero_define, zero_define); 64 | (void)zero_definezero_define; 65 | 66 | int h3(a, zero_define, b); 67 | (void)azero_defineb; 68 | 69 | // void arguments 70 | 71 | #define e2(a, b) h2(a, b) 72 | #define e3(a, b, c) h3(a, b, c) 73 | int one_two_three_four = e2(zero_define, 1234); 74 | int e2(aaa, zero_define); 75 | (void)aaa; 76 | 77 | aaa = e2(1, ul); 78 | 79 | e3(asd, zero_define, 1337) = e2(asd, 6969); 80 | 81 | // hard ones 82 | struct{ 83 | int f; 84 | } my_1; 85 | e2(my_, 1.f) = aaa; 86 | 87 | int h2(asd, 1blub); 88 | (void)asd1blub; 89 | } 90 | -------------------------------------------------------------------------------- /tests/compile/hello_world.c: -------------------------------------------------------------------------------- 1 | // compile 2 | 3 | // Shows that all standart library headers "work", or at least compile. 4 | 5 | // @note: list taken from wikipedia 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | // Windows does not support for C11, so these are not found 32 | //#include 33 | //#include 34 | //#include 35 | 36 | int main(){ 37 | printf("Hello, World!\n"); 38 | return 1; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /tests/compile/if_with_scope_returns_a_value_only_in_one_branch.c: -------------------------------------------------------------------------------- 1 | // check "must return a value." 2 | 3 | int function(int a){ 4 | if(a){ return 1; } 5 | } 6 | 7 | int main(){ 8 | 9 | function(1); 10 | } 11 | -------------------------------------------------------------------------------- /tests/compile/implicit_float_to_int_in_initializer.c: -------------------------------------------------------------------------------- 1 | 2 | int ident_6 = 0 <= 1.0f; 3 | 4 | int main(){ 5 | return ident_6; 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/include_and_defines.c: -------------------------------------------------------------------------------- 1 | // compile 2 | 3 | #pragma once 4 | 5 | #define stdio asd 6 | // These should probably be handled immediately. 7 | #include 8 | // #include "" 9 | 10 | 11 | #define smaller < 12 | #define file stdint.h 13 | #define bigger > 14 | 15 | // This needs to be defered. 16 | #define include_me smaller file bigger 17 | 18 | #include include_me 19 | 20 | #include __FILE__ 21 | 22 | int main(){ 23 | printf("hello!\n"); 24 | } 25 | -------------------------------------------------------------------------------- /tests/compile/include_math.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | int main(){ 6 | 7 | printf("abs(pi) %d\n", abs(3.141592653)); 8 | printf("abs(-pi) %d\n", abs(-3.141592653)); 9 | 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tests/compile/include_system_include_that_includes_a_relative_include.c: -------------------------------------------------------------------------------- 1 | // compile /I . 2 | 3 | #include 4 | 5 | int main(){ 6 | return arst; 7 | } 8 | -------------------------------------------------------------------------------- /tests/compile/includes_pragma_once_header_with_both_system_and_relative_path_include.c: -------------------------------------------------------------------------------- 1 | // compile -I . 2 | 3 | #ifdef HEADER 4 | #pragma once 5 | 6 | static inline int function(){ return 1; }; 7 | 8 | #else 9 | 10 | #define HEADER 11 | #include "includes_pragma_once_header_with_both_system_and_relative_path_include.c" 12 | #include 13 | 14 | int main(){ 15 | return function(); 16 | } 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /tests/compile/incomplete_struct_match.c: -------------------------------------------------------------------------------- 1 | 2 | struct{ 3 | struct type *a; 4 | } struct1; 5 | 6 | struct type { 7 | int a; 8 | }; 9 | 10 | struct{ 11 | struct type *a; 12 | } struct2; 13 | 14 | int main(){ 15 | struct1 = struct2; 16 | } 17 | -------------------------------------------------------------------------------- /tests/compile/infinite_loop_counts_as_returning_value.c: -------------------------------------------------------------------------------- 1 | // reject "must return a value" 2 | 3 | 4 | int has_infinite_for(){ 5 | for(int a = 0; ; a++){ } 6 | } 7 | 8 | int has_infinite_do_while(){ 9 | do{}while(1); 10 | } 11 | 12 | int has_infinite_while(){ 13 | while(1){} 14 | } 15 | 16 | int main(){ 17 | has_infinite_for() + has_infinite_do_while() + has_infinite_while(); 18 | } 19 | -------------------------------------------------------------------------------- /tests/compile/initialized_dllexport.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | __declspec(dllexport) int hello = 1; 4 | 5 | int main(){ 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/initializer_of_empty_structure.c: -------------------------------------------------------------------------------- 1 | 2 | // @note: if you define this to anything it should not compile. 3 | #define BUG 4 | 5 | struct empty_struct{}; 6 | 7 | struct empty_struct simple_initialized = {BUG}; 8 | 9 | union{ 10 | struct empty_struct empty_struct; 11 | int i; 12 | } union_containing_empty_struct = {BUG}; 13 | 14 | struct empty_struct array_of_empty_structs[10] = {BUG}; 15 | 16 | struct structure_containing_empty_struct{ 17 | struct empty_struct empty_struct; 18 | int i; 19 | } structure_containing_empty_struct = { 20 | // @note: I feel like this should work. gcc doesn't. 21 | // gcc: 'asd3.c:19:5: warning: excess elements in struct initializer' 22 | // clang: 'asd3.c:20:5: error: initializer for aggregate with no elements requires explicit braces' 23 | BUG 24 | }; 25 | 26 | 27 | int main(){ 28 | struct empty_struct a; 29 | struct structure_containing_empty_struct b = { 30 | a, 31 | 1 32 | }; 33 | struct structure_containing_empty_struct c = { 34 | {}, 35 | 1 36 | }; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /tests/compile/initializers.c: -------------------------------------------------------------------------------- 1 | 2 | int int_initializer = 1; 3 | int int_initializer_with_braces = {1}; 4 | 5 | // simple struct initializer 6 | struct { int a; } one_member = {1}; 7 | struct { int a; } one_member_with_braces = {{1}}; 8 | 9 | // aggregate struct initializer 10 | struct { struct {int a;} member; } one_aggregate_member = {1}; 11 | struct { struct {int a;} member; } one_aggregate_member_with_braces = {{1}}; 12 | struct { struct {int a;} member; } one_aggregate_member_with_braces_with_braces = {{{1}}}; 13 | // too many initializers 14 | //struct {struct {int a;} member; } one_aggregate_member_with_braces_with_braces_with_braces = {{{{1}}}}; 15 | 16 | struct {int a; int b;} two_members = {1, 2}; 17 | struct {int a; int b;} two_members_with_braces = { {1} , {2} }; 18 | 19 | struct { struct {int a; int b; } member; } aggregate_two_members = {1, 2}; 20 | struct { struct {int a; int b; } member; } aggregate_two_members_with_braces = {{1, 2}}; 21 | 22 | // @cleanup: simple union initializer 23 | 24 | // simple array initilizers 25 | int int_one_array[1] = {1}; 26 | int int_one_array_with_braces[1] = {{1}}; 27 | 28 | int int_two_array[2] = {1, 2}; 29 | int int_two_array_with_braces[2] = {{1}, {2}}; 30 | int int_two_array_one_initializer[2] = {1}; 31 | int int_two_array_one_initializer_with_braces[2] = {{1}}; 32 | 33 | // aggregate array initilizers 34 | struct {int a;} aggregate_one_array[1] = {1}; 35 | struct {int a;} aggregate_one_array_with_braces[1] = {{1}}; 36 | struct {int a;} aggregate_one_array_with_braces_with_braces[1] = {{{1}}}; 37 | 38 | struct {int a; int b;} aggregate_two_member_array_flat[2] = { 1, 2, 3, 4}; 39 | struct {int a; int b;} aggregate_two_member_array_agg_flat[2] = {{1, 2}, 3, 4}; 40 | struct {int a; int b;} aggregate_two_member_array_agg_agg[2] = {{1, 2}, {3, 4}}; 41 | struct {int a; int b;} aggregate_two_member_array_flat_agg[2] = { 1, 2, {3, 4}}; 42 | 43 | int main(){ 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /tests/compile/inline_intrinsic_function_with_a_bunch_of_arguments.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | int frac_h0; 5 | __m128i v_frac_h0 = _mm_set_epi16((short)frac_h0, (short)frac_h0, (short)frac_h0, (short)frac_h0, (short)frac_h0, (short)frac_h0, (short)frac_h0, (short)frac_h0); 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/invalid_directives_disabled_by_static_if.c: -------------------------------------------------------------------------------- 1 | 2 | #if 0 3 | #!/bin/bash 4 | 5 | #arst 6 | #endif 7 | 8 | int main(){} 9 | -------------------------------------------------------------------------------- /tests/compile/keyword_in_defined.c: -------------------------------------------------------------------------------- 1 | 2 | #if !defined(int) 3 | // ^^^ 4 | // This used to error, as 'int' was substituted to TOKEN_int, 5 | // and then 'defined' expected an identifier. 6 | int main(){} 7 | #endif 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/compile/legal_redeclaration_of_enum.c: -------------------------------------------------------------------------------- 1 | 2 | typedef enum a{ 3 | asd = 1, 4 | } typedef_of_enum; 5 | 6 | typedef enum a{ 7 | asd = 1, 8 | } typedef_of_enum; 9 | 10 | int main(){ 11 | 12 | typedef enum a{ 13 | asd = 1, 14 | } typedef_of_enum; 15 | return 0; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /tests/compile/legal_unresolved_types.c: -------------------------------------------------------------------------------- 1 | 2 | unresolved *pointer_to_unresolved_type; 3 | //unresolved (*pointer_to_unresolved_array)[10]; currently not legal anymore 10.11.2020 4 | 5 | struct{ 6 | unresolved *member; 7 | } struct_that_contains_an_unresolved_member; 8 | 9 | unresolved *function_returning_pointer_to_unresolved_type(){ 10 | return (void *)0; 11 | } 12 | 13 | void function_with_unresolved_argument(unresolved *unresolved_argument){ 14 | (void)unresolved_argument; 15 | } 16 | 17 | 18 | struct unresolved; 19 | typedef struct unresolved unresolved; 20 | 21 | // this actually is not legal I guess... 22 | /* 23 | struct{ 24 | unresolved a; 25 | } *pointer_to_struct_containing_unresolved_member; 26 | */ 27 | 28 | int main(){ 29 | function_with_unresolved_argument(function_returning_pointer_to_unresolved_type()); 30 | 31 | return 0; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /tests/compile/local_function_should_not_complain_about_redeclarations.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | 3 | int main(){ 4 | 5 | int a = 0, b = 1; 6 | 7 | 8 | int function(int a){ 9 | int b = 1; 10 | return a + b; 11 | } 12 | 13 | return function(a + b); 14 | } 15 | -------------------------------------------------------------------------------- /tests/compile/many_lf_enum.c: -------------------------------------------------------------------------------- 1 | int main(){} 2 | 3 | #define LIM1(x) x##0, x##1, x##2, x##3, x##4, x##5, x##6, x##7, x##8, x##9, 4 | #define LIM2(x) LIM1(x##0) LIM1(x##1) LIM1(x##2) LIM1(x##3) LIM1(x##4) \ 5 | LIM1(x##5) LIM1(x##6) LIM1(x##7) LIM1(x##8) LIM1(x##9) 6 | #define LIM3(x) LIM2(x##0) LIM2(x##1) LIM2(x##2) LIM2(x##3) LIM2(x##4) \ 7 | LIM2(x##5) LIM2(x##6) LIM2(x##7) LIM2(x##8) LIM2(x##9) 8 | #define LIM4(x) LIM3(x##0) LIM3(x##1) LIM3(x##2) LIM3(x##3) LIM3(x##4) \ 9 | LIM3(x##5) LIM3(x##6) LIM3(x##7) LIM3(x##8) LIM3(x##9) 10 | #define LIM5(x) LIM4(x##0) LIM4(x##1) LIM4(x##2) LIM4(x##3) LIM4(x##4) \ 11 | LIM4(x##5) LIM4(x##6) LIM4(x##7) LIM4(x##8) LIM4(x##9) 12 | #define LIM6(x) LIM5(x##0) LIM5(x##1) LIM5(x##2) LIM5(x##3) LIM5(x##4) \ 13 | LIM5(x##5) LIM5(x##6) LIM5(x##7) LIM5(x##8) LIM5(x##9) 14 | #define LIM7(x) LIM6(x##0) LIM6(x##1) LIM6(x##2) LIM6(x##3) LIM6(x##4) \ 15 | LIM6(x##5) LIM6(x##6) LIM6(x##7) LIM6(x##8) LIM6(x##9) 16 | 17 | enum q21_enum{ 18 | LIM5 (e) 19 | }; 20 | -------------------------------------------------------------------------------- /tests/compile/member_access_after_array_access_of_later_struct_argument.c: -------------------------------------------------------------------------------- 1 | 2 | static void function(struct unresolved *unresolved){ 3 | unresolved[1].member; 4 | } 5 | 6 | struct unresolved{ int member; }; 7 | 8 | int main(){ 9 | 10 | } 11 | -------------------------------------------------------------------------------- /tests/compile/member_designator_in_initializer_list_has_to_modify_what_the_current_object_is.c: -------------------------------------------------------------------------------- 1 | // check "Wanted 'void*' given 'int'." 2 | 3 | 4 | struct{ 5 | int a; 6 | int b; 7 | void *c; 8 | } arst = { 9 | .b = 1, 10 | 2 // This should initialize the 'void *c' and thus report a warning. This used to initialize the 'int b;' as I forgot to set 'member_at'. 11 | }; 12 | 13 | int main(){ 14 | } 15 | -------------------------------------------------------------------------------- /tests/compile/multiply_by_zero_should_compile.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | int main(){ 4 | int a = 1; 5 | a *= 0; 6 | return a; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /tests/compile/need_to_escape_when_stringifying.c: -------------------------------------------------------------------------------- 1 | 2 | #define make_wide__internal(a) L ## a 3 | #define make_wide(a) make_wide__internal(a) 4 | #define stringify(a) make_wide(#a) 5 | 6 | int main(){ 7 | stringify(!";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"); 8 | } -------------------------------------------------------------------------------- /tests/compile/noreturn_function_returns_a_value.c: -------------------------------------------------------------------------------- 1 | // check "'return' in function declared as '_Noreturn'." 2 | // check "Control flow reaching the end of '_Noreturn' function." 3 | 4 | _Noreturn int noreturn_function_1(){ 5 | return 1; 6 | } 7 | 8 | _Noreturn int noreturn_function_2(){} 9 | 10 | 11 | int main(){ 12 | noreturn_function_1(); 13 | noreturn_function_2(); 14 | } 15 | -------------------------------------------------------------------------------- /tests/compile/one_case_in_switch_statement_forgets_to_return_a_value.c: -------------------------------------------------------------------------------- 1 | // check "must return a value." 2 | 3 | int switch_statement_forgets_to_return_a_value(int a){ 4 | switch(a){ 5 | 6 | case 1: return 1; 7 | case 2: { /*return 1;*/ } break; 8 | default: { 9 | return 1337; 10 | } 11 | } 12 | } 13 | 14 | int main(){ 15 | return switch_statement_forgets_to_return_a_value(1337); 16 | } 17 | -------------------------------------------------------------------------------- /tests/compile/only_one_branch_of_an_if_returns_a_value.c: -------------------------------------------------------------------------------- 1 | // check "must return a value." 2 | 3 | int returns_value_in_one_branch_of_if(int a){ 4 | if(a) return 1; 5 | } 6 | 7 | int main(){ 8 | return returns_value_in_one_branch_of_if(0); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/only_warn_on_redeclartion_with_mismatching_dllexport_or_selectany_attribute.c: -------------------------------------------------------------------------------- 1 | // compile /Wdeclaration_differs_in_attribute 2 | // check "'a': [0] Redeclaration differs in __declspec(dllexport) attribute." 3 | // check "'b': [0] Redeclaration differs in __declspec(dllexport) attribute." 4 | // check "'c': [0] Redeclaration differs in __declspec(selectany) attribute." 5 | // check "'d': [0] Redeclaration differs in __declspec(selectany) attribute." 6 | // check "'e': [0] Redeclaration differs in __declspec(dllimport) attribute." 7 | // check "'f': [0] Redeclaration differs in __declspec(dllimport) attribute." 8 | 9 | int a; 10 | __declspec(dllexport) int a; // warning: Redeclaration differs int __declspec(dllexport) attribute. 11 | __declspec(dllexport) int b; 12 | int b; // warning: Redeclaration differs int __declspec(dllexport) attribute. 13 | int c; 14 | __declspec(selectany) int c; // warning: Redeclaration differs int __declspec(selectany) attribute. 15 | __declspec(selectany) int d; 16 | int d; // warning: Redeclaration differs int __declspec(selectany) attribute. 17 | int e; 18 | __declspec(dllimport) int e; // warning: Redeclaration differs int __declspec(dllimport) attribute. 19 | __declspec(dllimport) int f; 20 | int f; // warning: Redeclaration differs int __declspec(dllimport) attribute. 21 | 22 | int main(){} 23 | -------------------------------------------------------------------------------- /tests/compile/order_of_array_declarators.c: -------------------------------------------------------------------------------- 1 | 2 | typedef int A[3]; 3 | typedef int B[2][3]; 4 | typedef int C[1][2][3]; 5 | 6 | int array[1][2][3]; 7 | int (array[1])[2][3]; 8 | int ((array[1])[2])[3]; 9 | int (array[1][2])[3]; 10 | 11 | C array; 12 | B array[1]; 13 | A array[1][2]; 14 | 15 | int main(){ 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /tests/compile/patch_to_static_variable_obj.c: -------------------------------------------------------------------------------- 1 | // compile /c 2 | 3 | static char buffer[] = "hello :)"; 4 | 5 | int main(){ 6 | 7 | static char* unreachable[] = { 8 | buffer 9 | }; 10 | 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tests/compile/pointer_casts_in_addition_in_static_initializer.c: -------------------------------------------------------------------------------- 1 | 2 | struct structure{ 3 | int *hello; 4 | int *hello2; 5 | }s = { 6 | (int *)((char *)&s + ((__int64)&(((struct structure*)0)->hello))), 7 | (int *)((char *)&s + ((__int64)&(((struct structure*)0)->hello2))), 8 | }; 9 | 10 | int main(){ 11 | return *s.hello; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /tests/compile/pointer_literal_to_submember.c: -------------------------------------------------------------------------------- 1 | 2 | #define offset_in_type(type, member) (unsigned long long)(&((type *)0)->member) 3 | 4 | struct arst{ 5 | struct { int a; } arst; 6 | }; 7 | 8 | 9 | int main(){ 10 | int arst[offset_in_type(struct arst, arst.a) + 1]; 11 | 12 | return 1; 13 | } 14 | -------------------------------------------------------------------------------- /tests/compile/pointer_plus_bitfield.c: -------------------------------------------------------------------------------- 1 | 2 | int main(){ 3 | struct arst{ 4 | int a : 10; 5 | } arst = {1337}; 6 | 7 | int *pointer = (void *)1337; 8 | pointer + arst.a; 9 | pointer - arst.a; 10 | pointer += arst.a; 11 | pointer -= arst.a; 12 | } 13 | -------------------------------------------------------------------------------- /tests/compile/pointer_to_undeclared_struct_in_struct.c: -------------------------------------------------------------------------------- 1 | 2 | struct { 3 | struct asd *asd; 4 | }; 5 | 6 | 7 | int main(){ 8 | 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/pragma_comment_lib.c: -------------------------------------------------------------------------------- 1 | 2 | #pragma comment(lib, "Shell32.lib") 3 | #pragma comment(lib, "kernel32.lib") 4 | 5 | typedef unsigned short wchar_t; 6 | 7 | __declspec(dllimport) wchar_t **CommandLineToArgvW(wchar_t *lpCmdLine, int *pNumArgs); 8 | __declspec(dllimport) wchar_t *GetCommandLineW(void); 9 | 10 | int main(){ 11 | int NumArgs = 0; 12 | CommandLineToArgvW(GetCommandLineW(), &NumArgs); 13 | return NumArgs; 14 | } 15 | -------------------------------------------------------------------------------- /tests/compile/pragma_comment_lib_in_obj.c: -------------------------------------------------------------------------------- 1 | // compile /obj 2 | 3 | #pragma comment(lib, "Shell32.lib") 4 | #pragma comment(lib, "kernel32.lib") 5 | 6 | typedef unsigned short wchar_t; 7 | 8 | __declspec(dllimport) wchar_t **CommandLineToArgvW(wchar_t *lpCmdLine, int *pNumArgs); 9 | __declspec(dllimport) wchar_t *GetCommandLineW(void); 10 | 11 | int main(){ 12 | int NumArgs = 0; 13 | CommandLineToArgvW(GetCommandLineW(), &NumArgs); 14 | return NumArgs; 15 | } 16 | -------------------------------------------------------------------------------- /tests/compile/predeclaration_of_non_defined_dll_export_function.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | __declspec(dllexport) int not_defined(void); 4 | 5 | int main(){ 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/really_large_array_subscripts.c: -------------------------------------------------------------------------------- 1 | 2 | union union_0 { 3 | unsigned __int64 ident_0[3]; 4 | } ident_1; 5 | 6 | int main(){ 7 | union union_0 { 8 | unsigned __int64 ident_0[3]; 9 | } ident_2; 10 | 11 | return ident_1.ident_0[0x048FD4CFFEC78395] + ident_2.ident_0[0x048FD4CFFEC78395]; 12 | } 13 | -------------------------------------------------------------------------------- /tests/compile/redefine_alignas_macro.c: -------------------------------------------------------------------------------- 1 | // compile /std:c11 2 | // check "Redefinition of macro 'alignas'." 3 | 4 | #include 5 | 6 | #define alignas(x) __declspec(align(x)) 7 | 8 | int main(){} 9 | 10 | -------------------------------------------------------------------------------- /tests/compile/redefine_macro_should_only_warn.c: -------------------------------------------------------------------------------- 1 | // check "Redefinition of macro 'macro'." 2 | 3 | #define macro(x) (x) 4 | #define macro(x) 5 | 6 | int main(){ 7 | macro(hello syntax error) 8 | } 9 | 10 | -------------------------------------------------------------------------------- /tests/compile/referencing_an_external_structure_of_unresolved_type_by_address_should_work_in_object_file.c: -------------------------------------------------------------------------------- 1 | // compile /c 2 | 3 | extern struct unresolved a; 4 | 5 | int *b = (void *)&a; 6 | 7 | int main(){ 8 | 9 | int *b = (void *)&a; 10 | return *b; 11 | } 12 | -------------------------------------------------------------------------------- /tests/compile/register_sized_struct_in_conditional_expression_gets_membered.c: -------------------------------------------------------------------------------- 1 | 2 | struct inner{ 3 | unsigned char member; 4 | }; 5 | 6 | struct outer{ 7 | struct inner inner; 8 | }; 9 | 10 | int main(){ 11 | 12 | struct outer *outer = &(struct outer){}; 13 | 14 | struct inner default_inner; 15 | 16 | unsigned char a = (outer ? outer->inner : default_inner).member; 17 | 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /tests/compile/returns_a_value_in_a_subscope.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | 3 | int returns_a_value_in_a_subscope(){ 4 | { return 0; } 5 | } 6 | 7 | int main(){ 8 | return returns_a_value_in_a_subscope(); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/self_referanced_struct_and_typedef.c: -------------------------------------------------------------------------------- 1 | 2 | // repro of weird struct inclusion in 'oaidl.h' 3 | 4 | typedef struct _wireVARIANT *wireVARIANT; // line 278 5 | 6 | typedef struct _wireSAFEARR_VARIANT // line 300 7 | { 8 | int Size; 9 | wireVARIANT *aVariant; 10 | } SAFEARR_VARIANT; 11 | 12 | typedef struct _wireSAFEARRAY_UNION{ // line 335 13 | int type; 14 | union __MIDL_IOleAutomationTypes_0001{ 15 | SAFEARR_VARIANT VariantStr; 16 | } u; 17 | } SAFEARRAYUNION; 18 | 19 | 20 | struct _wireVARIANT{ // line 565 21 | int size; 22 | union{ 23 | wireVARIANT *pvarVal; // line 604 24 | } u; 25 | }; 26 | 27 | 28 | // type_stack: 29 | // [0] = struct _wireSAFEARR_VARIANT 30 | // [1] = pointer to wireVariant 31 | // [2] = pointer to struct _wireVARIANT 32 | // [3] = struct _wireVARIANT 33 | // [4] = union 34 | // [5] = pointer to wireVARIANT 35 | // next one would be 36 | // [6] = pointer to struct _wireVARIANT 37 | // but this one is already marked 'tempoary' 38 | 39 | 40 | int main(){ 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /tests/compile/separator_in_number.c: -------------------------------------------------------------------------------- 1 | 2 | int main(){ 3 | return 3200'000'000 + 0x3200'000'000 + 0b100'000'000; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /tests/compile/shadowing_global_struct_at_local_scope.c: -------------------------------------------------------------------------------- 1 | 2 | struct asd {int a;}; 3 | 4 | 5 | struct asd2 { int a; }; 6 | 7 | 8 | int main(){ 9 | struct asd {float b;} redeclaration; 10 | 11 | struct asd2 should_be_4_bytes; 12 | 13 | struct asd2{ 14 | int a; 15 | int b; 16 | } should_be_8_bytes; 17 | 18 | #define static_assert(expr) typedef char static_assert_hack[(expr) ? 1 : -1] 19 | 20 | static_assert(sizeof(should_be_4_bytes) == 4); 21 | static_assert(sizeof(should_be_8_bytes) == 8); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /tests/compile/signed_and_unsigned_integer_literals_in_static_if.c: -------------------------------------------------------------------------------- 1 | 2 | typedef _Atomic(char) atomic_char; 3 | 4 | __declspec(inline_asm) _Bool __atomic_compare_exchange_char(atomic_char *object, char *expected, char desired){ 5 | 6 | mov al, [expected] 7 | lock cmpxchg [object], desired 8 | mov [expected], al 9 | 10 | sete al 11 | return al 12 | } 13 | 14 | 15 | extern inline char __atomic_fetch_or_char(atomic_char *object, char operand){ 16 | char desired, expected = *object; 17 | do{ 18 | desired = operand | expected; 19 | }while(!__atomic_compare_exchange_char(object, &expected, desired)); 20 | return expected; 21 | } 22 | 23 | atomic_char a_char; 24 | 25 | int main(){ 26 | char n_char; 27 | 28 | n_char = __atomic_fetch_or_char(&a_char, n_char); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /tests/compile/sizeof_full_bitfield.c: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | unsigned version: 2; 3 | unsigned type: 6; 4 | 5 | unsigned payload: 24; 6 | } LanPacket; 7 | 8 | #define CASSERT(EXPRESSION) switch (0) {case 0: case (EXPRESSION):;} 9 | 10 | int main() { 11 | CASSERT(sizeof(LanPacket) == 4); 12 | } 13 | -------------------------------------------------------------------------------- /tests/compile/sizeof_global_in_array_length_inside_structure_at_global_scope.c: -------------------------------------------------------------------------------- 1 | 2 | int a; 3 | struct{ 4 | int arr[sizeof(a)]; 5 | }; 6 | 7 | int main(){ 8 | 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/sizeof_on_array_of_unknown_size_array_literal.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | int main(){ 4 | return sizeof((char[]){1, 2, 3}); 5 | } 6 | -------------------------------------------------------------------------------- /tests/compile/sleeping_on_typedef_to_already_defined_struct.c: -------------------------------------------------------------------------------- 1 | 2 | struct structure {}; 3 | 4 | typedef structure *pointer; 5 | typedef struct structure structure; 6 | 7 | int main(){ 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/sleeping_type.c: -------------------------------------------------------------------------------- 1 | 2 | typedef struct unresolved sleeping_type; 3 | 4 | struct unresolved{ 5 | int a; 6 | }; 7 | 8 | sleeping_type usage; 9 | 10 | int main(){ 11 | usage.a = 1337; 12 | return usage.a; 13 | } -------------------------------------------------------------------------------- /tests/compile/sleeping_unresolved_array.c: -------------------------------------------------------------------------------- 1 | 2 | int array[] = { 3 | unresolved, 4 | }; 5 | 6 | enum{ 7 | unresolved, 8 | }; 9 | 10 | int main(){ 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tests/compile/static_array_of_enum_size.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | enum{ 4 | size = 10, 5 | }; 6 | 7 | // this caused an infinite loop, as 'size' was marked 'static' but it is not, 8 | // and thus we slept on the wrong declaration 9 | static char array[size]; 10 | 11 | int main(){ 12 | 13 | } 14 | -------------------------------------------------------------------------------- /tests/compile/static_if_and_ternaries.c: -------------------------------------------------------------------------------- 1 | 2 | #if 0 ? 1 : 0 3 | #error 4 | #endif 5 | 6 | #if 1 ? 1 : 0 7 | #else 8 | #error 9 | #endif 10 | 11 | #if !(1 ? 1 : 0) 12 | #error 13 | #endif 14 | 15 | 16 | #if 1 ? 1 : 0 ? 1 : 0 17 | 18 | #else 19 | #error 20 | #endif 21 | 22 | #if 0 ? 1 : 0 ? 1 : 0 23 | #error 24 | #endif 25 | 26 | #if 0 ? 1 : 1 ? 1 : 0 27 | #else 28 | #error 29 | #endif 30 | 31 | int main(){ 32 | } 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /tests/compile/static_if_space_before_directive_that_follows_a_directive.c: -------------------------------------------------------------------------------- 1 | 2 | #if 1 3 | 4 | 5 | #if 1 6 | #endif 7 | #if 1 8 | 9 | #endif 10 | #endif 11 | 12 | int main(){} 13 | -------------------------------------------------------------------------------- /tests/compile/static_thread_local_variable_with_patch.c: -------------------------------------------------------------------------------- 1 | // compile /obj 2 | 3 | int arst2; 4 | 5 | __declspec(thread) static int *arst = &arst2; 6 | 7 | int main(){ 8 | return *arst; 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/string_literal_column_tests.c: -------------------------------------------------------------------------------- 1 | // check "(17,28): Warning" 2 | // check "(18,30): Warning" 3 | // check "(19,29): Warning" 4 | // check "(20,29): Warning" 5 | // check "(21,29): Warning" 6 | // check "(22,30): Warning" 7 | // check "(26,15): Warning" 8 | // check "(27,17): Warning" 9 | // check "(28,16): Warning" 10 | // check "(29,16): Warning" 11 | // check "(30,16): Warning" 12 | 13 | int main(){ 14 | 15 | int asd; 16 | 17 | {"string_literal"; int asd;} 18 | {"string_literal\n"; int asd;} 19 | {L"string_literal"; int asd;} 20 | {U"string_literal"; int asd;} 21 | {u"string_literal"; int asd;} 22 | {u8"string_literal"; int asd;} 23 | // {u16"string_literal"; int asd;} 24 | // {u32"string_literal"; int asd;} 25 | 26 | {'c'; int asd;} 27 | {'c\n'; int asd;} 28 | {L'c'; int asd;} 29 | {U'c'; int asd;} 30 | {u'c'; int asd;} 31 | // {u8'c'; int asd;} 32 | // {u16'c'; int asd;} 33 | // {u32'c'; int asd;} 34 | } 35 | -------------------------------------------------------------------------------- /tests/compile/string_literal_in_constant_expression.c: -------------------------------------------------------------------------------- 1 | 2 | char *ident_0 = &("0"[0]); 3 | 4 | int main(){ 5 | return ident_0[0]; 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/string_question_mark_and_implcit_conversion_to_bool.c: -------------------------------------------------------------------------------- 1 | 2 | int main(){ 3 | int a = "a" ? 1 : 0; 4 | } 5 | -------------------------------------------------------------------------------- /tests/compile/subscript_with_bitfield_assignment.c: -------------------------------------------------------------------------------- 1 | 2 | int main(){ 3 | int *values; 4 | struct { int code: 8; } *reg = 0; 5 | values[reg->code]; // also already borked 6 | values[reg->code = 5]; 7 | } 8 | -------------------------------------------------------------------------------- /tests/compile/switch_statement_returns_value.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | 3 | int switch_statement_returning_value(int a){ 4 | switch(a){ 5 | 6 | case 1: return 1; 7 | case 2: { return 1; } break; 8 | default: { 9 | return 1337; 10 | } 11 | } 12 | } 13 | 14 | int main(){ 15 | return switch_statement_returning_value(1337); 16 | } 17 | -------------------------------------------------------------------------------- /tests/compile/switch_with_default_case_does_return_a_value.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | 3 | char *function(int a){ 4 | switch(a){ 5 | default: return ""; 6 | } 7 | } 8 | 9 | int main(){ 10 | function(1); 11 | } 12 | -------------------------------------------------------------------------------- /tests/compile/system_include_dir_for_relative_include_test/relative_include.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | int arst; 4 | -------------------------------------------------------------------------------- /tests/compile/system_include_dir_for_relative_include_test/system_include.h: -------------------------------------------------------------------------------- 1 | 2 | #include "relative_include.h" 3 | -------------------------------------------------------------------------------- /tests/compile/test_for_broken_declaration_regrowing_function.c: -------------------------------------------------------------------------------- 1 | 2 | int arst(){ 3 | 4 | int *it; 5 | char *k2 = 0; 6 | 7 | 8 | int a1, a2, a3, a4; 9 | int b1, b2, b3, b4; 10 | int c1, c2, c3, c4; 11 | int d1, d2, d3, d4; 12 | 13 | (k2); // This used to report an undeclared identifier, because 'it' and 'k2' hash to the same thing and the array growing function was wrong. 14 | return 0; 15 | } 16 | 17 | int main(){} 18 | -------------------------------------------------------------------------------- /tests/compile/this_is_a_dll_because_of_DllMain.c: -------------------------------------------------------------------------------- 1 | 2 | int DllMain(){ 3 | return 1; 4 | } 5 | -------------------------------------------------------------------------------- /tests/compile/this_is_a_dll_with_no_entry_point_as_determined_by_the_out_file_extension.c: -------------------------------------------------------------------------------- 1 | // compile -out test.dll 2 | 3 | __declspec(dllexport) int hello_world; 4 | -------------------------------------------------------------------------------- /tests/compile/trailling_comma_in_function_calls.c: -------------------------------------------------------------------------------- 1 | 2 | int function(int my_first_very_long_argument_name, int my_second_very_long_argument_name){ 3 | return my_first_very_long_argument_name + my_second_very_long_argument_name; 4 | } 5 | 6 | 7 | int main(){ 8 | int my_first_very_long_argument_name = 1; 9 | int my_second_very_long_argument_name = -1; 10 | 11 | int result = function( 12 | my_first_very_long_argument_name, 13 | my_second_very_long_argument_name, 14 | ); 15 | 16 | 17 | return result; 18 | } 19 | -------------------------------------------------------------------------------- /tests/compile/type_stack_grow.c: -------------------------------------------------------------------------------- 1 | enum { 2 | }main(){ 3 | } 4 | 5 | #define PTR1 * * * * * * * * * * 6 | #define PTR2 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 7 | #define PTR3 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 PTR2 8 | #define PTR4 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 PTR3 9 | #define PTR5 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 PTR4 10 | #define PTR6 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 PTR5 11 | 12 | int PTR4 q3_var = 0; 13 | -------------------------------------------------------------------------------- /tests/compile/typedef_to_struct_that_gets_filled_in_in_another_typedef.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | typedef struct unresolved def; 4 | typedef struct unresolved{ 5 | int a; 6 | } def; 7 | 8 | int main(){ 9 | def a = {0}; 10 | return a.a; 11 | } 12 | -------------------------------------------------------------------------------- /tests/compile/typedef_to_unresolved_pointer_type.c: -------------------------------------------------------------------------------- 1 | 2 | typedef unresolved type; 3 | 4 | typedef int unresolved; 5 | 6 | typedef int type; 7 | 8 | int main(){return 0;} 9 | -------------------------------------------------------------------------------- /tests/compile/uintmax_without_suffix_should_still_be_bigger_than_intmax.c: -------------------------------------------------------------------------------- 1 | 2 | _Static_assert(18446744073709551615 > 0x7FFFFFFF, "wat."); 3 | 4 | int main(){ 5 | 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/unary_plus_on_float_literal_should_still_be_constant.c: -------------------------------------------------------------------------------- 1 | 2 | int main(){ 3 | static float f = +133.f; 4 | return (int)f; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /tests/compile/unfilled_external_at_block_scope_when_compiling_to_object.c: -------------------------------------------------------------------------------- 1 | // compile /c 2 | 3 | int main(){ 4 | extern int arst; 5 | int function(int); 6 | return function(arst); 7 | } 8 | -------------------------------------------------------------------------------- /tests/compile/unnamed_parameters_in_function_definition.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | 3 | 4 | // Not specifying parameter names is permitted for unused parameters. 5 | int function(int, char*[]){ return 0; } 6 | 7 | int main(){ 8 | return function(0, 0); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compile/unreferenced_external_variable_of_undefined_struct_type.c: -------------------------------------------------------------------------------- 1 | 2 | extern struct arst arst; 3 | 4 | int main(){ 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /tests/compile/unreferenced_static_inline_references_external_undefined_globals_variable.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | // @note: This is supposed to compile, because 'return_arst' is not referenced, 4 | // which means 'arst' is not referenced, but thats not how our reference counts work. 5 | 6 | extern int arst[3]; 7 | 8 | static inline int return_arst(int a){ 9 | return arst[a]; 10 | } 11 | 12 | int main(){} 13 | -------------------------------------------------------------------------------- /tests/compile/unresolved_pointer_dereferance.c: -------------------------------------------------------------------------------- 1 | 2 | struct{ 3 | unresolved *a; 4 | struct unresolved_struct *s; 5 | }s; 6 | 7 | struct unresolved_struct{ 8 | char *asd; 9 | }; 10 | 11 | typedef int unresolved; 12 | 13 | int main(){ 14 | *s.a; 15 | s.a[0]; 16 | *(&s)->a; 17 | 18 | s.s->asd; 19 | s.s[0]; 20 | (*s.s).asd[0]; 21 | } 22 | -------------------------------------------------------------------------------- /tests/compile/unresolved_return_type.c: -------------------------------------------------------------------------------- 1 | 2 | struct asd unresolved_predeclaration(struct asd2); 3 | 4 | static struct string load_entire_file(char *file_path){ 5 | struct string ret = {}; 6 | return ret; 7 | } 8 | 9 | struct string{ 10 | char *data; 11 | __int64 size; 12 | }; 13 | 14 | int main(){ 15 | struct string string = load_entire_file("hello"); 16 | return (int)string.size; 17 | } 18 | -------------------------------------------------------------------------------- /tests/compile/unresolved_type_at_local_scope.c: -------------------------------------------------------------------------------- 1 | 2 | int main(){ 3 | 4 | struct unresolved *unresolved = 0; 5 | 6 | struct unresolved{ 7 | int a; 8 | } definition; 9 | 10 | unresolved = &definition; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tests/compile/unresolved_types_that_are_later_filled_in_should_work_at_global_scope.c: -------------------------------------------------------------------------------- 1 | 2 | extern struct unresolved a; 3 | 4 | struct unresolved{ 5 | int arst; 6 | }; 7 | 8 | int *b = &a.arst; 9 | 10 | struct unresolved a = {1}; 11 | 12 | 13 | extern struct unresolved2 c; 14 | 15 | int *d = &c.arst; 16 | 17 | struct unresolved2{ 18 | int arst; 19 | }; 20 | 21 | struct unresolved2 c = {1}; 22 | 23 | int main(){ 24 | a.arst; 25 | int *b = (void *)&a; 26 | return *b; 27 | } 28 | -------------------------------------------------------------------------------- /tests/compile/using_defined_outside_of_static_if.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | int defined(int a){ 4 | int defined = 1; 5 | return defined; 6 | } 7 | 8 | int main(){ 9 | return defined(0); 10 | } 11 | -------------------------------------------------------------------------------- /tests/compile/using_typedef_to_array_of_unknown_size_multiple_times.c: -------------------------------------------------------------------------------- 1 | 2 | typedef int array_of_unknown_size_t[]; 3 | 4 | array_of_unknown_size_t array_of_unknown_size3 = { 5 | 0, 1, 2, 3 6 | }; 7 | 8 | array_of_unknown_size_t array_of_unknown_size4 = { 9 | 0, 1, 2, 3, 4, 5, 6, 7, 10 | }; 11 | 12 | array_of_unknown_size_t list1 = {1, 2, 3}, list2 = {1, 2, 3, 4}; 13 | 14 | int main(){ 15 | array_of_unknown_size_t array_of_unknown_size1 = { 16 | 0, 1, 2, 3 17 | }; 18 | 19 | array_of_unknown_size_t array_of_unknown_size2 = { 20 | 0, 1, 2, 3, 4, 5, 6, 7, 21 | }; 22 | 23 | static array_of_unknown_size_t array_of_unknown_size5 = { 24 | 0, 1, 2, 3 25 | }; 26 | 27 | static array_of_unknown_size_t array_of_unknown_size6 = { 28 | 0, 1, 2, 3, 4, 5, 6, 7, 29 | }; 30 | 31 | array_of_unknown_size_t list3 = {1, 2, 3}, list4 = {1, 2, 3, 4}; 32 | static array_of_unknown_size_t list5 = {1, 2, 3}, list6 = {1, 2, 3, 4}; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /tests/compile/void_typed_ternary.c: -------------------------------------------------------------------------------- 1 | 2 | void function1(){} 3 | void function2(){} 4 | 5 | int main(){ 6 | 7 | int a = 1; 8 | int b = 0; 9 | 10 | a ? function1() : function2(); 11 | b ? function1() : function2(); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /tests/compile/warn_on_extern_declaration_into_inline_declaration.c: -------------------------------------------------------------------------------- 1 | // check "'function': Function declared 'inline' but not 'extern' is implicitly 'extern'" 2 | 3 | int function(); 4 | inline int function(){ 5 | return 1; 6 | } 7 | 8 | 9 | int main(){ 10 | return function(); 11 | } 12 | -------------------------------------------------------------------------------- /tests/compile/warn_on_redeclaring_a_function_to_be_static_after_there_was_already_an_external_declaration.c: -------------------------------------------------------------------------------- 1 | // check "'function': Redefining declaration from external to static." 2 | 3 | int function(); 4 | static int function(){ 5 | return 1; 6 | } 7 | 8 | 9 | int main(){ 10 | return function(); 11 | } 12 | -------------------------------------------------------------------------------- /tests/compile/weird_argument_in_function_declarator.c: -------------------------------------------------------------------------------- 1 | 2 | int i_have_a_bunch_of_werid_arguments( 3 | int arg1(void), 4 | int (void), 5 | int (), 6 | int arg4(int), 7 | int (int), 8 | 9 | int arg6[], 10 | int [], 11 | 12 | int arg8[1], 13 | int [1], 14 | 15 | int arg10[1][2][3], 16 | int [1][2][3], 17 | 18 | int (*arg12)(), 19 | int (*)(), 20 | 21 | int (*arg14)(int), 22 | int (*)(int), 23 | 24 | int (int subarg1, int subarg2), 25 | 26 | int (int()), 27 | 28 | int (*arg18())[4], 29 | int (*())[4], 30 | 31 | int (*arg20())[], 32 | int (*())[], 33 | 34 | 35 | int (*arg22[])(), 36 | int (*[])(), 37 | 38 | 39 | int (*arg24[20])(), 40 | int (*[20])(), 41 | 42 | int); 43 | 44 | 45 | int main(){ 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /tests/compile/windows_defines.c: -------------------------------------------------------------------------------- 1 | // check "'a': Local variable is never used." 2 | 3 | #include 4 | #include 5 | 6 | int main(){ 7 | 8 | #define print(a) printf(#a " %d\n", a) 9 | 10 | print(WINVER); 11 | print(_WIN32_WINNT); 12 | print(NTDDI_VERSION); 13 | 14 | // There used to be a problem where warnings would not show up, 15 | // after a system include header, because we report at most 100 warnings. 16 | // This is a regression for that. 17 | int a; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /tests/compile/zero_sized_struct.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | typedef struct {} zero_sized_typedef; 4 | 5 | 6 | #ifdef __HLC__ 7 | #define ZERO_SIZE_STRUCT struct{} 8 | #else 9 | #define ZERO_SIZE_STRUCT zero_sized_typedef 10 | #endif 11 | 12 | 13 | ZERO_SIZE_STRUCT zero_sized_global; 14 | 15 | struct { 16 | ZERO_SIZE_STRUCT zero_sized_field; 17 | } zero_sized_struct_with_member; 18 | 19 | ZERO_SIZE_STRUCT array_of_zero_sized_struct[1]; 20 | 21 | ZERO_SIZE_STRUCT function_that_takes_zero_sized_struct_and_returns_zero_sized_struct(ZERO_SIZE_STRUCT argument){ 22 | return argument; 23 | } 24 | 25 | 26 | int main(){ 27 | ZERO_SIZE_STRUCT zero_sized_local; 28 | 29 | // zero_sized assignment and type match 30 | zero_sized_global = zero_sized_local; 31 | 32 | zero_sized_local = zero_sized_struct_with_member.zero_sized_field; 33 | 34 | ZERO_SIZE_STRUCT *zero_sized_pointer; 35 | 36 | *zero_sized_pointer = zero_sized_local; 37 | 38 | zero_sized_pointer = &zero_sized_global; 39 | 40 | zero_sized_local = *zero_sized_pointer; 41 | 42 | zero_sized_local = function_that_takes_zero_sized_struct_and_returns_zero_sized_struct(zero_sized_local); 43 | 44 | zero_sized_local = array_of_zero_sized_struct[0]; 45 | 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /tests/error/__FUNCTION__outside_function.c: -------------------------------------------------------------------------------- 1 | // fail "__FUNCTION__ is only allowed inside a function." 2 | 3 | int a = __FUNCTION__; 4 | -------------------------------------------------------------------------------- /tests/error/another_static_if_fail_check_that_is_just_not_supposed_to_assert.c: -------------------------------------------------------------------------------- 1 | // fail "Expected ')' in '#if' argument." 2 | 3 | #if (1 4 | 5 | -------------------------------------------------------------------------------- /tests/error/array_of_unknown_size_in_sub_struct_with_members_after_it.c: -------------------------------------------------------------------------------- 1 | // fail "Array of unknown size has to be the last member of struct." 2 | 3 | struct s{ 4 | int a : 1; 5 | struct { int b[]; }; 6 | int c : 1; 7 | }; 8 | -------------------------------------------------------------------------------- /tests/error/assignment_of_array_of_unknown_size.c: -------------------------------------------------------------------------------- 1 | // fail "Array can only be initialized by {initializer-list} or "string literal"." 2 | 3 | int main(){ 4 | char ident_0[] = ident_0; 5 | } 6 | -------------------------------------------------------------------------------- /tests/error/backslash_at_the_end_of_the_file.c: -------------------------------------------------------------------------------- 1 | // fail 2 | #define M(x) \ -------------------------------------------------------------------------------- /tests/error/case_more_then_once.c: -------------------------------------------------------------------------------- 1 | // check "Case '1' already handled." 2 | // fail "... Here is the previous case." 3 | 4 | int _start(){ 5 | switch(1){ 6 | case 1: break; 7 | case 1: break; 8 | } 9 | return 1; 10 | } 11 | -------------------------------------------------------------------------------- /tests/error/cast_int_to_struct.c: -------------------------------------------------------------------------------- 1 | // fail "Cast of 'int' to 'struct s' is illegal." 2 | 3 | int main(){ 4 | int a; 5 | struct s {}; 6 | (struct s)a; 7 | } 8 | -------------------------------------------------------------------------------- /tests/error/cast_to_function_type.c: -------------------------------------------------------------------------------- 1 | // fail "Cast to function is illegal." 2 | 3 | void takes_a_function_pointer (void (*function_pointer) (void *)); 4 | void function (void *) { } 5 | 6 | int main (void){ 7 | takes_a_function_pointer ((void (void *)) (function)); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /tests/error/cast_to_unresolved_struct.c: -------------------------------------------------------------------------------- 1 | // fail "'unresovled': Undeclared struct." 2 | 3 | int main(){ 4 | return (struct unresovled){}.a; 5 | } -------------------------------------------------------------------------------- /tests/error/circular_dependency.c: -------------------------------------------------------------------------------- 1 | // check "'b': Part of the cycle." 2 | // fail "'a': Part of the cycle." 3 | 4 | struct a{ 5 | struct b b; 6 | }; 7 | 8 | struct b{ 9 | struct a a; 10 | }; 11 | -------------------------------------------------------------------------------- /tests/error/compile_time_div_or_mod_by_zero.c: -------------------------------------------------------------------------------- 1 | // check "(29,1): Error at '/': Integer division by 0." 2 | // check "(30,1): Error at '/': Integer division by 0." 3 | // check "(31,1): Error at '/': Integer division by 0." 4 | // check "(32,1): Error at '/': Integer division by 0." 5 | // check "(34,1): Error at '/': Integer division by 0." 6 | // check "(35,1): Error at '/': Integer division by 0." 7 | // check "(36,1): Error at '/': Integer division by 0." 8 | // check "(37,1): Error at '/': Integer division by 0." 9 | // check "(43,1): Error at '%': Integer modulation by 0." 10 | // check "(44,1): Error at '%': Integer modulation by 0." 11 | // check "(45,1): Error at '%': Integer modulation by 0." 12 | // check "(46,1): Error at '%': Integer modulation by 0." 13 | // check "(48,1): Error at '%': Integer modulation by 0." 14 | // check "(49,1): Error at '%': Integer modulation by 0." 15 | // check "(50,1): Error at '%': Integer modulation by 0." 16 | // check "(51,1): Error at '%': Integer modulation by 0." 17 | // fail 18 | 19 | typedef __int8 s8; 20 | typedef unsigned __int8 u8; 21 | typedef __int16 s16; 22 | typedef unsigned __int16 u16; 23 | typedef __int32 s32; 24 | typedef unsigned __int32 u32; 25 | typedef __int64 s64; 26 | typedef unsigned __int64 u64; 27 | 28 | #define test(type) type a_##type = ((type) 1)/((type)0) 29 | test(s8); 30 | test(s16); 31 | test(s32); 32 | test(s64); 33 | 34 | test(u8); 35 | test(u16); 36 | test(u32); 37 | test(u64); 38 | #undef test 39 | 40 | 41 | 42 | #define test(type) type b_##type = ((type) 1)%((type)0) 43 | test(s8); 44 | test(s16); 45 | test(s32); 46 | test(s64); 47 | 48 | test(u8); 49 | test(u16); 50 | test(u32); 51 | test(u64); 52 | #undef test -------------------------------------------------------------------------------- /tests/error/compound_assignment_for_bool_with_rhs_of_string_type.c: -------------------------------------------------------------------------------- 1 | // fail "has to be of integer type, but is of type 'char[15]'." 2 | 3 | void ident_10(void){ 4 | _Bool ident_5; 5 | ident_5 &= "xr0e2urr22i2iu"; 6 | } 7 | -------------------------------------------------------------------------------- /tests/error/declaration_of_unresolved_type.c: -------------------------------------------------------------------------------- 1 | // fail "'unresolved': [0] Undeclared identifier." 2 | 3 | struct unresolved; 4 | struct unresolved a; 5 | 6 | int main(){ 7 | 8 | } -------------------------------------------------------------------------------- /tests/error/deeply_nested_struct.c: -------------------------------------------------------------------------------- 1 | // fail "Type nests too deep." 2 | 3 | #define LIM1(x) x##0 {x##1 {x##2 {x##3 {x##4 {x##5 {x##6 {x##7 {x##8 {x##9 { 4 | #define LIM2(x) LIM1(x##0) LIM1(x##1) LIM1(x##2) LIM1(x##3) LIM1(x##4) \ 5 | LIM1(x##5) LIM1(x##6) LIM1(x##7) LIM1(x##8) LIM1(x##9) 6 | #define LIM3(x) LIM2(x##0) LIM2(x##1) LIM2(x##2) LIM2(x##3) LIM2(x##4) \ 7 | LIM2(x##5) LIM2(x##6) LIM2(x##7) LIM2(x##8) LIM2(x##9) 8 | #define LIM4(x) LIM3(x##0) LIM3(x##1) LIM3(x##2) LIM3(x##3) LIM3(x##4) \ 9 | LIM3(x##5) LIM3(x##6) LIM3(x##7) LIM3(x##8) LIM3(x##9) 10 | #define LIM5(x) LIM4(x##0) LIM4(x##1) LIM4(x##2) LIM4(x##3) LIM4(x##4) \ 11 | LIM4(x##5) LIM4(x##6) LIM4(x##7) LIM4(x##8) LIM4(x##9) 12 | #define LIM6(x) LIM5(x##0) LIM5(x##1) LIM5(x##2) LIM5(x##3) LIM5(x##4) \ 13 | LIM5(x##5) LIM5(x##6) LIM5(x##7) LIM5(x##8) LIM5(x##9) 14 | #define LIM7(x) LIM6(x##0) LIM6(x##1) LIM6(x##2) LIM6(x##3) LIM6(x##4) \ 15 | LIM6(x##5) LIM6(x##6) LIM6(x##7) LIM6(x##8) LIM6(x##9) 16 | 17 | #define RBR1 } x; } x; } x; } x; } x; } x; } x; } x; } x; } x; 18 | #define RBR2 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 RBR1 19 | #define RBR3 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 RBR2 20 | #define RBR4 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 RBR3 21 | #define RBR5 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 RBR4 22 | 23 | LIM4(struct s) 24 | int x; 25 | RBR4 26 | -------------------------------------------------------------------------------- /tests/error/defined_type_should_always_be_big_enough_for_value_incorrect_printlike_warning.c: -------------------------------------------------------------------------------- 1 | // reject "Warning" 2 | 3 | __declspec(printlike) int print(char *format, ...){ 4 | (void)format; 5 | return 0; 6 | } 7 | 8 | int main(){ 9 | 10 | __int64 arst = 0; 11 | print("%lld\n", arst + 1); // This used to warn because we had the wrong defined type. 12 | } 13 | -------------------------------------------------------------------------------- /tests/error/defining_local_unresolved_struct_in_subscope.c: -------------------------------------------------------------------------------- 1 | // fail "Undeclared struct." 2 | 3 | int main(){ 4 | 5 | struct asd *asd; 6 | { 7 | struct asd{int a;}; 8 | asd->a; 9 | } 10 | 11 | return 0; 12 | } 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/error/disabled_if_should_not_complain_about_junk.c: -------------------------------------------------------------------------------- 1 | // reject "Junk" 2 | 3 | #if defined(__clang__) || defined(__HLC__) 4 | #define zero_struct {} 5 | #elif defined(_MSC_VER) || defined(__GNUC__) 6 | #define zero_struct {0} 7 | #endif 8 | 9 | #if defined(__clang__) || defined(__GNUC__) 10 | #define zero_struct {} 11 | #elif defined(_MSC_VER) || defined(__HLC__) 12 | #define zero_struct {0} 13 | #endif 14 | 15 | int main(){ 16 | 17 | } 18 | -------------------------------------------------------------------------------- /tests/error/dllimport_and_dllexport_at_global_scope.c: -------------------------------------------------------------------------------- 1 | // check "Error at 'initialized_dllimport_function': Cannot define a function that is declared '__declspec(dllimport)'." 2 | // check "Error at 'initialized_dllimport_variable': Variable declared '__declspec(dllimport)' cannot be initialized." 3 | // check "Error at 'static_uninitialized_dllimport_variable': Variable declared '__declspec(dllimport)' cannot also be declared 'static'." 4 | // check "Error at 'static_uninitialized_dllexport_variable': Variable declared '__declspec(dllexport)' cannot also be declared 'static'." 5 | // reject "Error at 'initialized_dllexport_function'" 6 | // reject "Error at 'initialized_dllexport_variable'" 7 | // reject "Error at 'uninitialized_dllimport_variable'" 8 | // reject "Error at 'uninitialized_dllexport_variable'" 9 | // reject "Error at 'extern_uninitialized_dllimport_variable'" 10 | // reject "Error at 'extern_uninitialized_dllexport_variable'" 11 | // fail 12 | 13 | __declspec(dllimport) int initialized_dllimport_function() { return 1; } // Error: dllimport prohibited on definition 14 | __declspec(dllimport) int initialized_dllimport_variable = 3; // Error: dllimport prohibited on definition 15 | __declspec(dllexport) int initialized_dllexport_function() { return 1; } // Okay: export definition 16 | __declspec(dllexport) int initialized_dllexport_variable = 3; // Okay: export definition 17 | 18 | __declspec(dllimport) int uninitialized_dllimport_variable; // Okay: dllimport declaration 19 | __declspec(dllexport) int uninitialized_dllexport_variable; // Okay: export tentative definition 20 | 21 | static __declspec(dllimport) int static_uninitialized_dllimport_variable; // Error: cannot be static 22 | static __declspec(dllexport) int static_uninitialized_dllexport_variable; // Error: cannot be static 23 | 24 | extern __declspec(dllimport) int extern_uninitialized_dllimport_variable; // Okay: dllimport declaration 25 | extern __declspec(dllexport) int extern_uninitialized_dllexport_variable; // Okay: export declaration (NOT definition) 26 | 27 | -------------------------------------------------------------------------------- /tests/error/dllimport_and_dllexport_at_local_scope.c: -------------------------------------------------------------------------------- 1 | // check "Error at 'static_uninitialized_dllimport_variable': Variable declared '__declspec(dllimport)' cannot also be declared 'static'." 2 | // check "Error at 'static_uninitialized_dllexport_variable': Variable declared '__declspec(dllexport)' cannot also be declared 'static'." 3 | // check "Error at 'uninitialized_dllexport_variable': Cannot define a variable declared '__declspec(dllexport)' inside of a function. Did you forget to add 'extern'?" 4 | // check "Error at 'initialized_dllexport_variable': Cannot define a variable declared '__declspec(dllexport)' inside of a function. Did you forget to add 'extern'?" 5 | // reject "Error at 'uninitialized_dllimport_variable'" 6 | // reject "Error at 'extern_initialized_dllimport_variable'" 7 | // reject "Error at 'extern_initialized_dllexport_variable'" 8 | // fail 9 | // broken 10 | 11 | int main(){ 12 | static __declspec(dllimport) int static_uninitialized_dllimport_variable; // Error: cannot be static 13 | static __declspec(dllexport) int static_uninitialized_dllexport_variable; // Error: cannot be static 14 | 15 | __declspec(dllimport) int uninitialized_dllimport_variable; // Okay: dllimport declaration 16 | __declspec(dllexport) int uninitialized_dllexport_variable; // Error: external definition at local scope. 17 | 18 | extern __declspec(dllimport) int extern_initialized_dllimport_variable; // Okay: dllimport declaration 19 | extern __declspec(dllexport) int extern_initialized_dllexport_variable; // Okay: export declaration (NOT definition) 20 | 21 | __declspec(dllexport) int initialized_dllexport_variable = 1; // Error: external definition at local scope. 22 | } 23 | 24 | __declspec(dllexport) int extern_initialized_dllexport_variable; 25 | -------------------------------------------------------------------------------- /tests/error/dot_expression_should_not_set_lhs_expression_flag.c: -------------------------------------------------------------------------------- 1 | // fail "Operand of '++' must be an L-value." 2 | 3 | struct asd{ 4 | int value; 5 | }; 6 | 7 | struct asd function() { 8 | return (struct asd){1}; 9 | } 10 | 11 | int _start(){ 12 | function().value++; // should not compile 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /tests/error/double_default.c: -------------------------------------------------------------------------------- 1 | // check "More than one 'default'-case in switch." 2 | // fail "... Here was the previous 'default'-case." 3 | 4 | int _start(){ 5 | switch(1){ 6 | default: 7 | default:; 8 | } 9 | return 1; 10 | } 11 | -------------------------------------------------------------------------------- /tests/error/double_sleep.c: -------------------------------------------------------------------------------- 1 | // fail "Undeclared identifier." 2 | 3 | int sleeping_on_bar(bar *asd){ 4 | 5 | } 6 | 7 | int sleeping_on_bar(bar *asd){ 8 | 9 | } 10 | 11 | -------------------------------------------------------------------------------- /tests/error/elif_after_else.c: -------------------------------------------------------------------------------- 1 | // fail "'#elif' after '#else'." 2 | 3 | #if 1 4 | 5 | #else 6 | 7 | #elif 1 8 | 9 | #endif 10 | 11 | -------------------------------------------------------------------------------- /tests/error/endif_header.h: -------------------------------------------------------------------------------- 1 | #endif 2 | -------------------------------------------------------------------------------- /tests/error/error_in_expression_within_struct_initializer_resetting_should_exit_statement.c: -------------------------------------------------------------------------------- 1 | // fail 2 | float ident_0[0x2] = (float [2]){, __alignof !, }; 3 | 4 | -------------------------------------------------------------------------------- /tests/error/escaped_string_literals_should_increment_the_line_count.c: -------------------------------------------------------------------------------- 1 | // fail "escaped_string_literals_should_increment_the_line_count.c(11" 2 | 3 | char *arst = " arst \ 4 | arst \ 5 | arst \ 6 | arst \ 7 | arst \ 8 | arst \ 9 | "; 10 | 11 | #error arst 12 | -------------------------------------------------------------------------------- /tests/error/extern.c: -------------------------------------------------------------------------------- 1 | // fail "Expected a type." 2 | extern 3 | -------------------------------------------------------------------------------- /tests/error/extern_variable_was_never_filled_in.c: -------------------------------------------------------------------------------- 1 | // fail "External declaration was declared and referenced but never defined." 2 | 3 | extern int arst; 4 | 5 | int main(){ 6 | arst = 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/error/file_ends_in_macro_expansion.c: -------------------------------------------------------------------------------- 1 | // fail 2 | #define C 1 3 | 4 | foo (p) 5 | 6 | { 7 | p[0] = C; 8 | 9 | 10 | 11 | 12 | p[5] = C 13 | -------------------------------------------------------------------------------- /tests/error/flexible_array_member_initialization.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return -1 4 | 5 | struct contains_flexible_array_member{ 6 | int member; 7 | int flexible_array_member[]; 8 | } s1 = { 1, { 2, 3 } }; 9 | 10 | struct contains_flexible_array_member{ 11 | int member; 12 | int flexible_array_member[]; 13 | } s2 = { 1, 2, 3 }; 14 | 15 | struct contains_flexible_array_member2{ 16 | int member; 17 | int flexible_array_member[]; 18 | } s3 = { .flexible_array_member = { 2, 3 } }; 19 | 20 | 21 | struct contains_flexible_array_member2{ 22 | int member; 23 | int flexible_array_member[]; 24 | } s4 = { .flexible_array_member = 2, 3 }; 25 | 26 | int main(){ 27 | assert(s1.flexible_array_member[0] == 2 && s1.flexible_array_member[1] == 3); 28 | assert(s2.flexible_array_member[0] == 2 && s2.flexible_array_member[1] == 3); 29 | assert(s3.flexible_array_member[0] == 2 && s3.flexible_array_member[1] == 3); 30 | assert(s4.flexible_array_member[0] == 2 && s3.flexible_array_member[1] == 3); 31 | 32 | // @Incomplete: unions nested structures, etc. 33 | } 34 | 35 | -------------------------------------------------------------------------------- /tests/error/float_literals_suffixes_and_a_number_at_the_end.c: -------------------------------------------------------------------------------- 1 | // fail 2 | 3 | // this gets identified as a float because of the e in the thing, and then the num_member_2 is postfix for the lexer 4 | // the parser thinks there is no suffix. Parser code needs a lot of help anyway. 5 | float asd = 2674151357484275986enum_member_2; 6 | 7 | int main(){} 8 | 9 | -------------------------------------------------------------------------------- /tests/error/function_calls_are_not_lhs_expressions.c: -------------------------------------------------------------------------------- 1 | // fail "must be a lhs expression" 2 | 3 | #define atomic_load(type, value) (*&(type){} = value, (type)*((volatile type *)(&value))) 4 | 5 | __int64 returns_in_a_register(int lhs_expr){ 6 | return 0; 7 | }; 8 | 9 | int main(){ 10 | int lhs_expr = 0; 11 | 12 | atomic_load(__int64, returns_in_a_register(lhs_expr)); 13 | } 14 | -------------------------------------------------------------------------------- /tests/error/function_in_struct.c: -------------------------------------------------------------------------------- 1 | // fail "Cannot declare a function in a struct." 2 | 3 | struct { 4 | void func(void); 5 | }; 6 | -------------------------------------------------------------------------------- /tests/error/function_scope_array_size_overflow.c: -------------------------------------------------------------------------------- 1 | // fail "Array size cannot exceed 0x7fffffff." 2 | 3 | int main(){ 4 | long long ident_0[8670853695427003083]; 5 | } 6 | -------------------------------------------------------------------------------- /tests/error/function_type_compount_literal.c: -------------------------------------------------------------------------------- 1 | // fail "Cast to function is illegal." 2 | 3 | int main(){ 4 | 5 | (int()){main}; 6 | 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /tests/error/half_parenthesized_comma_expression_in_static_if.c: -------------------------------------------------------------------------------- 1 | // fail "Expected ')' in '#if' argument." 2 | 3 | // This used to crash! 4 | #if (1, 5 | 6 | -------------------------------------------------------------------------------- /tests/error/hash_before_non_argument.c: -------------------------------------------------------------------------------- 1 | // fail "Expected a formal argument after '#' in macro replacement list for 'FOO'." 2 | 3 | #define FOO(a) # < 2 4 | FOO(a) 5 | -------------------------------------------------------------------------------- /tests/error/hash_if.c: -------------------------------------------------------------------------------- 1 | // fail "Expected an argument after '#if'." 2 | #if 3 | -------------------------------------------------------------------------------- /tests/error/hashes1.c: -------------------------------------------------------------------------------- 1 | // fail "Expected a formal argument after '#' in macro replacement list for 'a'." 2 | #define a q # 3 | -------------------------------------------------------------------------------- /tests/error/hashes2.c: -------------------------------------------------------------------------------- 1 | // fail "'##' at the end of a macro replacement list is illegal." 2 | #define b q ## 3 | -------------------------------------------------------------------------------- /tests/error/hashes3.c: -------------------------------------------------------------------------------- 1 | // fail "Expected a formal argument after '#' in macro replacement list for 'a'." 2 | #define a # q 3 | -------------------------------------------------------------------------------- /tests/error/hashes4.c: -------------------------------------------------------------------------------- 1 | // fail "'##' at the beginning of a macro replacement list is illegal." 2 | #define b ## q 3 | -------------------------------------------------------------------------------- /tests/error/hashes5.c: -------------------------------------------------------------------------------- 1 | // fail "Expected a formal argument after '#' in macro replacement list for 'a'." 2 | #define a(d) q # 3 | -------------------------------------------------------------------------------- /tests/error/hashes6.c: -------------------------------------------------------------------------------- 1 | // fail "'##' at the end of a macro replacement list is illegal." 2 | #define b(d) q ## 3 | -------------------------------------------------------------------------------- /tests/error/hashes7.c: -------------------------------------------------------------------------------- 1 | // fail "Expected a formal argument after '#' in macro replacement list for 'a'." 2 | #define a(d) # q 3 | -------------------------------------------------------------------------------- /tests/error/hashes8.c: -------------------------------------------------------------------------------- 1 | // fail "'##' at the beginning of a macro replacement list is illegal." 2 | #define b(d) ## q 3 | -------------------------------------------------------------------------------- /tests/error/include_open_index.c: -------------------------------------------------------------------------------- 1 | // fail "Newline in system include path." 2 | #include < 3 | 4 | -------------------------------------------------------------------------------- /tests/error/including_endif_header.c: -------------------------------------------------------------------------------- 1 | // fail "'#endif' matches '#if' in different file." 2 | 3 | #if 1 4 | #include "endif_header.h" 5 | -------------------------------------------------------------------------------- /tests/error/initializing_array_of_empty_struct.c: -------------------------------------------------------------------------------- 1 | // fail "Initializing empty structure or union requires explicit '{}'." 2 | 3 | struct empty_struct {}; 4 | 5 | struct empty_struct array_of_empty_struct[1] = { 1 }; 6 | -------------------------------------------------------------------------------- /tests/error/initializing_empty_struct.c: -------------------------------------------------------------------------------- 1 | // fail "Cannot initialize an empty structure with non-empty initializer-list." 2 | struct {} x = { 10 }; 3 | -------------------------------------------------------------------------------- /tests/error/initializing_nested_compound_using_designator_has_to_increment_member_index_by_more_than_one.c: -------------------------------------------------------------------------------- 1 | // fail "Too many initializers for structure 's'." 2 | 3 | struct s{ 4 | union u{ 5 | int arst; 6 | int arst2; 7 | }; 8 | }; 9 | 10 | int main(){ 11 | struct s u = {.arst = 1, 2}; 12 | } 13 | -------------------------------------------------------------------------------- /tests/error/inline_data_declaration.c: -------------------------------------------------------------------------------- 1 | // fail "Data declaration cannot be marked 'inline'." 2 | 3 | inline int i; 4 | 5 | int main(){ 6 | 7 | } 8 | -------------------------------------------------------------------------------- /tests/error/integer_promotion_and_bool.c: -------------------------------------------------------------------------------- 1 | // fail 2 | _Bool ident_0 = ident_0 == (unsigned __int64 )'0' * ident_0; 3 | 4 | -------------------------------------------------------------------------------- /tests/error/invalid_array_and_function_declarators.c: -------------------------------------------------------------------------------- 1 | // check "(6,29): Error at '(': Function returning array is illegal." 2 | // check "(7,32): Error at '(': Function returning function is illegal." 3 | // check "(8,23): Error at '[': Array of functions is illegal" 4 | // fail "(9,35): Error at '[': Only the most outer array can be of unknown size." 5 | 6 | int function_returning_array()[3]{} 7 | int function_returning_function()(){} 8 | int array_of_functions[3]() = {}; 9 | int array_of_array_of_unknown_size[3][]; 10 | -------------------------------------------------------------------------------- /tests/error/invalid_declarator_of_pointer_type.c: -------------------------------------------------------------------------------- 1 | // fail 2 | unresolved (*3rr0r); 3 | -------------------------------------------------------------------------------- /tests/error/label_redefinition.c: -------------------------------------------------------------------------------- 1 | // fail "Redefinition of label 'a'." 2 | 3 | 4 | int main(){ 5 | a: 6 | a: 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /tests/error/link_to_non_existant_library.c: -------------------------------------------------------------------------------- 1 | // compile -L this_is_a_non-existant_library.lib 2 | // fail "Error: Could not find specified library 'this_is_a_non-existant_library.lib'" 3 | 4 | int main(){ 5 | 6 | } 7 | -------------------------------------------------------------------------------- /tests/error/local_extern_declaration_with_wrong_type_should_error.c: -------------------------------------------------------------------------------- 1 | // fail "'extern' declaration inside function has different type from original" 2 | 3 | int main(){ 4 | extern int declaration_at_global_scope; 5 | declaration_at_global_scope = 1; 6 | } 7 | 8 | float declaration_at_global_scope; 9 | -------------------------------------------------------------------------------- /tests/error/macro_expansion_in_include_directive_eats_the_rest_of_the_file_then_errors.c: -------------------------------------------------------------------------------- 1 | // fail "Expected a ')' while collecting arguments for macro expansion." 2 | 3 | // This does not matter only has to be here. 4 | #define M1(A1, A2, A3, A4) 5 | 6 | // This collects all of its "arguments" until the end of the file. Then reports an error. 7 | #define M2(N) M1(L, N, R, 8 | 9 | // This pushes a postponed directive, but is then never resolves, as the M2 eat the entire file. 10 | #include M2(d) 11 | 12 | -------------------------------------------------------------------------------- /tests/error/main_sleeping_on_itself.c: -------------------------------------------------------------------------------- 1 | // fail "Expected a type, got a declaration." 2 | 3 | 4 | int 5 | main () 6 | { 7 | 8 | } 9 | 10 | main () 11 | { 12 | } 13 | 14 | -------------------------------------------------------------------------------- /tests/error/main_without_ending_closed_curly.c: -------------------------------------------------------------------------------- 1 | // fail "Unmatched '{' at global scope." 2 | char main(){ 3 | -------------------------------------------------------------------------------- /tests/error/member_is_not_in_struct_within_struct_literal.c: -------------------------------------------------------------------------------- 1 | // fail "Error at 'member_that_is_not_contained_in_S': Identifier is not a member of structure." 2 | 3 | struct S { struct S *next; int x; }; 4 | 5 | struct S v = (struct S) { .member_that_is_not_contained_in_S = 42 }; 6 | -------------------------------------------------------------------------------- /tests/error/member_redefinition.c: -------------------------------------------------------------------------------- 1 | // fail "Error at 'member': Redeclaration of member 'member'." 2 | 3 | struct asd{ 4 | int member; 5 | int member; 6 | }; 7 | -------------------------------------------------------------------------------- /tests/error/mod_by_zero_in_static_if.c: -------------------------------------------------------------------------------- 1 | // fail "Mod with zero." 2 | 3 | 4 | // This used to crash. 5 | #if 1 % UNDEFINED 6 | 7 | -------------------------------------------------------------------------------- /tests/error/never_filled_in_extern_variable_in_block_scope_should_avoid_undeclared_identifiers.c: -------------------------------------------------------------------------------- 1 | // reject "Undeclared identifier." 2 | // fail "'extern' variable was never defined." 3 | 4 | int main(){ 5 | extern int undefined; 6 | undefined = 1; 7 | } 8 | -------------------------------------------------------------------------------- /tests/error/non_constant_array_length_inside_structure_at_global_scope.c: -------------------------------------------------------------------------------- 1 | // fail "Array subscript is not constant." 2 | 3 | int a; 4 | struct{ 5 | int arr[a]; 6 | }; 7 | 8 | int main(){ 9 | 10 | } 11 | -------------------------------------------------------------------------------- /tests/error/non_defined_entry_point.c: -------------------------------------------------------------------------------- 1 | // compile -entry main 2 | // fail "Entry point has to be defined." 3 | 4 | void main(); 5 | -------------------------------------------------------------------------------- /tests/error/not_a_type_error_in_generic.c: -------------------------------------------------------------------------------- 1 | // fail "Error at 'arst': Expected a type-name or 'default' while parsing a _Generic association list." 2 | 3 | int main(){ 4 | int a; 5 | _Generic(a, arst: 123 ); // This used to infinitely loop. 6 | } 7 | -------------------------------------------------------------------------------- /tests/error/pointer_arithmetic_on_function_type.c: -------------------------------------------------------------------------------- 1 | // fail "Cannot use pointer arithmetic on function-pointer." 2 | 3 | extern int bar(void); 4 | 5 | int foo(void){ 6 | return (&bar + 4096) (); 7 | } 8 | -------------------------------------------------------------------------------- /tests/error/pointer_deref_to_incomplete_array.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | unsigned char incomplete_array[]; 4 | 5 | int main(){ 6 | unsigned char (*asd)[] = &incomplete_array; 7 | 8 | incomplete_array[0]; 9 | incomplete_array + 1; 10 | *incomplete_array; 11 | // sizeof(incomplete_array); - error: invalid application of 'sizeof' to an incomplete type 'unsigned char []' 12 | 13 | // asd[0]; - error: subscript of pointer to incomplete type 'unsigned char []' 14 | // asd + 1; - error: arithmetic on a pointer to an incomplete type 'unsigned char []' 15 | *asd; 16 | **asd; 17 | 18 | // unsigned char *deref = *asd; // this is fine apperantly. 19 | // 20 | // return **asd; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /tests/error/redeclaration_of_structure_one_with_pointer_to_int_one_with_pointer_to_void.c: -------------------------------------------------------------------------------- 1 | // fail "Redeclaration of type." 2 | 3 | struct structure{ 4 | void *a; 5 | }; 6 | 7 | struct structure{ 8 | int *a; 9 | }; 10 | 11 | 12 | int main(){ 13 | 14 | } 15 | -------------------------------------------------------------------------------- /tests/error/redeclaring_enum_value.c: -------------------------------------------------------------------------------- 1 | // check "Redeclaration of enum value as '2'." 2 | // fail "the previous declaration of value '1'." 3 | 4 | enum arst{ 5 | ARST = 1, 6 | ARST = 2, 7 | }; 8 | 9 | int main(){ 10 | 11 | } 12 | -------------------------------------------------------------------------------- /tests/error/redeclaring_variable_as_typedef.c: -------------------------------------------------------------------------------- 1 | // fail "Redeclaration of different kind." 2 | 3 | int a; 4 | typedef int a; 5 | 6 | int main(){ 7 | 8 | } 9 | -------------------------------------------------------------------------------- /tests/error/redefining_defined.c: -------------------------------------------------------------------------------- 1 | // fail "Cannot use 'defined' as a macro name." 2 | 3 | #define defined 9 4 | 5 | -------------------------------------------------------------------------------- /tests/error/rogue_semicolon.c: -------------------------------------------------------------------------------- 1 | // fail 2 | void (*_start)(struct *unresolved p;); 3 | -------------------------------------------------------------------------------- /tests/error/should_report_undeclared_identifiers_in_structures.c: -------------------------------------------------------------------------------- 1 | // fail "Error at 'type'" 2 | 3 | // This should fail because 'type' is undeclared, but currently fails because 'structure' is undeclared. 4 | // This is now fixed, so here is a regression test :) 5 | 6 | struct structure{ type a; }; 7 | struct structure arst; 8 | 9 | int main(){} 10 | 11 | -------------------------------------------------------------------------------- /tests/error/sleeping_on_ident_after_struct_has_been_defined.c: -------------------------------------------------------------------------------- 1 | // fail "(8,1): Error at 'foo': [0] Undeclared identifier." 2 | 3 | struct foo 4 | { 5 | int a, b, c; 6 | }; 7 | 8 | foo; 9 | 10 | -------------------------------------------------------------------------------- /tests/error/static_else_last_thing_in_the_file.c: -------------------------------------------------------------------------------- 1 | // fail "'#else' without matching '#endif'." 2 | #if 0 3 | 4 | #else 5 | -------------------------------------------------------------------------------- /tests/error/static_if_last_thing_in_the_file.c: -------------------------------------------------------------------------------- 1 | // fail "'#if' without matching '#endif'." 2 | #if 1 3 | -------------------------------------------------------------------------------- /tests/error/struct_self_inclusion.c: -------------------------------------------------------------------------------- 1 | // check "'a': [0] Undeclared identifier." 2 | // fail "'b': [0] Undeclared identifier." 3 | 4 | struct a{ 5 | struct a a; 6 | }; 7 | 8 | 9 | struct b{ 10 | struct b; 11 | }; 12 | -------------------------------------------------------------------------------- /tests/error/typedef_and_anonymous_use.c: -------------------------------------------------------------------------------- 1 | // fail "Undeclared identifier." 2 | 3 | typedef struct b{ 4 | struct{ 5 | struct unresolved a; 6 | }; 7 | } b; 8 | -------------------------------------------------------------------------------- /tests/error/typedef_to_array_of_unknown_size_should_not_get_overwritten_by_sized_typedef.c: -------------------------------------------------------------------------------- 1 | // broken 2 | // fail 3 | 4 | typedef int int_array[]; 5 | typedef int int_array[3]; 6 | 7 | int main(){ 8 | 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/error/typedef_to_itself.c: -------------------------------------------------------------------------------- 1 | // fail "'type_0': [0] Undeclared identifier." 2 | typedef type_0 type_0; 3 | 4 | int main(){ 5 | type_0 a; 6 | } 7 | -------------------------------------------------------------------------------- /tests/error/u64_values_in_static_if.c: -------------------------------------------------------------------------------- 1 | // fail "This should error" 2 | 3 | #if 18446744073709551615 > 123 4 | #error This should error 5 | #endif 6 | 7 | int main(){ 8 | 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/error/unary_plus_on_pointers.c: -------------------------------------------------------------------------------- 1 | // fail "Error at '+': Operand of unary '+' has to be of integer or floating point type" 2 | 3 | int main(){ 4 | char *arst; 5 | +arst; 6 | } 7 | -------------------------------------------------------------------------------- /tests/error/unbounded_static_if_recursion.c: -------------------------------------------------------------------------------- 1 | // fail "Unexpected end to '#if'." 2 | 3 | #if ( 4 | d 5 | -------------------------------------------------------------------------------- /tests/error/unended_cast_to_function.c: -------------------------------------------------------------------------------- 1 | // fail "Expected a type." 2 | 3 | int main(){ 4 | return (float( 5 | } 6 | 7 | -------------------------------------------------------------------------------- /tests/error/unnamed_int_declaration_in_structure.c: -------------------------------------------------------------------------------- 1 | // fail "Declaration does not declare anything." 2 | 3 | struct contains_unnamed_int { int; }; 4 | 5 | int main(){} 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/error/unresolved_anonymous_union.c: -------------------------------------------------------------------------------- 1 | // fail "Undeclared identifier." 2 | 3 | struct{ 4 | union{ 5 | struct unresolved a; 6 | }; 7 | } asd; 8 | -------------------------------------------------------------------------------- /tests/error/unresolved_array.c: -------------------------------------------------------------------------------- 1 | // fail "Undeclared identifier." 2 | 3 | struct unresolved a[4]; 4 | 5 | int main(){ 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/error/unresolved_array_in_struct.c: -------------------------------------------------------------------------------- 1 | // fail "Undeclared identifier." 2 | 3 | struct{ 4 | struct unresolved a[4]; 5 | }; 6 | -------------------------------------------------------------------------------- /tests/error/unresolved_struct_inclusion.c: -------------------------------------------------------------------------------- 1 | // fail "'unresolved': [0] Undeclared identifier." 2 | 3 | struct { unresolved; } 4 | -------------------------------------------------------------------------------- /tests/error/unresolved_type_in_struct_in_function_declaration.c: -------------------------------------------------------------------------------- 1 | // fail "Undeclared identifier." 2 | int (*a)(struct{struct unresolved a}); 3 | -------------------------------------------------------------------------------- /tests/error/using_expression_of_type_void_as_an_argument_to_varargs_function.c: -------------------------------------------------------------------------------- 1 | // fail "Expression of type void cannot be used as function argument." 2 | 3 | void varargs(int count, ...){ 4 | 5 | } 6 | 7 | int main(){ 8 | varargs(1, (void)1); 9 | } 10 | -------------------------------------------------------------------------------- /tests/error/using_wrong_tag_to_access_compound.c: -------------------------------------------------------------------------------- 1 | // check "Got 'struct i_am_an_enum', but 'i_am_an_enum' is an enum." 2 | // check "Got 'union i_am_an_enum', but 'i_am_an_enum' is an enum." 3 | // check "Got 'enum i_am_a_struct' but 'i_am_a_struct' is a struct." 4 | // check "Got 'union i_am_a_struct', but 'i_am_a_struct' is a struct." 5 | // check "Got 'enum i_am_a_union' but 'i_am_a_union' is a union." 6 | // check "Got 'struct i_am_a_union', but 'i_am_a_union' is a union." 7 | // fail 8 | 9 | enum i_am_an_enum{ 10 | enum_member, 11 | }; 12 | 13 | struct i_am_a_struct{ 14 | int struct_member; 15 | }; 16 | 17 | union i_am_a_union{ 18 | int union_member; 19 | }; 20 | 21 | struct i_am_an_enum se; 22 | union i_am_an_enum ue; 23 | enum i_am_a_struct es; 24 | union i_am_a_struct us; 25 | enum i_am_a_union eu; 26 | struct i_am_a_union su; 27 | -------------------------------------------------------------------------------- /tests/error/va_start_errors.c: -------------------------------------------------------------------------------- 1 | // check "(15,5): Error at '__va_start': Second argument to intrinsic function '__va_start' must be the last named argument of the varargs function." 2 | // check "(17,5): Error at '__va_start': Call to intrinsic function '__va_start' must have exactly two arguments." 3 | // fail "(22,5): Error at '__va_start': Intrinsic function '__va_start' can only used in a varargs function." 4 | // broken 5 | 6 | #include 7 | 8 | // @cleanup: I cannot test this in this file, because we won't parse functions if there are 9 | // errors in the global variables. 10 | // 11 | // int xxx = __va_start(0, 1); // "Intrinsic function '__va_start' can only used in a varargs function." 12 | 13 | int varargs(int asd, ...){ 14 | va_list va; 15 | __va_start(va, 1); // "Second argument to intrinsic function '__va_start' must be the last named argument of the varargs function." 16 | 17 | __va_start(1, asd, 1, 2, 3); // "Call to intrinsic function '__va_start' must have exactly two arguments." 18 | } 19 | 20 | int non_varargs(int asd){ 21 | va_list va; 22 | __va_start(va, asd); // "Intrinsic function '__va_start' can only used in a varargs function." 23 | } 24 | 25 | int main(){ 26 | varargs(1); 27 | non_varargs(1); 28 | } 29 | -------------------------------------------------------------------------------- /tests/error/very_large_bitfield.c: -------------------------------------------------------------------------------- 1 | // fail "Bitfield width for type ' 'unsigned char'' must be '<= 8', but is '6353347876179427265'." 2 | struct { 3 | unsigned char ident_0 : 6353347876179427265; 4 | }; -------------------------------------------------------------------------------- /tests/error/very_negative_bitfield.c: -------------------------------------------------------------------------------- 1 | // fail "Bitfield width must be non-negative." 2 | 3 | typedef struct struct_0 { 4 | long long ident_0 : -6598051613625061302; 5 | }type_0; 6 | 7 | -------------------------------------------------------------------------------- /tests/error/void_declaration.c: -------------------------------------------------------------------------------- 1 | // fail "Cannot declare a variable of type void." 2 | 3 | void ident_0; 4 | 5 | 6 | -------------------------------------------------------------------------------- /tests/error/void_pointer_arithmetic.c: -------------------------------------------------------------------------------- 1 | // check "(9,18): Error at '+': Cannot use pointer arithmetic on pointer to 'void'." 2 | // check "(10,18): Error at '+=': Cannot use pointer arithmetic on pointer to 'void'." 3 | // check "(16,23): Error at '+': Cannot use pointer arithmetic on function-pointer." 4 | // check "(17,23): Error at '+=': Cannot use pointer arithmetic on function-pointer." 5 | // fail 6 | 7 | void *asd = 0; 8 | 9 | void *asd2 = asd + 3; 10 | void *asd3 = asd += 3; 11 | 12 | void func(){} 13 | 14 | void (*func_ptr)(void) = func; 15 | 16 | void *asd4 = func_ptr + 1; 17 | void *asd5 = func_ptr += 1; 18 | -------------------------------------------------------------------------------- /tests/error/void_semi_in_struct.c: -------------------------------------------------------------------------------- 1 | // fail "Cannot declare a struct member with type void." 2 | union { 3 | void; 4 | }; 5 | -------------------------------------------------------------------------------- /tests/error/void_type_in_struct.c: -------------------------------------------------------------------------------- 1 | // fail "Cannot declare a struct member with type void." 2 | 3 | struct{ 4 | void asd; 5 | }; 6 | -------------------------------------------------------------------------------- /tests/error/we_should_not_be_able_to_index_a_pointer_to_an_unresolved_struct.c: -------------------------------------------------------------------------------- 1 | // fail "'unresolved': Undeclared struct." 2 | 3 | static void function(struct unresolved *unresolved){ 4 | unresolved[1]; 5 | } 6 | 7 | // struct unresolved{ int member; }; 8 | 9 | int main(){ 10 | 11 | } 12 | -------------------------------------------------------------------------------- /tests/linkage/array_initializer_is_in_different_file/header.h: -------------------------------------------------------------------------------- 1 | 2 | typedef struct structure{ 3 | char *name; 4 | char *desc; 5 | int (*create)(void); 6 | } structure; 7 | 8 | extern structure my_structure; 9 | -------------------------------------------------------------------------------- /tests/linkage/array_initializer_is_in_different_file/main.c: -------------------------------------------------------------------------------- 1 | // compile other.c 2 | // run 3 | 4 | #include "header.h" 5 | 6 | static structure *structures[] = { 7 | &my_structure, 8 | 0 9 | }; 10 | 11 | 12 | int main(){ 13 | for(int i = 0; structures[i]; i++){ 14 | structures[i]->create(); 15 | } 16 | return 0; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /tests/linkage/array_initializer_is_in_different_file/other.c: -------------------------------------------------------------------------------- 1 | // skip 2 | 3 | #include "header.h" 4 | 5 | 6 | int create(void){ 7 | return 0; 8 | } 9 | 10 | structure my_structure = { 11 | .name = "my_structure", 12 | .desc = "It's my structure", 13 | .create = create, 14 | }; 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/linkage/arrays_of_unknown_size_filled_in_in_first/main.c: -------------------------------------------------------------------------------- 1 | // compile other.c 2 | 3 | extern char *names[]; 4 | 5 | char *names[] = { 6 | "otto", 7 | "karl", 8 | "betti", 9 | "charlotte", 10 | }; 11 | 12 | int main(){ 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /tests/linkage/arrays_of_unknown_size_filled_in_in_first/other.c: -------------------------------------------------------------------------------- 1 | // skip 2 | extern char *names[]; 3 | -------------------------------------------------------------------------------- /tests/linkage/crt_and_dll/arst: -------------------------------------------------------------------------------- 1 | arst 2 | 3 | -------------------------------------------------------------------------------- /tests/linkage/crt_and_dll/opens_a_file.c: -------------------------------------------------------------------------------- 1 | // compile /c /MDd 2 | // compile /c /MDd /LD reads_the_file.c 3 | // link reads_the_file.obj /DLL 4 | // link opens_a_file.obj reads_the_file.lib 5 | // run 6 | 7 | #include 8 | 9 | __declspec(dllimport) int arst(FILE *file); 10 | 11 | int main(){ 12 | FILE *file = fopen("arst", "rb"); 13 | return arst(file); 14 | } 15 | -------------------------------------------------------------------------------- /tests/linkage/crt_and_dll/reads_the_file.c: -------------------------------------------------------------------------------- 1 | // skip 2 | 3 | #include 4 | 5 | __declspec(dllexport) int arst(FILE *file){ 6 | char buffer[8]; 7 | return fread(buffer, 1, sizeof(buffer), file); 8 | } 9 | -------------------------------------------------------------------------------- /tests/linkage/dllexport_only_defined_in_one/header.h: -------------------------------------------------------------------------------- 1 | 2 | __declspec(dllexport) void my_exported_function(); -------------------------------------------------------------------------------- /tests/linkage/dllexport_only_defined_in_one/main.c: -------------------------------------------------------------------------------- 1 | // compile other.c 2 | #include "header.h" 3 | 4 | int main(){ 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /tests/linkage/dllexport_only_defined_in_one/other.c: -------------------------------------------------------------------------------- 1 | // skip 2 | #include "header.h" 3 | 4 | void my_exported_function(){ 5 | } -------------------------------------------------------------------------------- /tests/linkage/dllimport_and_dllexport/main.c: -------------------------------------------------------------------------------- 1 | // broken 2 | // compile -DTEST -L other.lib 3 | // run 4 | 5 | #define TEST1 0x5c823042 6 | #define TEST2 0x658195d9 7 | #define TEST3 0x3202fd59 8 | #define TEST4 0x51761348 9 | #define TEST5 0x2832f030 10 | #define TEST6 0x1696ef10 11 | 12 | #define assert(a) if(!(a)) return -1 13 | 14 | #ifdef TEST 15 | 16 | __declspec(dllexport) int variable_the_test_should_export = TEST1; 17 | __declspec(dllexport) int function_the_test_should_export(){ 18 | return TEST2; 19 | }; 20 | 21 | __declspec(dllimport) int variable_the_test_should_import_globally; 22 | __declspec(dllimport) int function_the_test_should_import_globally(); 23 | 24 | int main(){ 25 | __declspec(dllimport) int variable_the_test_should_import_locally; 26 | __declspec(dllimport) int function_the_test_should_import_locally(); 27 | 28 | assert(variable_the_test_should_import_globally == TEST3); 29 | assert(function_the_test_should_import_globally() == TEST4); 30 | assert(variable_the_test_should_import_locally == TEST5); 31 | assert(function_the_test_should_import_locally() == TEST6); 32 | } 33 | 34 | #elif 0 35 | 36 | __declspec(dllexport) int variable_the_test_should_export = TEST1; 37 | __declspec(dllexport) int function_the_test_should_export(){ 38 | return TEST2; 39 | }; 40 | 41 | #else 42 | 43 | // 44 | // This is the part, we don't compile when running the tests. 45 | // 46 | 47 | __declspec(dllimport) int variable_the_test_should_export; 48 | __declspec(dllimport) int function_the_test_should_export(); 49 | 50 | 51 | __declspec(dllexport) int variable_the_test_should_import_globally = TEST3; 52 | __declspec(dllexport) int function_the_test_should_import_globally(){ 53 | if(variable_the_test_should_export != TEST1) return 0; 54 | if(function_the_test_should_export() != TEST2) return 0; 55 | return TEST4; 56 | }; 57 | 58 | __declspec(dllexport) int variable_the_test_should_import_locally = TEST5; 59 | __declspec(dllexport) int function_the_test_should_import_locally(){ 60 | return TEST6; 61 | }; 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /tests/linkage/dllimport_and_dllexport/other.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalBeyer/Headerless-C-Compiler/a25e3b9858cd7c1d1fd731754ca78aa7b966d379/tests/linkage/dllimport_and_dllexport/other.dll -------------------------------------------------------------------------------- /tests/linkage/dllimport_and_dllexport/other.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PascalBeyer/Headerless-C-Compiler/a25e3b9858cd7c1d1fd731754ca78aa7b966d379/tests/linkage/dllimport_and_dllexport/other.lib -------------------------------------------------------------------------------- /tests/linkage/locally_extern_declared_variable/main.c: -------------------------------------------------------------------------------- 1 | // compile other.c 2 | // run 3 | 4 | int main(){ 5 | 6 | extern int ext; 7 | 8 | return ext; 9 | } 10 | -------------------------------------------------------------------------------- /tests/linkage/locally_extern_declared_variable/other.c: -------------------------------------------------------------------------------- 1 | // skip 2 | int ext; 3 | -------------------------------------------------------------------------------- /tests/linkage/predefined_inline_asm_function/main.c: -------------------------------------------------------------------------------- 1 | // compile other.c 2 | // run 3 | 4 | int my_nice_inline_asm_function(); 5 | 6 | int main(){ 7 | return my_nice_inline_asm_function(); 8 | } 9 | -------------------------------------------------------------------------------- /tests/linkage/predefined_inline_asm_function/other.c: -------------------------------------------------------------------------------- 1 | // skip 2 | 3 | __declspec(inline_asm) int my_nice_inline_asm_function(){ 4 | xor eax, eax 5 | return eax 6 | } 7 | -------------------------------------------------------------------------------- /tests/linkage/simple_static/main.c: -------------------------------------------------------------------------------- 1 | // compile other.c 2 | // run 3 | // check "static 1337" 4 | // check "other static 6969" 5 | // check "asd a" 6 | // check "other asd d" 7 | // check "a 1337" 8 | // check "a 6969" 9 | 10 | // if both do not initialize 'a' then its an unresolved external 11 | int a = 1337; 12 | 13 | static int _static = 1337; 14 | 15 | 16 | static int asd(){ 17 | return 0xa; 18 | } 19 | 20 | 21 | #include 22 | 23 | int main(){ 24 | 25 | printf("static %d\n", _static); 26 | printf("other static %d\n", return_my_static()); 27 | 28 | printf("asd %x\n", asd()); 29 | printf("other asd %x\n", return_my_asd()); 30 | 31 | printf("a %d\n", a); 32 | set_a(); 33 | printf("a %d\n", a); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /tests/linkage/simple_static/other.c: -------------------------------------------------------------------------------- 1 | // skip 2 | 3 | // if this is not explicitly 'extern' then there will be storage allocated. 4 | int a; 5 | 6 | static int _static = 6969; 7 | 8 | 9 | static int asd(){ 10 | return 0xd; 11 | } 12 | 13 | int return_my_static(){ 14 | return _static; 15 | } 16 | 17 | int return_my_asd(){ 18 | return asd(); 19 | } 20 | 21 | void set_a(){ 22 | a = 6969; 23 | } 24 | -------------------------------------------------------------------------------- /tests/linkage/sizeof_array_of_unknown_size_which_gets_filled_in_other_compilation_unit/main.c: -------------------------------------------------------------------------------- 1 | // compile other.c 2 | // run 3 | 4 | int array_of_unknown_size[]; 5 | 6 | int main(){ 7 | int sum = 0; 8 | for(int i = 0; i < sizeof(array_of_unknown_size)/sizeof(*array_of_unknown_size); i++){ 9 | sum += array_of_unknown_size[i]; 10 | } 11 | return !(sum == 55); 12 | } 13 | -------------------------------------------------------------------------------- /tests/linkage/sizeof_array_of_unknown_size_which_gets_filled_in_other_compilation_unit/other.c: -------------------------------------------------------------------------------- 1 | // skip 2 | 3 | int array_of_unknown_size[10] = { 4 | 1,2,3,4,5,6,7,8,9,10 5 | }; 6 | -------------------------------------------------------------------------------- /tests/linkage/static_function_pointer_array_that_references_external_function/main.c: -------------------------------------------------------------------------------- 1 | // compile other.c 2 | // run 3 | // check "hi!" 4 | // check "bye!" 5 | 6 | #include 7 | #include 8 | 9 | 10 | void bye(){ 11 | printf("bye!\n"); 12 | } 13 | 14 | 15 | void exec_pointers(); 16 | 17 | int main(){ 18 | exec_pointers(); 19 | return 0; 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/linkage/static_function_pointer_array_that_references_external_function/other.c: -------------------------------------------------------------------------------- 1 | // skip 2 | 3 | #include 4 | 5 | typedef void (*function_pointer)(void); 6 | 7 | void hi(){ 8 | printf("hi!\n"); 9 | } 10 | void bye(void); 11 | 12 | static function_pointer pointers[] = { 13 | hi, 14 | bye, 15 | }; 16 | 17 | void exec_pointers(){ 18 | for(int i = 0; i < sizeof(pointers)/sizeof(*pointers); i++){ 19 | (*(pointers[i]))(); 20 | } 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/linkage/struct_literals_should_not_have_the_open_curly_as_their_symbol.c: -------------------------------------------------------------------------------- 1 | // compile /c 2 | // link 3 | 4 | struct arst{ 5 | struct arst2{ 6 | int a; 7 | } *m, *m2; 8 | } arst = { 9 | .m = (struct arst2 []){1, 2, 3, 4}, // These symbols used to be called '{'. 10 | .m2 = (struct arst2 []){15, 2, 3, 4}, // These symbols used to be called '{'. 11 | }; 12 | 13 | int main(){ 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /tests/linkage/the_body_of_an_inline_extern_function_included_in_two_compilation_units_should_not_be_parsed_twice/file_one_which_includes_the_header.c: -------------------------------------------------------------------------------- 1 | // compile file_two_which_includes_the_header.c 2 | // reject "Warning" 3 | 4 | #include "header_with_an_inline_function_that_has_a_static_buffer.h" 5 | 6 | int main(){ 7 | return function(1) + other(); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /tests/linkage/the_body_of_an_inline_extern_function_included_in_two_compilation_units_should_not_be_parsed_twice/file_two_which_includes_the_header.c: -------------------------------------------------------------------------------- 1 | // skip 2 | 3 | #include "header_with_an_inline_function_that_has_a_static_buffer.h" 4 | 5 | int other(){ 6 | return function(2); 7 | } 8 | -------------------------------------------------------------------------------- /tests/linkage/the_body_of_an_inline_extern_function_included_in_two_compilation_units_should_not_be_parsed_twice/header_with_an_inline_function_that_has_a_static_buffer.h: -------------------------------------------------------------------------------- 1 | // skip 2 | 3 | extern inline int function(int a){ 4 | static char buffer[0x100]; 5 | return buffer[a]; 6 | } 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/linkage/type_index_for_undefined_struct_as_argument_for_function_pointer/main.c: -------------------------------------------------------------------------------- 1 | // compile other.c 2 | 3 | typedef void (*function)(struct s *s); 4 | 5 | typedef struct s{ 6 | function functions[13]; 7 | } struc; 8 | 9 | function f = (void *)0; 10 | 11 | int main(){ 12 | struct s s; 13 | f(&s); 14 | return 0; 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/linkage/type_index_for_undefined_struct_as_argument_for_function_pointer/other.c: -------------------------------------------------------------------------------- 1 | // skip -------------------------------------------------------------------------------- /tests/linkage/uninitialized_dllexport_variable_should_be_automatic.c: -------------------------------------------------------------------------------- 1 | // compile /c 2 | // link 3 | 4 | __declspec(dllexport) char *hello; 5 | 6 | int main(){ 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /tests/linkage/where_is_main/other.c: -------------------------------------------------------------------------------- 1 | // skip 2 | 3 | int main(){ 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /tests/run/alloca.c: -------------------------------------------------------------------------------- 1 | // run with a pile of arguments please 2 | 3 | #include 4 | #include 5 | 6 | struct big_return{ 7 | int a1, a2, a3, a4; 8 | int b1, b2, b3, b4; 9 | int c1, c2, c3, c4; 10 | int d1, d2, d3, d4; 11 | } function_with_a_pile_of_arguments( 12 | int a1, int a2, int a3, int a4, 13 | int b1, int b2, int b3, int b4, 14 | int c1, int c2, int c3, int c4, 15 | int d1, int d2, int d3, int d4 16 | ){ 17 | struct big_return ret = { 18 | a1, a2, a3, a4, 19 | b1, b2, b3, b4, 20 | c1, c2, c3, c4, 21 | d1, d2, d3, d4, 22 | }; 23 | return ret; 24 | } 25 | 26 | int main(int argc, char *argv[]){ 27 | 28 | char **pointers = alloca(argc * sizeof(*pointers)); 29 | 30 | for(int i = 0; i < argc; i++){ 31 | size_t length = strlen(argv[i]); 32 | pointers[i] = alloca(length + 1); 33 | memcpy(pointers[i], argv[i], length + 1); 34 | } 35 | 36 | struct big_return ret = function_with_a_pile_of_arguments( 37 | 1, 2, 3, 4, 38 | 1, 2, 3, 4, 39 | 1, 2, 3, 4, 40 | 1, 2, 3, 4, 41 | ); 42 | 43 | for(int i = 0; i < argc; i++){ 44 | size_t length = strlen(argv[i]); 45 | if(memcmp(pointers[i], argv[i], length + 1) != 0) return 1; 46 | } 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /tests/run/array_designator_next_current_object.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return -1 4 | 5 | int array[400] = { 6 | [300] = 1, 7 | 2, 8 | 3, 9 | [0] = 1337, 10 | 420, 11 | 12 | [399] = 0xdead, 13 | [15] = 0xbeef, 14 | 15 | }; 16 | 17 | int main(){ 18 | assert(array[300] == 1); 19 | assert(array[301] == 2); 20 | assert(array[302] == 3); 21 | assert(array[303] == 0); 22 | assert(array[0] == 1337); 23 | assert(array[1] == 420); 24 | assert(array[399] == 0xdead); 25 | assert(array[15] == 0xbeef); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /tests/run/array_of_unknown_size_compound_literal_current_object.c: -------------------------------------------------------------------------------- 1 | // run 2 | // check "array[0] = {1.000000, 2.000000}" 3 | // check "array[1] = {3.000000, 4.000000}" 4 | 5 | #include 6 | 7 | int main(){ 8 | 9 | struct v2{ 10 | float x, y; 11 | }; 12 | 13 | 14 | struct v2 *array = (struct v2 []){1.0f, 2.0f, 3.0f, 4.0f}; 15 | 16 | printf("array[0] = {%f, %f}\n" , array[0].x, array[0].y); 17 | printf("array[1] = {%f, %f}\n" , array[1].x, array[1].y); 18 | return 0; 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/run/array_of_unknown_size_is_never_filled_in.c: -------------------------------------------------------------------------------- 1 | // check "Bounds for array of unknown size were never filled in." 2 | // run 3 | 4 | 5 | // If a _tentative_ declaration is never filled in, it gets a zero-initializer. 6 | // This means in the end this is equivalent to 7 | // 8 | // int array_of_unknown_size[] = {0}; 9 | // 10 | // Hence, it should compile and run just fine. 11 | int array_of_unknown_size[]; 12 | 13 | int main(){ 14 | return array_of_unknown_size[0]; 15 | } 16 | -------------------------------------------------------------------------------- /tests/run/arrays_and_logical_and.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | int main(){ 4 | if("a" && "b"){ 5 | return 0; 6 | } 7 | return 1; 8 | } -------------------------------------------------------------------------------- /tests/run/arrays_of_unknown_size_initialized_by_string_literals.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | const char arr[] = { 4 | "Hello" ", " "World!\n" 5 | }; 6 | 7 | struct { 8 | char arr[]; 9 | } arst = { 10 | "Hello" ", " "World!\n" 11 | }; 12 | 13 | int main(){ 14 | const char arr3[] = { 15 | "Hello" ", " "World!\n" 16 | }; 17 | 18 | struct { 19 | char arr[]; 20 | } arst3 = { 21 | "Hello" ", " "World!\n" 22 | }; 23 | 24 | 25 | static const char arr2[] = { 26 | "Hello" ", " "World!\n" 27 | }; 28 | 29 | static struct { 30 | char arr[]; 31 | } arst2 = { 32 | "Hello" ", " "World!\n" 33 | }; 34 | 35 | return arr[0] + arr2[0] + arr3[0] - arst.arr[0] - arst2.arr[0] - arst3.arr[0]; 36 | } 37 | -------------------------------------------------------------------------------- /tests/run/assigning_to_a_function_pointer.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | int (*func)(void); 4 | 5 | int main(){ 6 | if(!*func){ 7 | (func = main)(); 8 | } 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /tests/run/big_return_type_and_first_float_argument.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | struct v2{ 4 | float x; 5 | float y; 6 | float z; 7 | float w; 8 | }; 9 | 10 | struct v2 inclusion(float a){ 11 | struct v2 ret = { a, a }; 12 | return ret; 13 | } 14 | 15 | int main(){ 16 | inclusion(1.0f); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /tests/run/bitfield_arguments_to_local_function.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return 1 4 | 5 | typedef unsigned __int16 uint16_t; 6 | 7 | int main(){ 8 | 9 | 10 | int asd(int a, int b, int c){ 11 | assert(a == 1237); 12 | assert(b == 3); 13 | assert(c == 5); 14 | return 0; 15 | } 16 | 17 | struct { 18 | uint16_t a : 13; 19 | uint16_t b : 3; 20 | uint16_t c; 21 | } bitfield = { 22 | 1237, 23 | 3, 24 | 5 25 | }; 26 | 27 | return asd(bitfield.a, bitfield.b, bitfield.c); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /tests/run/cast_to_float_in_initializer.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return -1 4 | 5 | float asd = (float)1337; 6 | 7 | int main(){ 8 | float asd2 = (float)1337; 9 | assert(asd == 1337); 10 | assert((int)asd == 1337); 11 | assert(asd == asd2); 12 | return 0; 13 | } -------------------------------------------------------------------------------- /tests/run/checking_predefines_from_the_commandline.c: -------------------------------------------------------------------------------- 1 | // compile "-Dassert(a)=if(!(a)) return 1;" -DNO_VALUE -DVALUE=1337 2 | // run 3 | 4 | int main(){ 5 | assert(NO_VALUE == 1); 6 | assert(VALUE == 1337); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /tests/run/comma_expression_that_end_in_a_function_should_still_evaluate_their_lhs.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | int a; 4 | 5 | int function(){ 6 | return a; 7 | } 8 | 9 | int main(){ 10 | return (a = 3, function)() - 3; 11 | } 12 | -------------------------------------------------------------------------------- /tests/run/comparing_double_to_float_literal.c: -------------------------------------------------------------------------------- 1 | // compile /c 2 | // link 3 | // run 4 | 5 | int main(){ 6 | float f = 123.0f; // float literal. 7 | double d = 123.0; // double literal. 8 | 9 | if(f != d){ 10 | return 1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/run/deref_call.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | typedef int (*xfn)( ); 4 | static int func (xfn fn) 5 | { 6 | return (*fn)(); 7 | } 8 | 9 | 10 | int main(){ 11 | 12 | 13 | static int int_func(){ 14 | return 1337; 15 | } 16 | return 1337 == func(int_func) - 1; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /tests/run/do_while_false.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | int main(){ 4 | int i = 1337; 5 | do{ 6 | i = 0; 7 | }while(0); 8 | return i; 9 | } -------------------------------------------------------------------------------- /tests/run/float_test.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return -1 4 | 5 | int main(){ 6 | float a = 1.0f; 7 | float b = 1.0f; 8 | float c1 = a + b; 9 | assert(c1 == 2); 10 | float c2 = a * b; 11 | assert(c2 == 1); 12 | float c3 = a - b; 13 | assert(c3 == 0); 14 | float c4 = a / b; 15 | assert(c4 == 1); 16 | a += 1; 17 | assert(a == 2); 18 | a *= 2; 19 | assert(a == 4); 20 | a -= 1; 21 | assert(a == 3); 22 | a /= 3; 23 | assert(a == 1); 24 | //assert(a++ == 1); 25 | //assert(++a == 3); 26 | //assert(a-- == 3); 27 | //assert(--a == 1); 28 | 29 | double e = 1.0; 30 | double f = 1.0; 31 | double g1 = e + f; 32 | assert(g1 == 2); 33 | double g2 = e * f; 34 | assert(g2 == 1); 35 | double g3 = e - f; 36 | assert(g3 == 0); 37 | double g4 = e / f; 38 | assert(g4 == 1); 39 | e += 1; 40 | assert(e == 2); 41 | e *= 2; 42 | assert(e == 4); 43 | e -= 1; 44 | assert(e == 3); 45 | e /= 3; 46 | assert(e == 1); 47 | 48 | if(a){ 49 | assert(a); 50 | } 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /tests/run/function_returns_a_function_ptr_returns_a_funtion_pointer.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | 4 | int function(void){ 5 | return 1337; 6 | } 7 | 8 | int (*(function_returning_a_function)(void))(void){ 9 | return function; 10 | } 11 | 12 | int (*(*(function_that_returns_a_function_which_returns_a_function)(void))(void))(void){ 13 | return function_returning_a_function; 14 | } 15 | 16 | int main(){ 17 | 18 | return function_that_returns_a_function_which_returns_a_function()()() == 1337 ? 0 : 1; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /tests/run/function_that_is_only_referenced_by_a_global_declaration.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | static int function_that_is_only_referanced_by_global_declaration(int a){ 4 | return a; 5 | } 6 | 7 | static int (*global_declaration)(int) = &function_that_is_only_referanced_by_global_declaration; 8 | 9 | int main(){ 10 | return global_declaration(0); 11 | } 12 | -------------------------------------------------------------------------------- /tests/run/handle_escaped_percent_correctly_in_printlike_function.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | __declspec(printlike) char *arst(char *format, ...){ 4 | return format; 5 | } 6 | 7 | int main(){ 8 | 9 | char *format = arst("%%"); 10 | 11 | if(format[0] != '%') return 1; 12 | if(format[1] != '%') return 1; 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /tests/run/hex_escape_sequences_and_character_literal_sizes.c: -------------------------------------------------------------------------------- 1 | // run 2 | // check "sizeof('\xff') = 4 (-1)" 3 | // check "sizeof('\xff\xff') = 4 (65535)" 4 | // check "sizeof('\xff\xff\xff\xff') = 4 (-1)" 5 | // check "sizeof(L'\xffff') = 2 (65535)" 6 | // check "sizeof(u'\xffff') = 2 (65535)" 7 | // check "4294967295" 8 | 9 | #include 10 | 11 | #define test(a) printf("sizeof(" #a ") = %d (%d)\n", sizeof(a), a); 12 | 13 | int main(){ 14 | test('\xff'); 15 | test('\xff\xff'); 16 | test('\xff\xff\xff\xff'); 17 | 18 | test(L'\xffff'); 19 | test(u'\xffff'); 20 | 21 | unsigned __int64 asd = U'\xffffffff'; 22 | printf("%llu\n", asd); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /tests/run/implicit_return_zero_for_main.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | int set_eax(){ 4 | return 1337; 5 | } 6 | 7 | int main(){ 8 | set_eax(); 9 | } 10 | -------------------------------------------------------------------------------- /tests/run/implicitly_dllimport_functions.c: -------------------------------------------------------------------------------- 1 | // compile 2 | // check "'GetStdHandle': Function is treated as dllimport, but was not declared '__declspec(dllimport)'." 3 | // check "'WriteFile': Function is treated as dllimport, but was not declared '__declspec(dllimport)'." 4 | // run 5 | // check "Hello, World!" 6 | 7 | void *GetStdHandle(int handle_num); 8 | int WriteFile(void *handle, void *buffer, int bytes_to_write, int *bytes_written, void *overlapped); 9 | 10 | int main(){ 11 | 12 | static char buffer[] = "Hello, World!"; 13 | 14 | void *handle = GetStdHandle(/*STD_OUTPUT_HANDLE*/-11); 15 | int bytes_written = 0; 16 | int success = WriteFile(handle, buffer, sizeof(buffer)-1, &bytes_written, 0); 17 | if(!success) return 1; 18 | if(bytes_written != sizeof(buffer)-1) return 1; 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /tests/run/inc_dec_Bool.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #include 4 | 5 | int main(){ 6 | char one = 1; 7 | char zero = 0; 8 | 9 | _Bool arst; 10 | arst++; // {0,1} + 1 is 1. 11 | if(memcmp(&arst, &one, 1) != 0) return 1; 12 | 13 | arst++; // {0,1} + 1 is 1. 14 | if(memcmp(&arst, &one, 1) != 0) return 1; 15 | 16 | arst--; // 1 - 1 is 0. 17 | if(memcmp(&arst, &zero, 1) != 0) return 1; 18 | 19 | arst--; // 0 - 1 is 0. 20 | if(memcmp(&arst, &one, 1) != 0) return 1; 21 | 22 | ++arst; 23 | if(memcmp(&arst, &one, 1) != 0) return 1; 24 | 25 | ++arst; 26 | if(memcmp(&arst, &one, 1) != 0) return 1; 27 | 28 | --arst; 29 | if(memcmp(&arst, &zero, 1) != 0) return 1; 30 | 31 | --arst; 32 | if(memcmp(&arst, &one, 1) != 0) return 1; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /tests/run/increment_and_decrement_on_an_empty_struct.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return 1; 4 | 5 | struct empty { 6 | }; 7 | 8 | int main() 9 | { 10 | struct empty *pointer_to_empty = &(struct empty){}; 11 | struct empty *initial = pointer_to_empty; 12 | pointer_to_empty++; 13 | assert(pointer_to_empty == initial); 14 | pointer_to_empty--; 15 | assert(pointer_to_empty == initial); 16 | ++pointer_to_empty; 17 | assert(pointer_to_empty == initial); 18 | --pointer_to_empty; 19 | assert(pointer_to_empty == initial); 20 | 21 | pointer_to_empty += 5; 22 | assert(pointer_to_empty == initial); 23 | pointer_to_empty -= 5; 24 | assert(pointer_to_empty == initial); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /tests/run/initialized_array_of_unions_containing_just_a_flexible_array_member.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return -1 4 | 5 | int main(){ 6 | 7 | union has_flexible_array_member{ 8 | int flexible_array[]; 9 | } array_of_flexible_array_members[10] = { 10 | 1, 2, 3 11 | }; 12 | 13 | assert(sizeof(array_of_flexible_array_members) == 0); 14 | assert(sizeof(array_of_flexible_array_members[0]) == 0); 15 | assert(array_of_flexible_array_members[0].flexible_array[0] == 1); 16 | assert(array_of_flexible_array_members[0].flexible_array[1] == 2); 17 | assert(array_of_flexible_array_members[0].flexible_array[2] == 3); 18 | } 19 | -------------------------------------------------------------------------------- /tests/run/initialized_flexible_array_members.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return -1 4 | 5 | struct has_flexible_array_member{ 6 | char array[]; 7 | }; 8 | 9 | int simple_flex_array(){ 10 | int prev = 1; 11 | struct has_flexible_array_member flex = { 12 | .array[0x1000] = 1, 13 | }; 14 | int post = 1; 15 | 16 | zero(flex.array, 0x1000); 17 | assert(prev == 1); 18 | assert(post == 1); 19 | return 0; 20 | } 21 | 22 | int flex_array_compound(){ 23 | int prev = 1; 24 | struct has_flexible_array_member *flex = &(struct has_flexible_array_member){ 25 | .array[0x1000] = 1, 26 | }; 27 | int post = 1; 28 | 29 | zero(flex->array, 0x1000); 30 | assert(prev == 1); 31 | assert(post == 1); 32 | return 0; 33 | } 34 | 35 | 36 | int static_simple_flex_array(){ 37 | static int prev = 1; 38 | static struct has_flexible_array_member flex = { 39 | .array[0x1000] = 1, 40 | }; 41 | static int post = 1; 42 | 43 | zero(flex.array, 0x1000); 44 | assert(prev == 1); 45 | assert(post == 1); 46 | return 0; 47 | } 48 | 49 | int static_flex_array_compound(){ 50 | static int prev = 1; 51 | static struct has_flexible_array_member *flex = &(struct has_flexible_array_member){ 52 | .array[0x1000] = 1, 53 | }; 54 | static int post = 1; 55 | 56 | zero(flex->array, 0x1000); 57 | assert(prev == 1); 58 | assert(post == 1); 59 | return 0; 60 | } 61 | 62 | 63 | int main(){ 64 | assert(simple_flex_array() == 0); 65 | assert(flex_array_compound() == 0); 66 | assert(static_simple_flex_array() == 0); 67 | assert(static_flex_array_compound() == 0); 68 | 69 | return 0; 70 | } 71 | 72 | 73 | void *zero(void *mem, unsigned __int64 amount){ 74 | char *it = mem; 75 | for(unsigned __int64 i = 0; i < amount; i++){ 76 | *it++ = 0; 77 | } 78 | return mem; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /tests/run/initializer_of_struct_which_contains_unnamed_member.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | struct arst{ 4 | struct { int a; }; 5 | int b; 6 | }; 7 | 8 | #define assert(a) if(!(a)) return 1; 9 | 10 | int main(){ 11 | 12 | struct arst arst = {1, 2}; 13 | 14 | assert(arst.a == 1); 15 | assert(arst.b == 2); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /tests/run/initializers_need_to_patch_outer_type_as_well.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | typedef unsigned char u8; 4 | struct contains_small_array {u8 a[3], b; }; 5 | struct contains_small_array array[] = { { 1 }, 2 }; 6 | 7 | struct contains_small_anon_struct { struct{u8 a[3];}; u8 b; }; 8 | struct contains_small_anon_struct array2[] = { { 1 }, 2 }; 9 | 10 | #define assert(a) if(!(a)) return 1; 11 | 12 | int main(){ 13 | 14 | assert(sizeof(array)/sizeof(*array) == 2); 15 | assert(array[0].a[0] == 1 && array[0].a[1] == 0 && array[0].a[2] == 0 && array[0].b == 0); 16 | assert(array[1].a[0] == 2 && array[1].a[1] == 0 && array[1].a[2] == 0 && array[1].b == 0); 17 | 18 | assert(sizeof(array2)/sizeof(*array2) == 2); 19 | assert(array2[0].a[0] == 1 && array2[0].a[1] == 0 && array2[0].a[2] == 0 && array2[0].b == 0); 20 | assert(array2[1].a[0] == 2 && array2[1].a[1] == 0 && array2[1].a[2] == 0 && array2[1].b == 0); 21 | 22 | struct contains_small_array l_array[] = { { 1 }, 2 }; 23 | struct contains_small_anon_struct l_array2[] = { { 1 }, 2 }; 24 | 25 | assert(sizeof(l_array)/sizeof(*l_array) == 2); 26 | assert(l_array[0].a[0] == 1 && l_array[0].a[1] == 0 && l_array[0].a[2] == 0 && l_array[0].b == 0); 27 | assert(l_array[1].a[0] == 2 && l_array[1].a[1] == 0 && l_array[1].a[2] == 0 && l_array[1].b == 0); 28 | 29 | assert(sizeof(l_array2)/sizeof(*l_array2) == 2); 30 | assert(l_array2[0].a[0] == 1 && l_array2[0].a[1] == 0 && l_array2[0].a[2] == 0 && l_array2[0].b == 0); 31 | assert(l_array2[1].a[0] == 2 && l_array2[1].a[1] == 0 && l_array2[1].a[2] == 0 && l_array2[1].b == 0); 32 | } 33 | -------------------------------------------------------------------------------- /tests/run/integer_promotion_for_unary_operators_on_integer_literals.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return -1 4 | 5 | int main(){ 6 | 7 | char c; 8 | unsigned char uc; 9 | 10 | assert(sizeof(c) == 1); 11 | assert(sizeof(++c) == 1); 12 | assert(sizeof(c++) == 1); 13 | assert(sizeof(--c) == 1); 14 | assert(sizeof(c--) == 1); 15 | 16 | assert(sizeof(uc) == 1); 17 | assert(sizeof(++uc) == 1); 18 | assert(sizeof(uc++) == 1); 19 | assert(sizeof(--uc) == 1); 20 | assert(sizeof(uc--) == 1); 21 | 22 | short s; 23 | unsigned short us; 24 | 25 | assert(sizeof(s) == 2); 26 | assert(sizeof(++s) == 2); 27 | assert(sizeof(s++) == 2); 28 | assert(sizeof(--s) == 2); 29 | assert(sizeof(s--) == 2); 30 | 31 | assert(sizeof(us) == 2); 32 | assert(sizeof(++us) == 2); 33 | assert(sizeof(us++) == 2); 34 | assert(sizeof(--us) == 2); 35 | assert(sizeof(us--) == 2); 36 | 37 | assert(sizeof(+c) == 4); 38 | assert(sizeof(+s) == 4); 39 | assert(sizeof(+uc) == 4); 40 | assert(sizeof(+us) == 4); 41 | 42 | assert(sizeof(-c) == 4); 43 | assert(sizeof(-s) == 4); 44 | assert(sizeof(-uc) == 4); 45 | assert(sizeof(-us) == 4); 46 | 47 | assert(sizeof(~c) == 4); 48 | assert(sizeof(~s) == 4); 49 | assert(sizeof(~uc) == 4); 50 | assert(sizeof(~us) == 4); 51 | 52 | assert(sizeof(!c) == 4); 53 | assert(sizeof(!s) == 4); 54 | assert(sizeof(!uc) == 4); 55 | assert(sizeof(!us) == 4); 56 | 57 | assert(!((void *)0) == 1); 58 | assert(!((void *)1) == 0); 59 | 60 | assert(sizeof(1i8) == 1); 61 | assert(sizeof(1ui8) == 1); 62 | 63 | assert(sizeof(1i16) == 2); 64 | assert(sizeof(1ui16) == 2); 65 | 66 | assert(sizeof(1i32) == 4); 67 | assert(sizeof(1ui32) == 4); 68 | 69 | assert(sizeof(1i64) == 8); 70 | assert(sizeof(1ui64) == 8); 71 | 72 | assert(sizeof(+1i8) == 4); 73 | assert(sizeof(+1ui8) == 4); 74 | assert(sizeof(+1i16) == 4); 75 | assert(sizeof(+1ui16) == 4); 76 | 77 | assert(sizeof(-1i8) == 4); 78 | assert(sizeof(-1ui8) == 4); 79 | assert(sizeof(-1i16) == 4); 80 | assert(sizeof(-1ui16) == 4); 81 | 82 | assert(sizeof(~1i8) == 4); 83 | assert(sizeof(~1ui8) == 4); 84 | assert(sizeof(~1i16) == 4); 85 | assert(sizeof(~1ui16) == 4); 86 | 87 | assert(sizeof(!1i8) == 4); 88 | assert(sizeof(!1ui8) == 4); 89 | assert(sizeof(!1i16) == 4); 90 | assert(sizeof(!1ui16) == 4); 91 | 92 | 93 | assert(!~0xffffffff); 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /tests/run/intrinsic_argument_to_varargs_procedure.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #define assert(a) (!(a) ? _exit(1) : (void)0) 8 | 9 | int varargs(char *format, ...){ 10 | va_list va; 11 | va_start(va, format); 12 | 13 | __m256i *value = va_arg(va, __m256i *); 14 | 15 | for(int i = 0; i < sizeof(value->m256i_i8); i++) assert(value->m256i_i8[i] == 'A'); 16 | 17 | va_end(va); 18 | return 0; 19 | } 20 | 21 | 22 | int main(){ 23 | 24 | __m256i d = _mm256_set1_epi8(0x41); 25 | 26 | varargs("%#?\n", d); 27 | 28 | return 0; 29 | } 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tests/run/intrinsic_function_argument.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #include 4 | 5 | #define assert(a) (!(a) ? __fastfail(1) : (void)0) 6 | 7 | int one(int a){ 8 | assert(a == 1); 9 | } 10 | 11 | static void assert_m128(__m128i m128){ 12 | one(1); 13 | _mm_extract_epi32(m128, 0); 14 | assert(_mm_extract_epi32(m128, 1) == 1); 15 | assert(_mm_extract_epi32(m128, 2) == 2); 16 | assert(_mm_extract_epi32(m128, 3) == 3); 17 | } 18 | 19 | 20 | int main(){ 21 | __m128i m128 = _mm_set_epi32(3, 2, 1, 0); 22 | assert(_mm_extract_epi32(m128, 0) == 0); 23 | assert(_mm_extract_epi32(m128, 1) == 1); 24 | assert(_mm_extract_epi32(m128, 2) == 2); 25 | assert(_mm_extract_epi32(m128, 3) == 3); 26 | 27 | assert_m128(m128); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /tests/run/intrinsic_test.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #include 4 | 5 | int main(){ 6 | __int8 s8 = -8; 7 | __int16 s16 = -16; 8 | __int32 s32 = -32; 9 | __int64 s64 = -64; 10 | 11 | unsigned __int8 u8 = 8; 12 | unsigned __int16 u16 = 16; 13 | unsigned __int32 u32 = 32; 14 | unsigned __int64 u64 = 64; 15 | 16 | void *ptr = &ptr; 17 | 18 | // __debugbreak(); 19 | __rdtsc(); 20 | 21 | __rdtscp(&u32); 22 | 23 | u8 = _addcarry_u8(u8, u8, u8, &u8); 24 | u8 = _addcarry_u16(u8, u16, u16, &u16); 25 | u8 = _addcarry_u32(u8, u32, u32, &u32); 26 | u8 = _addcarry_u64(u8, u64, u64, &u64); 27 | 28 | __addgsbyte(0, u8); 29 | __addgsword(0, u16); 30 | __addgsdword(0, u32); 31 | __addgsqword(0, u64); 32 | __incgsbyte(0); 33 | __incgsword(0); 34 | __incgsdword(0); 35 | __incgsqword(0); 36 | 37 | u8 = _BitScanForward(&u32, u32); 38 | u8 = _BitScanReverse(&u32, u32); 39 | u8 = _BitScanForward64(&u32, u64); 40 | u8 = _BitScanReverse64(&u32, u64); 41 | 42 | u8 = _bittest(&s32, s32); 43 | u8 = _bittest64(&s64, s64); 44 | 45 | u8 = _bittestandcomplement(&s32, s32 & 31); 46 | u8 = _bittestandcomplement64(&s64, s64 & 63); 47 | 48 | u8 = _bittestandreset(&s32, s32 & 31); 49 | u8 = _bittestandreset64(&s64, s64 & 63); 50 | 51 | u8 = _bittestandset(&s32, s32 & 31); 52 | u8 = _bittestandset64(&s64, s64 & 64); 53 | 54 | s8 = _InterlockedCompareExchange8(&s8, s8, s8); 55 | s16 = _InterlockedCompareExchange16(&s16, s16, s16); 56 | s32 = _InterlockedCompareExchange(&s32, s32, s32); 57 | s64 = _InterlockedCompareExchange64(&s64, s64, s64); 58 | 59 | __declspec(align(16)) __int64 array[2] = {0}; 60 | u8 = _InterlockedCompareExchange128(array, s64, s64, array); 61 | 62 | ptr = _InterlockedCompareExchangePointer(&ptr, ptr, ptr); 63 | 64 | s8 = _InterlockedExchangeAdd8(&s8, s8); 65 | s16 = _InterlockedExchangeAdd16(&s16, s16); 66 | s32 = _InterlockedExchangeAdd(&s32, s32); 67 | s64 = _InterlockedExchangeAdd64(&s64, s64); 68 | 69 | s8 = _InterlockedIncrement8(&s8); 70 | s16 = _InterlockedIncrement16(&s16); 71 | s32 = _InterlockedIncrement(&s32); 72 | s64 = _InterlockedIncrement64(&s64); 73 | 74 | s8 = _InterlockedDecrement8(&s8); 75 | s16 = _InterlockedDecrement16(&s16); 76 | s32 = _InterlockedDecrement(&s32); 77 | s64 = _InterlockedDecrement64(&s64); 78 | 79 | __stosb(&u8, 0x13, 1); 80 | __stosw(&u16, 0x1337, 1); 81 | __stosd(&u32, 0x13371337, 1); 82 | __stosq(&u64, 0x1337133713371337, 1); 83 | 84 | __movsb(&u8, (unsigned __int8 *)&s8, 1); 85 | __movsw(&u16, (unsigned __int16 *)&s16, 1); 86 | __movsd(&u32, (unsigned __int32 *)&s32, 1); 87 | __movsq(&u64, (unsigned __int64 *)&s64, 1); 88 | 89 | 90 | u16 = __popcnt16(u16); 91 | u32 = __popcnt(u32); 92 | u64 = __popcnt64(u64); 93 | 94 | _mm_pause(); 95 | 96 | _InterlockedExchange(&u32, u32); 97 | 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /tests/run/local_extern_compound.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | struct arst{ int a[3]; } arst = {1, 2, -3}; 4 | 5 | int main(){ 6 | extern struct arst arst; 7 | 8 | return arst.a[0] + arst.a[1] + arst.a[2]; 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/run/local_function_declaration_later_function_definition.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | int main(){ 4 | int asd(); 5 | return asd() == 1337 ? 0 : 1; 6 | } 7 | 8 | 9 | int asd(){ 10 | return 1337; 11 | } -------------------------------------------------------------------------------- /tests/run/lzcnt.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #include 4 | 5 | int main(){ 6 | unsigned short s = 0x100; 7 | unsigned int i = 0x10000; 8 | unsigned long long l = 0x100000000; 9 | 10 | s = __lzcnt16(s); 11 | if(s != 7) return 1; 12 | i = __lzcnt(i); 13 | if(i != 15) return 1; 14 | l = __lzcnt64(l); 15 | if(l != 31) return 1; 16 | 17 | return 0; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /tests/run/member_offset_in_initializer_of_array.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return 1; 4 | 5 | struct asd{ 6 | int member_one; 7 | int member_two; 8 | }; 9 | 10 | 11 | int offsets[] = { 12 | (int)(__int64)(&(((struct asd *)0)->member_one)), 13 | (int)(__int64)(&(((struct asd *)0)->member_two)), 14 | }; 15 | 16 | 17 | int main(){ 18 | 19 | assert(sizeof(offsets) == 8); 20 | assert(offsets[0] == 0); 21 | assert(offsets[1] == 4); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /tests/run/minus_one_pointer_literal.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | int main(){ 4 | 5 | __int64 pointer = (__int64)((void *)-1); 6 | 7 | if(pointer != -1) return 1; 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /tests/run/negative_subscript.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | int main(){ 4 | char *it = "@ ^@ @ @@ @^@ @ @ ^@@@ @@^@@@ @ ^@"; 5 | 6 | int count = 0; 7 | for(; *it; it++){ 8 | if(*it == '@' && it[-1] != '^'){ 9 | count++; 10 | } 11 | } 12 | 13 | return (count == 0xe) ? 0 : 1; 14 | } 15 | -------------------------------------------------------------------------------- /tests/run/oddly_sized_struct_types.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | void _exit(int status); 4 | #define assert(a) (!(a) ? _exit(1) : (void)0) 5 | 6 | struct seven{ 7 | char a[7]; 8 | }; 9 | 10 | struct six{ 11 | char a[6]; 12 | }; 13 | 14 | struct five{ 15 | char a[5]; 16 | }; 17 | 18 | struct three{ 19 | char a[3]; 20 | }; 21 | 22 | struct three get_three(){ 23 | struct three three = {}; 24 | three.a[0] = 1; 25 | three.a[1] = 2; 26 | three.a[2] = 3; 27 | return three; 28 | } 29 | 30 | void take_three(struct three three){ 31 | assert(three.a[0] == 1); 32 | assert(three.a[1] == 2); 33 | assert(three.a[2] == 3); 34 | } 35 | 36 | 37 | struct five get_five(){ 38 | struct five five = {}; 39 | five.a[0] = 1; 40 | five.a[1] = 2; 41 | five.a[2] = 3; 42 | five.a[3] = 4; 43 | five.a[4] = 5; 44 | return five; 45 | } 46 | 47 | void take_five(struct five five){ 48 | assert(five.a[0] == 1); 49 | assert(five.a[1] == 2); 50 | assert(five.a[2] == 3); 51 | assert(five.a[3] == 4); 52 | assert(five.a[4] == 5); 53 | } 54 | 55 | 56 | struct six get_six(){ 57 | struct six six = {}; 58 | six.a[0] = 1; 59 | six.a[1] = 2; 60 | six.a[2] = 3; 61 | six.a[3] = 4; 62 | six.a[4] = 5; 63 | six.a[5] = 6; 64 | return six; 65 | } 66 | 67 | void take_six(struct six six){ 68 | assert(six.a[0] == 1); 69 | assert(six.a[1] == 2); 70 | assert(six.a[2] == 3); 71 | assert(six.a[3] == 4); 72 | assert(six.a[4] == 5); 73 | assert(six.a[5] == 6); 74 | } 75 | 76 | struct seven get_seven(){ 77 | struct seven seven = {}; 78 | seven.a[0] = 1; 79 | seven.a[1] = 2; 80 | seven.a[2] = 3; 81 | seven.a[3] = 4; 82 | seven.a[4] = 5; 83 | seven.a[5] = 6; 84 | seven.a[6] = 7; 85 | return seven; 86 | } 87 | 88 | void take_seven(struct seven seven){ 89 | assert(seven.a[0] == 1); 90 | assert(seven.a[1] == 2); 91 | assert(seven.a[2] == 3); 92 | assert(seven.a[3] == 4); 93 | assert(seven.a[4] == 5); 94 | assert(seven.a[5] == 6); 95 | assert(seven.a[6] == 7); 96 | } 97 | 98 | int main(){ 99 | struct three three = get_three(); 100 | take_three(three); 101 | struct five five = get_five(); 102 | take_five(five); 103 | struct six six = get_six(); 104 | take_six(six); 105 | struct seven seven = get_seven(); 106 | take_seven(seven); 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /tests/run/offsets_on_anonymous_substructs.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | struct arst{ 4 | struct { int anon1; }; 5 | struct { int anon2; }; 6 | struct { int anon3; }; 7 | struct { int anon4; }; 8 | struct { int anon5; }; 9 | struct { int anon6; }; 10 | struct { int anon7; }; 11 | struct { int anon8; }; 12 | struct { int anon9; }; 13 | struct { int anona; }; 14 | struct { int anonb; }; 15 | struct { int anonc; }; 16 | struct { int anond; }; 17 | struct { int anone; }; 18 | struct { int anonf; }; 19 | }; 20 | 21 | struct string{ 22 | union{ 23 | int size; 24 | int length; 25 | int amount; 26 | }; 27 | union{ 28 | char *data; 29 | char *memory; 30 | }; 31 | }; 32 | 33 | #define assert(a) if(!(a)) return 1; 34 | 35 | int main(){ 36 | 37 | assert(0x0000000000000000 == (int)&((struct arst *)0)->anon1); 38 | assert(0x0000000000000004 == (int)&((struct arst *)0)->anon2); 39 | assert(0x0000000000000008 == (int)&((struct arst *)0)->anon3); 40 | assert(0x000000000000000C == (int)&((struct arst *)0)->anon4); 41 | assert(0x0000000000000010 == (int)&((struct arst *)0)->anon5); 42 | assert(0x0000000000000014 == (int)&((struct arst *)0)->anon6); 43 | assert(0x0000000000000018 == (int)&((struct arst *)0)->anon7); 44 | assert(0x000000000000001C == (int)&((struct arst *)0)->anon8); 45 | assert(0x0000000000000020 == (int)&((struct arst *)0)->anon9); 46 | assert(0x0000000000000024 == (int)&((struct arst *)0)->anona); 47 | assert(0x0000000000000028 == (int)&((struct arst *)0)->anonb); 48 | assert(0x000000000000002C == (int)&((struct arst *)0)->anonc); 49 | assert(0x0000000000000030 == (int)&((struct arst *)0)->anond); 50 | assert(0x0000000000000034 == (int)&((struct arst *)0)->anone); 51 | assert(0x0000000000000038 == (int)&((struct arst *)0)->anonf); 52 | 53 | 54 | assert((int)&((struct string *)0)->size == 0); 55 | assert((int)&((struct string *)0)->length == 0); 56 | assert((int)&((struct string *)0)->amount == 0); 57 | assert((int)&((struct string *)0)->data == 8); 58 | assert((int)&((struct string *)0)->memory == 8); 59 | 60 | 61 | return 0; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /tests/run/packed.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return -1 4 | #define offset_in_type(type, member) (__int64)(&((type *)0)->member) 5 | 6 | int main(){ 7 | struct __declspec(packed) packed{ 8 | __int8 a; 9 | __int32 b; 10 | __int16 c; 11 | __int64 d; 12 | } packed = { 13 | .a = 1, 14 | .b = 2, 15 | .c = 3, 16 | .d = 4, 17 | }; 18 | 19 | assert(offset_in_type(struct packed, a) == 0); 20 | assert(offset_in_type(struct packed, b) == 1); 21 | assert(offset_in_type(struct packed, c) == 1 + 4); 22 | assert(offset_in_type(struct packed, d) == 1 + 4 + 2); 23 | assert(sizeof(packed) == 1 + 4 + 2 + 8); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /tests/run/patches_into_flexible_array_member.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | struct structure_that_ends_in_flexible_array{ 4 | int hello; 5 | void *flexible_array[]; 6 | } arst = { 7 | 6, 8 | { 9 | &arst.flexible_array[0], 10 | &arst.flexible_array[1], 11 | &arst.flexible_array[2], 12 | &arst.flexible_array[3], 13 | &arst.flexible_array[4], 14 | &arst.flexible_array[5], 15 | } 16 | }; 17 | 18 | 19 | int main(){ 20 | for(int i = 0; i < arst.hello; i++){ 21 | if(arst.flexible_array[i] != &arst.flexible_array[i]) return 1; 22 | } 23 | return 0; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /tests/run/pointer_arithmetic_with_minus_one.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | int main(){ 5 | 6 | struct arst { 7 | int arst[5]; 8 | } *type = 0; 9 | 10 | type = type + (-1); 11 | 12 | return !((__int64)type == -sizeof(struct arst)); 13 | } 14 | -------------------------------------------------------------------------------- /tests/run/pointers_to_arrays_of_unknown_size.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define offset_in_type(type, member) (unsigned long long)(&((type *)0)->member) 4 | 5 | #define assert(a) if(!(a)) return 1; 6 | 7 | int main(){ 8 | 9 | struct has_array_of_unknown_size{ 10 | int asd; 11 | int array_of_unknown_size[]; 12 | }; 13 | 14 | 15 | assert(offset_in_type(struct has_array_of_unknown_size, array_of_unknown_size) == 4); 16 | assert(*(&((struct has_array_of_unknown_size *)0)->array_of_unknown_size) == (int *)4); 17 | 18 | // int (*asd)[] = &((struct has_array_of_unknown_size *)0)->array_of_unknown_size; 19 | return 0; 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/run/redeclaring_in_same_scope_and_regrowing_the_declaration_table.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | int main(){ 4 | int a = 1; 5 | int a = 2; 6 | 7 | if(a != 2) return 1; 8 | 9 | 10 | int c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; 11 | 12 | if(a != 2) return 1; 13 | 14 | int c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; 15 | 16 | if(a != 2) return 1; 17 | 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /tests/run/static_address_of_static_variable.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return 1 4 | 5 | int main(){ 6 | static int a = 1337; 7 | static int *b = &a; 8 | 9 | assert(&a == b); 10 | assert(a == *b); 11 | 12 | return 0; 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/run/static_initializers_to_string_literal.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return -1 4 | 5 | int main(){ 6 | static char array[] = "0123456789"; 7 | assert(array[0] == '0' && array[9] == '9' && array[10] == 0); 8 | 9 | static char array2[10] = "0123456789"; 10 | assert(array2[0] == '0' && array2[9] == '9' && array2[10] == 0); 11 | 12 | static char *pointer = "0123456789"; 13 | assert(pointer[0] == '0' && pointer[9] == '9' && pointer[10] == 0); 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /tests/run/static_reference_of_dll_import_function_needs_stub_compile_to_object.c: -------------------------------------------------------------------------------- 1 | // compile /c 2 | // link 3 | // run 4 | 5 | __declspec(dllimport) void *malloc(unsigned long long size); 6 | 7 | void *(*func)(unsigned long long size) = malloc; 8 | 9 | int main(){ 10 | char *a = func(1); 11 | *a = 0; 12 | return *a; 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/run/static_reference_of_dllimport_function_needs_stub.c: -------------------------------------------------------------------------------- 1 | // check "causes a stub to be generated" 2 | // run 3 | 4 | __declspec(dllimport) void *malloc(unsigned long long size); 5 | 6 | void *(*func)(unsigned long long size) = malloc; 7 | 8 | int main(){ 9 | char *a = func(1); 10 | *a = 0; 11 | return *a; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /tests/run/string_initializer_in_function.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define ARRAY_SIZE 4 | void unknown_size(){ 5 | char c[ARRAY_SIZE] = "asd"; 6 | unsigned char uc[ARRAY_SIZE] = "asd"; 7 | short s[ARRAY_SIZE] = L"asd"; 8 | unsigned short us[ARRAY_SIZE] = L"asd"; 9 | int i[ARRAY_SIZE] = U"asd"; 10 | unsigned int ui[ARRAY_SIZE] = U"asd"; 11 | } 12 | #undef ARRAY_SIZE 13 | 14 | #define ARRAY_SIZE 3 15 | void no_zero(){ 16 | char c[ARRAY_SIZE] = "asd"; 17 | unsigned char uc[ARRAY_SIZE] = "asd"; 18 | short s[ARRAY_SIZE] = L"asd"; 19 | unsigned short us[ARRAY_SIZE] = L"asd"; 20 | int i[ARRAY_SIZE] = U"asd"; 21 | unsigned int ui[ARRAY_SIZE] = U"asd"; 22 | } 23 | #undef ARRAY_SIZE 24 | 25 | #define ARRAY_SIZE 4 26 | void right_size(){ 27 | char c[ARRAY_SIZE] = "asd"; 28 | unsigned char uc[ARRAY_SIZE] = "asd"; 29 | short s[ARRAY_SIZE] = L"asd"; 30 | unsigned short us[ARRAY_SIZE] = L"asd"; 31 | int i[ARRAY_SIZE] = U"asd"; 32 | unsigned int ui[ARRAY_SIZE] = U"asd"; 33 | } 34 | #undef ARRAY_SIZE 35 | 36 | #define ARRAY_SIZE 100 37 | void big_size(){ 38 | char c[ARRAY_SIZE] = "asd"; 39 | unsigned char uc[ARRAY_SIZE] = "asd"; 40 | short s[ARRAY_SIZE] = L"asd"; 41 | unsigned short us[ARRAY_SIZE] = L"asd"; 42 | int i[ARRAY_SIZE] = U"asd"; 43 | unsigned int ui[ARRAY_SIZE] = U"asd"; 44 | } 45 | #undef ARRAY_SIZE 46 | 47 | int main(){ 48 | unknown_size(); 49 | no_zero(); 50 | right_size(); 51 | big_size(); 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /tests/run/stringify_tests.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #define assert(a) if(!(a)) return 1 4 | 5 | #define stringify(a) #a 6 | #define stringify2(_, a) #a 7 | #define stringify_va(...) #__VA_ARGS__ 8 | 9 | int main(){ 10 | // 11 | // normal tests 12 | // 13 | 14 | assert(stringify(a) == "a"); 15 | assert(stringify(a + b) == "a + b"); 16 | assert(stringify(a 17 | + 18 | b) == "a + b"); 19 | assert(stringify(a/*comment*/b) == "a b"); 20 | assert(stringify(a /* comment*/ 21 | /*comment*/ 22 | b) == "a b"); 23 | 24 | assert(stringify("hello") == "\"hello\""); 25 | 26 | assert(stringify("hello" "hello") == "\"hello\" \"hello\""); 27 | 28 | assert(stringify( a ) == "a"); 29 | assert(stringify( a + b ) == "a + b"); 30 | assert(stringify( a+b ) == "a+b"); 31 | 32 | // 33 | // second argument 34 | // 35 | assert(stringify2(1, a) == "a"); 36 | assert(stringify2(1, a + b) == "a + b"); 37 | assert(stringify2(1, a 38 | + 39 | b) == "a + b"); 40 | assert(stringify2(1, a/*comment*/b) == "a b"); 41 | assert(stringify2(1, a /* comment*/ 42 | /*comment*/ 43 | b) == "a b"); 44 | 45 | assert(stringify2(1, "hello") == "\"hello\""); 46 | 47 | assert(stringify2(1, "hello" "hello") == "\"hello\" \"hello\""); 48 | 49 | // 50 | // __VA_ARGS__ 51 | // 52 | assert(stringify_va(a) == "a"); 53 | assert(stringify_va(a + b) == "a + b"); 54 | assert(stringify_va(a 55 | + 56 | b) == "a + b"); 57 | assert(stringify_va(a/*comment*/b) == "a b"); 58 | assert(stringify_va(a /* comment*/ 59 | /*comment*/ 60 | b) == "a b"); 61 | 62 | assert(stringify_va("hello") == "\"hello\""); 63 | 64 | assert(stringify_va("hello" "hello") == "\"hello\" \"hello\""); 65 | 66 | 67 | return 0; 68 | } 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /tests/run/test.h: -------------------------------------------------------------------------------- 1 | 2 | typedef __int8 s8; 3 | typedef __int16 s16; 4 | typedef __int32 s32; 5 | typedef __int64 s64; 6 | 7 | typedef unsigned __int8 u8; 8 | typedef unsigned __int16 u16; 9 | typedef unsigned __int32 u32; 10 | typedef unsigned __int64 u64; 11 | 12 | typedef int b32; 13 | typedef s64 smm; 14 | 15 | void _exit(int status); 16 | #define assert(a) (!(a) ? (_exit(1), 0) : 0) 17 | 18 | #define true 1 19 | #define false 0 20 | #define null ((void *)0) 21 | #define array_count(a) (sizeof(a)/sizeof(*(a))) -------------------------------------------------------------------------------- /tests/run/the_infinite_function_call.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | typedef struct unresolved function(); 4 | typedef int end_function(); 5 | 6 | struct unresolved{ 7 | function *f; 8 | end_function *g; 9 | }; 10 | 11 | int global_counter; 12 | 13 | int g(){ 14 | return global_counter; 15 | } 16 | 17 | struct unresolved f(){ 18 | struct unresolved ret = {f, g}; 19 | global_counter++; 20 | 21 | return ret; 22 | } 23 | 24 | int main(){ 25 | return f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f() 26 | .f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f() 27 | .f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().g() == 0x48 ? 0 : 1; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /tests/run/tls.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | __declspec(thread) int thread_local_variable = 1; 4 | 5 | typedef void *HANDLE; 6 | 7 | __declspec(dllimport) HANDLE __stdcall CreateThread(void * lpThreadAttributes, unsigned long long dwStackSize, void * lpStartAddress, void * lpParameter, void * dwCreationFlags, void * lpThreadId); 8 | __declspec(dllimport) unsigned int __stdcall WaitForSingleObject(HANDLE hHandle, unsigned int dwMilliseconds); 9 | 10 | void *thread_address; 11 | 12 | int thread_proc(void *){ 13 | thread_local_variable = 2; 14 | thread_address = &thread_local_variable; 15 | return 0; 16 | } 17 | 18 | int main(){ 19 | 20 | thread_local_variable = 3; 21 | thread_address = &thread_local_variable; 22 | 23 | HANDLE ThreadHandle = CreateThread(0, 0, thread_proc, 0, 0, 0); 24 | WaitForSingleObject(ThreadHandle, /*INFINITE*/0xFFFFFFFF); 25 | if(thread_address == &thread_local_variable) return 1; 26 | 27 | return 0; 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/run/varargs_with_floating_point_immediate.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #include 4 | #include "test.h" 5 | 6 | void va_args_function(char *pad, ...){ 7 | va_list arg_list; 8 | va_start(arg_list, pad); 9 | 10 | float f = (float)va_arg(arg_list, double); 11 | 12 | assert(f == 1.0f); 13 | 14 | va_end(arg_list); 15 | } 16 | 17 | 18 | int main(){ 19 | va_args_function("1.0f: %f\n", 1.0f); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /tests/run/we_have_to_have_a_pre_main_file_even_for_main_without_arguments.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #pragma comment(lib, "kernel32") 4 | 5 | void *CreateThread(void *, __int64, unsigned int (*)(void *context), void *, int, void *); 6 | void Sleep(int); 7 | 8 | unsigned int sleep_and_exit(void *context){ 9 | Sleep(16); 10 | return 1; 11 | } 12 | 13 | int main(){ 14 | CreateThread(0, 0, sleep_and_exit, 0, 0, 0); 15 | 16 | // Exiting from main here is supposed to exit the process, 17 | // but Windows does not treat the main thread differantly 18 | // from any other thread. 19 | // This means, it will only cause the thread to call 20 | // `ExitThread` and the last thread that exits is `sleep_and_exit`. 21 | // This will cause the exit code to be `1` incorrectly. 22 | } 23 | -------------------------------------------------------------------------------- /tests/stdlib/setjmp.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #include 4 | 5 | 6 | jmp_buf env; 7 | 8 | int function(void){ 9 | longjmp(env, 1); 10 | return 1; 11 | } 12 | 13 | 14 | int main(){ 15 | if(setjmp(env) == 0){ 16 | return function(); 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /tests/stdlib/stddef.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int main(){ 5 | ptrdiff_t ptr; 6 | size_t size; 7 | // max_align_t max_align; 8 | wchar_t wchar; 9 | void *null = NULL; 10 | 11 | struct structure{ 12 | int a; 13 | }; 14 | 15 | return offsetof(struct structure, a); 16 | } 17 | -------------------------------------------------------------------------------- /tests/stdlib/using_stdup_from_oldnames.c: -------------------------------------------------------------------------------- 1 | // run 2 | 3 | #include 4 | #include 5 | 6 | int main(){ 7 | 8 | char *hello = "Hello, World!\n"; 9 | 10 | char *hello2 = strdup(hello); 11 | 12 | return strcmp(hello, hello2); 13 | } 14 | 15 | --------------------------------------------------------------------------------