├── .git-blame-ignore-revs ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── compile_time_python ├── .prospector.yml ├── __main__.py ├── colors.py ├── compile.py ├── compiler_explanations.py ├── explain_compiler_output.py ├── options.py └── util.py ├── d++ ├── docs ├── assign_function_to_int.md ├── assign_to_array.md ├── dcc_overview.png ├── eof_byte.md ├── function-definition-not-allowed-here.md ├── function-variable-clash.md ├── malloc_sizeof.md ├── missing_newline.md ├── stack_use_after_return.md └── zero_byte.md ├── install_scripts └── macos_install.sh ├── lib ├── create_github_release.py └── help2man_include.txt ├── packaging └── debian │ ├── .gitignore │ ├── build.sh │ └── debian │ ├── compat │ ├── control │ ├── copyright │ ├── manpages │ └── rules ├── run_time_python ├── .prospector.yml ├── colors.py ├── drive_gdb.py ├── explain_context.py ├── explain_error.py ├── explain_output_difference.py ├── gdb_interface.py ├── start_gdb.py ├── util.py └── watch_valgrind.py ├── tests ├── .gitignore ├── check_output │ ├── birds │ │ ├── bird-EOF-byte.c │ │ ├── bird-extra-newline.c │ │ ├── bird-line-missing-1-byte.c │ │ ├── bird-line-too-long.c │ │ ├── bird-line-wrong.c │ │ ├── bird-missing-newline.c │ │ ├── bird-no-output.c │ │ ├── bird-truncated.c │ │ ├── bird-zero-byte.c │ │ └── bird.c │ ├── check_birds.sh │ └── simple_check_output.sh ├── compile_time_errors │ ├── array_static_illegal_index.c │ ├── array_string_index.c │ ├── error_after_warning.c │ ├── main_wrong_type.c │ ├── no_main.c │ ├── printf_int_string_mismatch.c │ ├── relational_expression_with_comma.c │ ├── uninitialized_local_variable.c │ ├── unistd_compile_error.c │ └── variable_used_in_own_initialization.c ├── do_tests.sh ├── expected_output │ ├── array_static_illegal_index │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── array_string_index │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── array_subscript_is_not_an_integer │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── assert_without_closing_parenthesis │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── assign_array_to_int │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── assign_function_to_int │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── assign_pointer_to_int │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── assign_to_array │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── assign_to_multidimensional_array │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── braces_before_error │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── break_statement_not_in_loop │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── call_stack_null │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── call_stack_uninitialized │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── check-o │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── check_birds │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── check_exit_status │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── comparison_between_pointer_and_integer_char_and_int │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── condition_has_identical_branches │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── const0 │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── continue_statement_not_in_loop │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── data_argument_not_used_by_format_string │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── declaration_shadows_a_local_variable │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── dereference_null_with_arrow │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── dereference_null_with_arrow_arrow │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── dereference_null_with_arrow_arrow_arrow │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── dereference_null_with_asterisk │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── dereference_null_with_index │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── dereference_uninitialized_char_star_with_asterisk │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── dereference_uninitialized_with_arrow │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── dereference_uninitialized_with_arrow_arrow_arrow │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── dereference_uninitialized_with_asterisk │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── dereference_uninitialized_with_index │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── display_pointer_value0 │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── display_pointer_value1 │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── double_free │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── double_int_literal_conversion │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── duplicated-cond │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── empty_main--leak-check │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── empty_main-fsanitize=address │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── empty_main │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── enum0 │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── error_after_warning │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── expected_in_for_statement_specifier │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── expression_is_not_assignable │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── expression_result_unused │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── extra_tokens_at_end_of_include_directive │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── fclose │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── fdopen-fsanitize=address,valgrind │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── fgetc_NULL │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── fgetc_after_close │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── fgetc_uninitialized │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── fileno │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── fopen │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── format_type_mismatch │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── freopen │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── function-variable-clash │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── function_definition_is_not_allowed_here │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── h_file_not_found │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── has_empty_body │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── hash_define │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── ignoring_return_value_of_function │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── illegal_2d_array_access.cpp │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── illegal_2d_array_access │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── illegal_argv_index.cpp │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── illegal_argv_index │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── illegal_malloc_array_index--ifdef-main │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── illegal_malloc_array_index-fsanitize=address │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── illegal_malloc_array_index │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── illegal_malloc_array_index_uninitialized--ifdef-main │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── illegal_malloc_array_index_uninitialized-fsanitize=address │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── illegal_malloc_array_index_uninitialized │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── illegal_nested_array_assignment │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── illegal_vla_index │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── implicit_function_declaration │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── incremental_compilation │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── indexing_one_too_far │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── indirection-requires-pointer-operand │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── int_overflow │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── invalid_equal_equal_at_end_of_declaration │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── invalid_preprocessing_directive │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── is_uninitialized_when_used_here │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── is_uninitialized_when_used_within_its_own_initialization │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── leak_simple--leak-check │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── leak_then_exit--leak-check │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── leak_valgrind--leak-check │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── logical-and-always-false │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── logical-equal-expressions │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── logical-or-always-true │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── main_wrong_type │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── missing_function_return_type │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── missing_library_include │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── missing_parameter_type │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── missing_semicolon_line_before_assert │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── misspelt_printf │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── mod_zero-fsanitize=memory │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── mod_zero-fsanitize=valgrind │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── mod_zero.cpp │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── mod_zero │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── more_conversions_than_data_arguments │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── multiple_unsequenced_modifications │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── no_leak_printf--leak-check │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── no_leak_simple--leak-check │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── no_main │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── non_void_function_does_not_return_a_value │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── non_void_function_does_not_return_a_value_in_all_control_paths │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── nonnull │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── parameter_o_main │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── popen │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── posix_spawn │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── print_path │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── printf_int_string_mismatch │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── relational_comparison_result_unused │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── relational_expression_with_comma │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── rename │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── result_of_comparison_against_a_string_literal_is_unspecified │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── return_type_of_main_is_not_int │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── scanf_missing_ampersand │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── seek │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── simple_check_output │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── stack_use_after_return │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── string │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── subscripted_value_is_not_an_array │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── synchronization-time │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── too_many_arguments_to_function_call_expected_d_have_d │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── two_main_functions │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── two_uninitialized_values │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-array-element-if-fsanitize=address,memory │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-array-element-if-fsanitize=memory │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-array-element-if-fsanitize=valgrind │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-array-element-if │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-array-element-printf.cpp │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-array-element-printf │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-array-element-sum │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-char-array-fsanitize=valgrind │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-char-array-large.cpp │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-char-array-large │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-char-array.cpp-fsanitize=valgrind │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-local-variable │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-overflow │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-pointer-array │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-struct-field │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-struct-field1 │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-types-illegal-index │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-types-malloc │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized-types │ │ ├── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized_exit_status.cpp │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized_exit_status │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized_local_variable │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized_posix_spawn-fsanitize=valgrind │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── uninitialized_posix_spawnp-fsanitize=valgrind │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── unistd_compile_error │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── unistd_name_clash │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── unistd_use │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── unknown_escape_sequence │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── unknown_type_name_define │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── unknown_type_name_include │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── unterminated-strcmp │ │ ├── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── unterminated-strcpy │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── unterminated-strlen │ │ ├── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── unterminated-strncmp │ │ └── 000000-clang-16.0-x86_64-pc-linux-gnu.txt │ ├── unterminated_strcat │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── unterminated_string │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── use_after_free │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── use_after_return--use-after-return │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── use_after_return │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── use_of_undeclared_identifier │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── using_the_result_of_an_assignment_as_a_condition_without_parenthese │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── variable_used_in_own_initialization │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── void_function_should_not_return_a_value │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── warning_unknown_escape_sequence │ │ └── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ ├── write_null_stream │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt │ └── zero_size_array │ │ ├── 000000-clang-14.0-x86_64-pc-linux-gnu.txt │ │ └── 000001-clang-16.0-x86_64-pc-linux-gnu.txt ├── run_time_errors │ ├── braces_before_error.c │ ├── call_stack_null.c │ ├── call_stack_uninitialized.c │ ├── check-o.sh │ ├── const0.c │ ├── dereference_null_with_arrow.c │ ├── dereference_null_with_arrow_arrow.c │ ├── dereference_null_with_arrow_arrow_arrow.c │ ├── dereference_null_with_asterisk.c │ ├── dereference_null_with_index.c │ ├── dereference_uninitialized_char_star_with_asterisk.c │ ├── dereference_uninitialized_with_arrow.c │ ├── dereference_uninitialized_with_arrow_arrow_arrow.c │ ├── dereference_uninitialized_with_asterisk.c │ ├── dereference_uninitialized_with_index.c │ ├── display_pointer_value0.c │ ├── display_pointer_value1.c │ ├── double_free.c │ ├── enum0.c │ ├── fgetc_NULL.c │ ├── fgetc_after_close.c │ ├── fgetc_uninitialized.c │ ├── hash_define.c │ ├── illegal_2d_array_access.c │ ├── illegal_2d_array_access.cpp │ ├── illegal_argv_index.c │ ├── illegal_argv_index.cpp │ ├── illegal_malloc_array_index.c │ ├── illegal_malloc_array_index_uninitialized.c │ ├── illegal_nested_array_assignment.c │ ├── illegal_vla_index.c │ ├── incremental_compilation.sh │ ├── int_overflow.c │ ├── leak_simple.c │ ├── leak_then_exit.c │ ├── leak_valgrind.c │ ├── mod_zero.c │ ├── mod_zero.cpp │ ├── two_uninitialized_values.c │ ├── uninitialized-array-element-if.c │ ├── uninitialized-array-element-printf.c │ ├── uninitialized-array-element-printf.cpp │ ├── uninitialized-array-element-sum.c │ ├── uninitialized-char-array-large.c │ ├── uninitialized-char-array-large.cpp │ ├── uninitialized-char-array.c │ ├── uninitialized-char-array.cpp │ ├── uninitialized-overflow.c │ ├── uninitialized-pointer-array.c │ ├── uninitialized-struct-field.c │ ├── uninitialized-struct-field1.c │ ├── uninitialized-types-illegal-index.c │ ├── uninitialized-types-malloc.c │ ├── uninitialized-types.c │ ├── uninitialized_exit_status.c │ ├── uninitialized_exit_status.cpp │ ├── uninitialized_posix_spawn.c │ ├── uninitialized_posix_spawnp.c │ ├── unterminated-strcmp.c │ ├── unterminated-strcpy.c │ ├── unterminated-strlen.c │ ├── unterminated-strncmp.c │ ├── unterminated_strcat.c │ ├── unterminated_string.c │ ├── use_after_free.c │ ├── use_after_return.c │ ├── write_null_stream.c │ └── zero_size_array.c ├── run_time_no_errors │ ├── check_exit_status.sh │ ├── empty_main.c │ ├── fclose.c │ ├── fdopen.c │ ├── fileno.c │ ├── fopen.c │ ├── freopen.c │ ├── no_leak_printf.c │ ├── no_leak_simple.c │ ├── popen.c │ ├── posix_spawn.c │ ├── print_path.sh │ ├── rename.c │ ├── seek.c │ ├── string.c │ ├── synchronization-time.c │ ├── unistd_name_clash.c │ └── unistd_use.c ├── single_test.sh └── unused │ └── infinite_recursion.c ├── unhandled_run_time_errors ├── copy_uninitialized_double_to_int.c ├── short_overflow.c └── write_input_stream.c └── wrapper_c ├── dcc_check_output.c ├── dcc_dual_sanitizers.c ├── dcc_io.cpp ├── dcc_main.c ├── dcc_save_stdin.c └── dcc_util.c /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # reformat python with black 2 | 988486da44659cde8a42c4429c278bf402417116 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # exclude generated files from repo 2 | # and files/directories used created in development 3 | dcc 4 | dcc.1 5 | __pycache__ 6 | _build 7 | *.swp 8 | a.out 9 | *.o 10 | core 11 | *.deb 12 | *.rpm 13 | *.orig 14 | *tmp* 15 | random* 16 | experiments* 17 | debian 18 | 19 | # don't accidentally add random test files to repo 20 | /*.c 21 | /*.sh 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | EMBEDDED_SOURCE = $(wildcard run_time_python/*.py wrapper_c/*.c wrapper_c/*.cpp) 2 | SOURCE = $(wildcard compile_time_python/*.py) 3 | BUILD_DIR=_build 4 | 5 | # EMBEDDED_PACKAGE_NAME used by pkgutil.get_data in compile_time_python/compile.py 6 | EMBEDDED_PACKAGE_NAME=embedded_src 7 | PACKAGE_DIR=$(BUILD_DIR)/$(EMBEDDED_PACKAGE_NAME) 8 | 9 | dcc: $(SOURCE) $(EMBEDDED_SOURCE) Makefile 10 | rm -rf $(BUILD_DIR) 11 | mkdir -p $(PACKAGE_DIR) 12 | touch $(PACKAGE_DIR)/__init__.py 13 | echo 'VERSION = "'`git describe --tags`'"' >$(BUILD_DIR)/version.py 14 | for f in $(EMBEDDED_SOURCE); do ln -sf ../../$$f $(PACKAGE_DIR); done 15 | for f in $(SOURCE); do ln -sf ../$$f $(BUILD_DIR); done 16 | # --symlinks here breaks pkgutil.read_data in compile.py 17 | cd $(BUILD_DIR); zip $@.zip -9 -r *.py $(EMBEDDED_PACKAGE_NAME) 18 | echo '#!/usr/bin/env python3' >$@ 19 | cat $(BUILD_DIR)/$@.zip >>$@ 20 | chmod 755 $@ 21 | rm -rf $(BUILD_DIR) 22 | 23 | dcc.1: dcc lib/help2man_include.txt 24 | help2man --include=lib/help2man_include.txt ./dcc >dcc.1 25 | 26 | tests: dcc 27 | tests/do_tests.sh ./dcc 28 | 29 | tests_all_clang_versions: dcc 30 | for compiler in /usr/bin/clang-[1-24-9]* ; do echo $$compiler;tests/do_tests.sh ./dcc $$compiler; echo; done 31 | 32 | 33 | VERSION=$(shell git describe --tags|sed 's/-/./;s/-.*//') 34 | 35 | deb: packaging/debian/dcc_${VERSION}_all.deb 36 | 37 | packaging/debian/dcc_${VERSION}_all.deb: dcc dcc.1 38 | rm -rf debian 39 | mkdir -p debian/DEBIAN/usr/local/bin/ 40 | cp -p dcc debian/DEBIAN/usr/local/bin/ 41 | ln -sf dcc debian/DEBIAN/usr/local/bin/dcc++ 42 | echo Package: dcc >debian/DEBIAN/control 43 | echo Architecture: all >>debian/DEBIAN/control 44 | echo Description: a C compiler which explain errors to novice programmers >>debian/DEBIAN/control 45 | packaging/debian/build.sh 46 | 47 | .PHONY: deb tests tests_all_clang_versions 48 | -------------------------------------------------------------------------------- /compile_time_python/.prospector.yml: -------------------------------------------------------------------------------- 1 | strictness: medium 2 | pylint: 3 | run: true 4 | options: 5 | never-returning-functions: util.die 6 | disable: 7 | - consider-using-in 8 | - eval-used 9 | - import-outside-toplevel 10 | - multiple-imports 11 | - no-else-continue 12 | - no-else-return 13 | - too-many-arguments 14 | - too-many-locals 15 | - too-many-boolean-expressions 16 | - too-many-branches 17 | - too-many-nested-blocks 18 | - too-many-statements 19 | mccabe: 20 | run: false 21 | 22 | 23 | #strictness: medium 24 | #test-warnings: true 25 | #doc-warnings: true 26 | #autodetect: false 27 | #max-line-length: 120 28 | # 29 | #pep8: 30 | # full: true 31 | # disable: 32 | # - N803 # argument name should be lowercase 33 | # - N806 # variable in function should be lowercase 34 | # - N812 # lowercase imported as non lowercase 35 | # 36 | #pylint: 37 | # run: true 38 | # disable: 39 | # - too-many-locals 40 | # - arguments-differ 41 | # - no-else-return 42 | # - inconsistent-return-statements 43 | # 44 | #pep257: 45 | # run: true 46 | # disable: 47 | # - D203 # 1 blank line required before class docstring 48 | # - D212 # Multi-line docstring summary should start at the first line 49 | # - D213 # Multi-line docstring summary should start at the second line 50 | -------------------------------------------------------------------------------- /compile_time_python/__main__.py: -------------------------------------------------------------------------------- 1 | from compile import main 2 | 3 | if __name__ == "__main__": 4 | main() 5 | -------------------------------------------------------------------------------- /compile_time_python/colors.py: -------------------------------------------------------------------------------- 1 | # https://github.com/jonathaneunice/colors/ with some code removed 2 | 3 | # Copyright (c) 2012 Giorgos Verigakis 4 | # 5 | # Permission to use, copy, modify, and distribute this software for any 6 | # purpose with or without fee is hereby granted, provided that the above 7 | # copyright notice and this permission notice appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | 17 | import re 18 | 19 | # ANSI color names. There is also a "default" 20 | COLORS = ('black', 'red', 'green', 'yellow', 'blue', 21 | 'magenta', 'cyan', 'white') 22 | 23 | # ANSI style names 24 | STYLES = ('none', 'bold', 'faint', 'italic', 'underline', 'blink', 25 | 'blink2', 'negative', 'concealed', 'crossed') 26 | 27 | 28 | def _join(*values): 29 | """ 30 | Join a series of values with semicolons. The values 31 | are either integers or strings, so stringify each for 32 | good measure. Worth breaking out as its own function 33 | because semicolon-joined lists are core to ANSI coding. 34 | """ 35 | return ';'.join(str(v) for v in values) 36 | 37 | 38 | def _color_code(spec, base): 39 | """ 40 | Workhorse of encoding a color. Give preference to named colors from 41 | ANSI, then to specific numeric or tuple specs. If those don't work, 42 | try looking up CSS color names or parsing CSS color specifications 43 | (hex or rgb). 44 | 45 | :param str|int|tuple|list spec: Unparsed color specification 46 | :param int base: Either 30 or 40, signifying the base value 47 | for color encoding (foreground and background respectively). 48 | Low values are added directly to the base. Higher values use ` 49 | base + 8` (i.e. 38 or 48) then extended codes. 50 | :returns: Discovered ANSI color encoding. 51 | :rtype: str 52 | :raises: ValueError if cannot parse the color spec. 53 | """ 54 | if isinstance(spec, str): 55 | spec = spec.strip().lower() 56 | 57 | if spec == 'default': 58 | return _join(base + 9) 59 | elif spec in COLORS: 60 | return _join(base + COLORS.index(spec)) 61 | elif isinstance(spec, int) and 0 <= spec <= 255: 62 | return _join(base + 8, 5, spec) 63 | elif isinstance(spec, (tuple, list)): 64 | return _join(base + 8, 2, _join(*spec)) 65 | else: 66 | raise ValueError() # not using rgb currently 67 | rgb = parse_rgb(spec) 68 | # parse_rgb raises ValueError if cannot parse spec 69 | # or returns an rgb tuple if it can 70 | return _join(base + 8, 2, _join(*rgb)) 71 | 72 | 73 | def color(s, fg=None, bg=None, style=None): 74 | """ 75 | Add ANSI colors and styles to a string. 76 | 77 | :param str s: String to format. 78 | :param str|int|tuple fg: Foreground color specification. 79 | :param str|int|tuple bg: Background color specification. 80 | :param str: Style names, separated by '+' 81 | :returns: Formatted string. 82 | :rtype: str (or unicode in Python 2, if s is unicode) 83 | """ 84 | codes = [] 85 | 86 | if fg: 87 | codes.append(_color_code(fg, 30)) 88 | if bg: 89 | codes.append(_color_code(bg, 40)) 90 | if style: 91 | for style_part in style.split('+'): 92 | if style_part in STYLES: 93 | codes.append(STYLES.index(style_part)) 94 | else: 95 | raise ValueError('Invalid style "%s"' % style_part) 96 | 97 | if codes: 98 | template = '\x1b[{0}m{1}\x1b[0m' 99 | return template.format(_join(*codes), s) 100 | else: 101 | return s 102 | 103 | def strip_color(s): 104 | """ 105 | Remove ANSI color/style sequences from a string. The set of all possible 106 | ANSI sequences is large, so does not try to strip every possible one. But 107 | does strip some outliers seen not just in text generated by this module, but 108 | by other ANSI colorizers in the wild. Those include `\x1b[K` (aka EL or 109 | erase to end of line) and `\x1b[m`, a terse version of the more common 110 | `\x1b[0m`. 111 | """ 112 | return re.sub('\x1b\\[(K|.*?m)', '', s) 113 | 114 | 115 | -------------------------------------------------------------------------------- /d++: -------------------------------------------------------------------------------- 1 | dcc -------------------------------------------------------------------------------- /docs/assign_function_to_int.md: -------------------------------------------------------------------------------- 1 | You will get this error if for example, you write code like this:: 2 | 3 | ```c 4 | int a; 5 | a = square; 6 | ``` 7 | 8 | when you wanted to do this: 9 | 10 | ```c 11 | int a; 12 | a = square(5); 13 | ``` 14 | -------------------------------------------------------------------------------- /docs/assign_to_array.md: -------------------------------------------------------------------------------- 1 | You are not permitted to assign arrays in C. 2 | 3 | You can NOT do this: 4 | 5 | ```c 6 | #define ARRAY_SIZE 10 7 | 8 | int array1[ARRAY_SIZE] = {0,1,2,3,4,5,6,7,8,9}; 9 | int array2[ARRAY_SIZE]; 10 | 11 | array2 = array1; 12 | ``` 13 | 14 | You can instead use a loop to copy each array element individually. 15 | 16 | ```c 17 | 18 | #define ARRAY_SIZE 10 19 | 20 | int array1[ARRAY_SIZE] = {0,1,2,3,4,5,6,7,8,9}; 21 | int array2[ARRAY_SIZE]; 22 | 23 | 24 | for (int i = 0; i < 10; i++) { 25 | array2[i] = array1[i]; 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/dcc_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/docs/dcc_overview.png -------------------------------------------------------------------------------- /docs/eof_byte.md: -------------------------------------------------------------------------------- 1 | Accidentally printing the special **EOF** value returned by the functions _getchar_, _getc_ and _fgetc_ is common bug. 2 | 3 | For example, this program prints the **EOF** value before the loop exits: 4 | 5 | ```c 6 | #include 7 | 8 | int main(void) { 9 | int c = 0; 10 | while (c != EOF) { 11 | int c = getchar(); 12 | putchar(c); 13 | } 14 | return 0; 15 | } 16 | ``` 17 | 18 | The special **EOF** value typically is defined to be `-1` (in ``) 19 | and when printed is invisible. So the program appears to work. 20 | 21 | ```console 22 | $ dcc cat.c 23 | $ echo cat | ./a.out 24 | cat 25 | $ 26 | ``` 27 | 28 | But the program will fail automated testing because it is printing an extra byte. 29 | 30 | This is a program that output the same bytes as the above example. 31 | 32 | ```c 33 | #include 34 | 35 | int main(void) { 36 | 37 | putchar('c'); 38 | putchar('a'); 39 | putchar('t'); 40 | putchar('\n'); 41 | putchar(EOF); 42 | 43 | return 0; 44 | } 45 | ``` 46 | 47 | This is a program which doesn't print the EOF value: 48 | 49 | ```c 50 | #include 51 | 52 | int main(void) { 53 | int c = getchar(); 54 | while (c != EOF) { 55 | putchar(c); 56 | c = getchar(); 57 | } 58 | return 0; 59 | } 60 | ``` 61 | -------------------------------------------------------------------------------- /docs/function-definition-not-allowed-here.md: -------------------------------------------------------------------------------- 1 | 2 | If you forget a curly bracket, e.g. 3 | ```c 4 | int sum(int x, int y) { 5 | if (x > y) { 6 | return x + y; 7 | } else { 8 | return x - y; 9 | // <-- missing closing curly bracket 10 | } 11 | 12 | int f(int x) { 13 | return sum(x, x); 14 | } 15 | ``` 16 | 17 | The compiler will give an error when the next function definition starts. 18 | 19 | You can fix by adding the missing curly bracket (brace): 20 | 21 | ```c 22 | int sum(int x, int y) { 23 | if (x > y) { 24 | return x + y; 25 | } else { 26 | return x - y; 27 | } 28 | } 29 | 30 | int f(int x) { 31 | return sum(x, x); 32 | } 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/function-variable-clash.md: -------------------------------------------------------------------------------- 1 | It is legal to have local variable with the same name as a function, but you can't then call the function 2 | because the local variable declaration hides the function. 3 | 4 | For example: 5 | 6 | ```c 7 | int sum(int x, int y) { 8 | return x + y; 9 | } 10 | 11 | int f(int sum) { 12 | int square = sum * sum; 13 | 14 | // error sum because sum is a variable 15 | return sum(square, square); 16 | } 17 | ``` 18 | 19 | You can fix the name clash by changing the name of the variable: 20 | 21 | ```c 22 | int sum(int x, int y) { 23 | return x + y; 24 | } 25 | 26 | int f(int a) { 27 | int square = a * a; 28 | 29 | // error sum because sum is a variable 30 | return sum(square, square); 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/malloc_sizeof.md: -------------------------------------------------------------------------------- 1 | You must be careful when using malloc to allocate the correct number of bytes. 2 | 3 | For example, this program contains a common error. 4 | 5 | The programmer would like malloc to allocate enough bytes 6 | to hold a struct node. 7 | 8 | 9 | But instead they ask malloc for enough bytes to hold a **pointer** to a **struct node**. 10 | 11 | ```c 12 | struct node { 13 | struct node *next; 14 | int data; 15 | }; 16 | 17 | int main(void) { 18 | 19 | struct node *n; 20 | 21 | n = malloc(sizeof (struct node *)); 22 | n->data = NULL; 23 | 24 | } 25 | ``` 26 | 27 | This program asks malloc for enough bytes to hold a **struct node**. 28 | 29 | ```c 30 | struct node { 31 | struct node *next; 32 | int data; 33 | }; 34 | 35 | int main(void) { 36 | struct node *n; 37 | 38 | n = malloc(sizeof (struct node)); 39 | n->data = NULL; 40 | 41 | } 42 | ``` 43 | 44 | This video introduces the concepts underlying malloc: 45 | 46 |
47 | 48 |
49 | 50 | This video takes you though using these concepts: 51 | 52 | 53 |
54 | 55 |
-------------------------------------------------------------------------------- /docs/missing_newline.md: -------------------------------------------------------------------------------- 1 | Forgetting to print a newline is a common mistake. 2 | 3 | For example, this program doesn't print a newline. 4 | 5 | ```c 6 | int main(void) { 7 | int answer = 7 * 6; 8 | printf("%d", answer); 9 | } 10 | 11 | ``` 12 | 13 | So when its compiled and run you'll see something like this: 14 | 15 | ```console 16 | $ dcc answer.c 17 | $ ./a.out 18 | 42$ 19 | ``` 20 | 21 | If you add a **\n** to the _printf_ like this: 22 | 23 | ```c 24 | int main(void) { 25 | int answer = 7 * 6; 26 | printf("%d\n", answer); 27 | } 28 | ``` 29 | 30 | It will fix the problem: 31 | 32 | 33 | ```console 34 | $ dcc answer.c 35 | $ ./a.out 36 | 42 37 | $ 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /docs/stack_use_after_return.md: -------------------------------------------------------------------------------- 1 | A C function can not return a pointer to a local variable. 2 | 3 | A local variable variable does not exist after the function returns. 4 | 5 | For example, you can NOT do this: 6 | 7 | ```c 8 | struct node { 9 | struct node *next; 10 | int data; 11 | }; 12 | 13 | struct node *create_node(int i) { 14 | struct node n; 15 | 16 | n.data = i; 17 | n.next = NULL; 18 | 19 | return &n; 20 | } 21 | ``` 22 | 23 | A function can return a pointer provided by malloc: 24 | 25 | For example, you can do this: 26 | 27 | 28 | ```c 29 | struct node { 30 | struct node *next; 31 | int data; 32 | }; 33 | 34 | struct node *create_node(int i) { 35 | struct node *p; 36 | 37 | p = malloc(sizeof (struct node)); 38 | p->data = i; 39 | p->next = NULL; 40 | 41 | return p; 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/zero_byte.md: -------------------------------------------------------------------------------- 1 | Accidentally printing a zero byte is easy to do in a C program but hard to debug. 2 | 3 | For example, this program accidentally prints a zero byte when it prints `string[3]`: 4 | 5 | ```c 6 | #include 7 | 8 | int main(void) { 9 | char *string = "dog"; 10 | 11 | for (int i = 0; i < 4; i++) { 12 | putchar(string[i]); 13 | } 14 | 15 | putchar('\n'); 16 | 17 | return 0; 18 | } 19 | ``` 20 | 21 | And because printing of a zero byte is invisible, the program looks like it works: 22 | 23 | ```console 24 | $ dcc dog.c 25 | $ ./a.out 26 | dog 27 | $ 28 | ``` 29 | 30 | 31 | 32 | This is an equivalent program: 33 | 34 | ```c 35 | #include 36 | 37 | int main(void) { 38 | 39 | putchar('d'); 40 | putchar('o'); 41 | putchar('g'); 42 | putchar('\0'); // or putchar(0); 43 | putchar('\n'); 44 | 45 | return 0; 46 | } 47 | ``` 48 | 49 | This is a program which doesn't print the zero byte: 50 | 51 | ```c 52 | #include 53 | 54 | int main(void) { 55 | char *string = "dog"; 56 | 57 | for (int i = 0; string[i] != '\0'; i++) { 58 | putchar(string[i]); 59 | } 60 | 61 | putchar('\n'); 62 | 63 | return 0; 64 | } 65 | ``` 66 | 67 | It is equivalent to this program: 68 | 69 | ```c 70 | #include 71 | 72 | int main(void) { 73 | 74 | putchar('d'); 75 | putchar('o'); 76 | putchar('g'); 77 | putchar('\n'); 78 | 79 | return 0; 80 | } 81 | ``` 82 | -------------------------------------------------------------------------------- /install_scripts/macos_install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | HOME_PATH=~ 4 | INSTALL_PATH="${HOME_PATH}/.dcc" 5 | 6 | if [[ `uname` = MINGW* ]] || [[ `uname` = MSYS* ]]; then 7 | if [[ $MSYS2_PATH_TYPE != 'inherit' ]]; then 8 | setx MSYS2_PATH_TYPE inherit 9 | echo Updated! Please restart your terminal and rerun this script to install dcc. 10 | fi 11 | fi 12 | 13 | function report_missing_gdb () { 14 | if [[ `uname` = Darwin ]]; then 15 | echo "Missing gdb on path, see: https://sourceware.org/gdb/wiki/PermissionsDarwin." 16 | elif [[ `uname` = MINGW* ]] || [[ `uname` = MSYS* ]]; then 17 | echo "Git not found. Please run \"pacman -S python --noconfirm;\" in the terminal and then reinstall" 18 | elif [[ `uname` = Linux ]]; then 19 | echo "Please install git using your package manager For example: sudo apt install python" 20 | fi 21 | exit 1 22 | } 23 | 24 | function report_missing_python3 () { 25 | if [[ `uname` = Darwin ]]; then 26 | echo "python3 not found on path, ensure python3 is available." 27 | elif [[ `uname` = MINGW* ]] || [[ `uname` = MSYS* ]]; then 28 | echo "Git not found. Please run \"pacman -S python --noconfirm;\" in the terminal and then reinstall" 29 | elif [[ `uname` = Linux ]]; then 30 | echo "Please install git using your package manager For example: sudo apt install python" 31 | fi 32 | exit 1 33 | } 34 | 35 | command -v python3 >/dev/null 2>&1 || report_missing_python3 36 | command -v gdb >/dev/null 2>&1 || report_missing_gdb 37 | 38 | if [ -d "${INSTALL_PATH}" ]; then 39 | echo "Looks like you already have dcc installed!" 40 | echo "To uninstall run \"rm -rf ${INSTALL_PATH}\"" 41 | exit 1 42 | fi 43 | 44 | sudo mkdir "$INSTALL_PATH" 45 | sudo curl -L https://github.com/COMP1511UNSW/dcc/releases/latest/download/dcc -o "$INSTALL_PATH/dcc" 46 | sudo chmod +x "$INSTALL_PATH/dcc" 47 | 48 | # Add to .bashrc if using bash 49 | if [ ${SHELL} = "/bin/bash" ]; then 50 | echo "export PATH=\"$INSTALL_PATH:\$PATH\"" >> ~/.bash_profile 51 | echo "export PATH=\"$INSTALL_PATH:\$PATH\"" >> ~/.bashrc 52 | fi 53 | 54 | # Add to .zshrc if using zsh 55 | if [ ${SHELL} = "/bin/zsh" ]; then 56 | echo "export PATH=\"$INSTALL_PATH:\$PATH\"" >> ~/.zshrc 57 | fi 58 | 59 | export PATH="$INSTALL_PATH:$PATH" 60 | 61 | if [[ `uname` = MINGW32* ]]; then 62 | #Export to path -- for current terminal 63 | export PATH="$HOME/.dcc/dcc:$PATH" 64 | 65 | #Export path for new terminals 66 | export ORIGINAL_PATH="$HOME/.dcc/dcc:$ORIGINAL_PATH" 67 | 68 | # Set path 69 | setx PATH "$ORIGINAL_PATH" 70 | fi 71 | 72 | if [[ `uname` = MINGW64* ]] || [[ `uname` = MSYS* ]]; then 73 | #Export to path -- for current terminal 74 | export PATH="$HOME/.dcc/dcc:$PATH" 75 | 76 | #Export path for new terminals 77 | export ORIGINAL_PATH="$HOME/.dcc/dcc:$ORIGINAL_PATH" 78 | 79 | # Set path 80 | setx PATH "$ORIGINAL_PATH" 81 | fi 82 | 83 | echo "DCC Successfully installed! Please restart your terminal..." -------------------------------------------------------------------------------- /lib/create_github_release.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # run as e.g. create_github_release.py 1.0 'Initial github release of dcc' 4 | 5 | # https://stackoverflow.com/questions/38153418/can-someone-give-a-python-requests-example-of-uploading-a-release-asset-in-githu/52354681#52354681 6 | 7 | import json, os, re, subprocess, sys 8 | from urllib.parse import urlencode 9 | from urllib.request import Request, urlopen 10 | 11 | REPO = 'COMP1511UNSW/dcc' 12 | URL_TEMPLATE = 'https://{}.github.com/repos/' + REPO + '/releases' 13 | 14 | def make_release(token, tag): 15 | # print('token', token) 16 | # print('tag', tag) 17 | # print('url', URL_TEMPLATE.format('api'),) 18 | _json = json.loads(urlopen(Request( 19 | URL_TEMPLATE.format('api'), 20 | json.dumps({ 21 | 'tag_name': tag, 22 | 'name': tag, 23 | 'prerelease': False, 24 | }).encode(), 25 | headers={ 26 | 'Accept': 'application/vnd.github.v3+json', 27 | 'Authorization': 'token ' + token, 28 | }, 29 | )).read().decode()) 30 | return _json['id'] 31 | 32 | def upload_file(token, pathname, release_id): 33 | with open(pathname, 'br') as myfile: 34 | content = myfile.read() 35 | print('pathname', pathname) 36 | print('token', token) 37 | print('url', URL_TEMPLATE.format('uploads') + '/' + str(release_id) + '/assets?' \ 38 | + urlencode({'name': os.path.split(pathname)[1]})) 39 | json.loads(urlopen(Request( 40 | URL_TEMPLATE.format('uploads') + '/' + str(release_id) + '/assets?' \ 41 | + urlencode({'name': os.path.split(pathname)[1]}), 42 | content, 43 | headers={ 44 | 'Accept': 'application/vnd.github.v3+json', 45 | 'Authorization': 'token ' + token, 46 | 'Content-Type': 'application/zip', 47 | }, 48 | )).read().decode()) 49 | 50 | def run(command): 51 | print(' '.join(command)) 52 | subprocess.check_call(command) 53 | 54 | def update_readme(tag): 55 | with open('README.md') as f: 56 | contents = f.read() 57 | contents = re.sub(r'dcc/releases/download/[^/]+', 'dcc/releases/download/' + tag, contents) 58 | contents = re.sub(r'dcc_[\w\.]+_all.deb', f'dcc_{tag}_all.deb', contents) 59 | with open('README.md', 'w') as f: 60 | f.write(contents) 61 | 62 | def main(): 63 | if len(sys.argv) != 3: 64 | print("Usage:", sys.argv[0], ' ', file=sys.stderr) 65 | sys.exit(1) 66 | tag = sys.argv[1] # e.g 1.0' 67 | description = sys.argv[2] # description 68 | token = os.environ.get('GITHUB_TOKEN', '') 69 | with open(os.path.join(os.environ.get('HOME', ''), '.github_token')) as f: 70 | token = f.read().strip() 71 | update_readme(tag) 72 | run(['git', 'commit', 'README.md', '--allow-empty', '-m', 'release ' + tag]) 73 | run(['git', 'tag', '-a', tag, '-m', description]) 74 | run(['git', 'push']) 75 | run(['git', 'push', 'origin', tag]) 76 | run(['rm', '-f', 'dcc']) 77 | run(['make', 'dcc', 'dcc.1']) 78 | run(['packaging/debian/build.sh']) 79 | release_id = make_release(token, tag) 80 | for pathname in ['dcc', f'packaging/debian/dcc_{tag}_all.deb']: 81 | upload_file(token, pathname, release_id) 82 | 83 | if __name__ == '__main__': 84 | main() 85 | -------------------------------------------------------------------------------- /lib/help2man_include.txt: -------------------------------------------------------------------------------- 1 | [EXAMPLES] 2 | 3 | $ dcc buffer_overflow.c 4 | $ ./a.out 5 | a.c:6:3: runtime error: index 10 out of bounds for type 'int [10]' 6 | 7 | Execution stopped here in main() in buffer_overflow.c at line 6: 8 | 9 | int a[10]; 10 | for (int i = 0; i <= 10; i++) { 11 | --> a[i] = i * i; 12 | } 13 | } 14 | 15 | Values when execution stopped: 16 | 17 | a = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81} 18 | i = 10 19 | $ dcc --memory uninitialized-array-element.c 20 | $ ./a.out 21 | uninitialized-array-element:6 runtime error uninitialized variable used 22 | 23 | Execution stopped here in main() in uninitialized-array-element.c at line 6: 24 | 25 | int a[1000]; 26 | a[42] = 42; 27 | --> if (a[argc]) { 28 | a[43] = 43; 29 | } 30 | 31 | Values when execution stopped: 32 | 33 | argc = 1 34 | a[42] = 42 35 | a[43] = -1094795586 <-- warning appears to be uninitialized value 36 | a[argc] = -1094795586 <-- warning appears to be uninitialized value 37 | $ dcc --leak-check leak.c 38 | $ dcc --valgrind uninitialized-array-element.c 39 | uninitialized-array-element:6 runtime error uninitialized variable used 40 | 41 | Execution stopped here in main() in uninitialized-array-element.c at line 6: 42 | 43 | int a[1000]; 44 | a[42] = 42; 45 | --> if (a[argc]) { 46 | a[43] = 43; 47 | } 48 | 49 | Values when execution stopped: 50 | 51 | argc = 1 52 | a[42] = 42 53 | a[43] = 0 54 | a[argc] = 0 55 | 56 | $ dcc --leak-check leak.c 57 | $ ./a.out 58 | Error: free not called for memory allocated with malloc in function main in leak.c at line 3. 59 | 60 | [ENVIRONMENT] 61 | DCC_DEBUG level of debugging output 62 | [AUTHOR] 63 | Andrew Taylor 64 | [REPORTING BUGS] 65 | https://github.com/COMP1511UNSW/dcc/issues 66 | -------------------------------------------------------------------------------- /packaging/debian/.gitignore: -------------------------------------------------------------------------------- 1 | dcc-* 2 | dcc_* 3 | 4 | -------------------------------------------------------------------------------- /packaging/debian/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export EMAIL="andrewt@unsw.edu.au" 4 | export DEBFULLNAME="Andrew Taylor" 5 | 6 | base_directory=$(dirname $(readlink -f "$0")) 7 | source_directory=$base_directory/../.. 8 | version=`git describe --tags|sed 's/-/./;s/-.*//'` 9 | package_name=dcc 10 | 11 | dir=$base_directory/dcc-$version 12 | 13 | rm -rf $dir 14 | mkdir -p $dir/debian/ 15 | cp -p $source_directory/dcc $dir 16 | cp -p $source_directory/dcc.1 $dir 17 | rsync -a $base_directory/debian/ $dir/debian/ 18 | git tag -l -n9 --sort=-version:refname --format 'dcc (%(refname:lstrip=-1)) unstable; urgency=medium 19 | 20 | * %(contents) 21 | -- %(*authorname) %(*authoremail) %(*authordate)'| 22 | sed 's?> \(.*\) \(.*\) \(.*\) \([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\) \(.*\) \(.*\)?> \1, \3 \2 \5 \4 \6?' >$dir/debian/changelog 23 | 24 | cd $dir 25 | dpkg-buildpackage -b 26 | #cd $base_directory 27 | #lintian dcc_${version}_all.deb 28 | exit 0 29 | 30 | -------------------------------------------------------------------------------- /packaging/debian/debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /packaging/debian/debian/control: -------------------------------------------------------------------------------- 1 | Source: dcc 2 | Section: devel 3 | Priority: optional 4 | Maintainer: Andrew Taylor 5 | Build-Depends: debhelper (>= 9) 6 | 7 | Package: dcc 8 | Architecture: all 9 | Depends: python3 (>= 3.6), gdb(>= 7.12), clang(>= 7.0), valgrind(>= 1:3.13) 10 | Homepage: https://github.com/COMP1511UNSW/dcc 11 | Description: compiler for novice C programmers 12 | dcc compiles C programs using clang and adds explanations suitable 13 | for novice programmers to compiler messages novice programmers are 14 | likely to encounter and not understand. dcc also adds code to the 15 | binary which detects run-time errors and print information likely 16 | to be helpful to novice programmers, including printing values of 17 | variable in lines used near where the run-time error occurred. 18 | -------------------------------------------------------------------------------- /packaging/debian/debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: dcc 3 | Source: https://github.com/COMP1511UNSW/dcc 4 | 5 | Files: help_cs50.py 6 | Copyright: unknown 7 | License: GPL/v3 8 | 9 | Files: * 10 | Copyright: 2011-2019 Andrew Taylor 11 | License: GPL/v3 12 | -------------------------------------------------------------------------------- /packaging/debian/debian/manpages: -------------------------------------------------------------------------------- 1 | dcc.1 2 | -------------------------------------------------------------------------------- /packaging/debian/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | clean: 4 | @# Do nothing 5 | 6 | build: 7 | @# Do nothing 8 | 9 | binary: 10 | mkdir -p debian/dcc/usr/bin 11 | mkdir -p debian/dcc/usr/share/doc/dcc 12 | cp dcc debian/dcc/usr/bin/ 13 | gzip -9 --stdout debian/changelog >debian/dcc/usr/share/doc/dcc/changelog.gz 14 | cp debian/copyright debian/dcc/usr/share/doc/dcc 15 | dh_installman 16 | dh_gencontrol 17 | dh_builddeb 18 | -------------------------------------------------------------------------------- /run_time_python/.prospector.yml: -------------------------------------------------------------------------------- 1 | ../compile_time_python/.prospector.yml -------------------------------------------------------------------------------- /run_time_python/colors.py: -------------------------------------------------------------------------------- 1 | ../compile_time_python/colors.py -------------------------------------------------------------------------------- /run_time_python/drive_gdb.py: -------------------------------------------------------------------------------- 1 | import os, platform, sys, signal, traceback 2 | import colors, gdb_interface, explain_error, util 3 | 4 | # 5 | # Code below is executed from gdb. 6 | # It prints details of the program state likely to be of interest to 7 | # a beginner programmer 8 | # 9 | 10 | # workaround - avoid warning message from analysers 11 | if 0: 12 | gdb = None 13 | 14 | 15 | def drive_gdb(): 16 | output_stream = os.fdopen(3, "w", encoding="utf-8", errors="replace") 17 | util.set_debug_level() 18 | util.set_debug_stream(output_stream) 19 | windows_subsystem_for_linux = "microsoft" in platform.uname()[3].lower() 20 | colorize_output = output_stream.isatty() or os.environ.get( 21 | "DCC_COLORIZE_OUTPUT", False 22 | ) 23 | if colorize_output: 24 | color = colors.color 25 | else: 26 | color = lambda text, *args, **kwargs: text 27 | # signal.signal(signal.SIGINT, interrupt_handler) 28 | 29 | try: 30 | gdb_interface.set_interface(gdb) 31 | gdb_interface.gdb_attach() 32 | pid = os.environ.get("DCC_PID", "") 33 | sanitizer2_pid = os.environ.get("DCC_SANITIZER2_PID", "") 34 | sanitizer1_pid = os.environ.get("DCC_SANITIZER1_PID", "") 35 | if pid and sanitizer2_pid and sanitizer1_pid: 36 | if pid == sanitizer2_pid: 37 | os.kill(int(sanitizer1_pid), signal.SIGUSR1) 38 | explain_error.explain_error(output_stream, color) 39 | except gdb.error as e: 40 | if "ptrace" in str(e).lower() and os.path.exists("/.dockerenv"): 41 | print( 42 | "\ndcc : can not provide information about variables because docker not run with --cap-add=SYS_PTRACE\n", 43 | file=output_stream, 44 | ) 45 | elif util.get_debug_level(): 46 | traceback.print_exc(file=output_stream) 47 | sys.exit(1) 48 | except Exception: 49 | if util.get_debug_level(): 50 | traceback.print_exc(file=output_stream) 51 | sys.exit(1) 52 | 53 | output_stream.flush() 54 | # __dcc_error_exit hangs for unknown reason on WSL 55 | if not windows_subsystem_for_linux: 56 | gdb_interface.gdb_execute("call (void)__dcc_error_exit()") 57 | # kill_all() 58 | gdb_interface.gdb_execute("quit") 59 | 60 | 61 | if __name__ == "__main__": 62 | drive_gdb() 63 | -------------------------------------------------------------------------------- /run_time_python/gdb_interface.py: -------------------------------------------------------------------------------- 1 | import os, re 2 | from util import dprint 3 | 4 | 5 | def set_interface(interface): 6 | global gdb 7 | gdb = interface 8 | 9 | 10 | def gdb_attach(): 11 | gdb.execute("set exec-file-mismatch off") 12 | pid = int(os.environ.get("DCC_PID")) 13 | if "DCC_VALGRIND_ERROR" in os.environ or "DCC_VALGRIND_RUNNING" in os.environ : 14 | dprint(2, "attaching gdb to valgrind", pid) 15 | gdb.execute(f"target remote | vgdb --pid={pid}") 16 | else: 17 | dprint(2, "attaching gdb to ", pid) 18 | gdb.execute(f"attach {pid}") 19 | dprint(3, "gdb_attach() returning") 20 | 21 | 22 | # most uses can be replaced by gdb_eval 23 | def gdb_evaluate(expression): 24 | dprint(3, "gdb_evaluate:", expression) 25 | value = gdb_execute(f"print {expression}") 26 | value = re.sub(r"^[^=]*=\s*", "", value).strip() 27 | dprint(3, "->", value) 28 | return value.strip() 29 | 30 | 31 | def gdb_eval(expression): 32 | dprint(3, "gdb_eval:", expression) 33 | try: 34 | value = gdb.parse_and_eval(expression) 35 | dprint(3, "->", value) 36 | except gdb.error as e: 37 | dprint(3, e) 38 | value = None 39 | return value 40 | 41 | 42 | def gdb_set_frame(level): 43 | gdb_execute(f"frame {level}") 44 | 45 | 46 | # only in recent gdb versions 47 | def gdb_get_frame(): 48 | dprint(3, "gdb.selected_frame") 49 | try: 50 | return gdb.selected_frame().level() 51 | except gdb.error as e: 52 | dprint(3, "gdb.selected_frame", e) 53 | return 0 54 | 55 | 56 | def gdb_execute(command): 57 | dprint(3, "gdb.execute:", command) 58 | try: 59 | s = gdb.execute(command, to_string=True) 60 | except gdb.error as e: 61 | dprint(3, "gdb.execute", e) 62 | s = "" 63 | dprint(3, "gdb.execute:", "->", s) 64 | return s 65 | 66 | 67 | def gdb_flush(): 68 | dprint(3, "gdb.flush") 69 | gdb.flush(gdb.STDOUT) 70 | gdb.flush(gdb.STDERR) 71 | 72 | 73 | def gdb_get_byte_array(array, length): 74 | try: 75 | gdb_array = gdb_eval(array) 76 | return bytearray((256 + int(gdb_array[i])) % 256 for i in range(length)) 77 | except (IndexError, ValueError, TypeError, gdb.error): 78 | return b'' 79 | -------------------------------------------------------------------------------- /run_time_python/start_gdb.py: -------------------------------------------------------------------------------- 1 | import os, sys, signal, subprocess, time 2 | 3 | 4 | def start_gdb(gdb_driver_file="drive_gdb.py"): 5 | signal.signal(signal.SIGINT, lambda *_: kill_all()) 6 | debug_level = int(os.environ.get("DCC_DEBUG", "0")) 7 | 8 | # 9 | # if a run-time error has occurred in sanitizer1 kill sanitizer2 now to avoid dupicate error 10 | # sanitizer2 will sanitizer1 if it starts gdb successfully 11 | # 12 | pid = os.environ.get("DCC_PID", "") 13 | sanitizer2_pid = os.environ.get("DCC_SANITIZER2_PID", "") 14 | sanitizer1_pid = os.environ.get("DCC_SANITIZER1_PID", "") 15 | if pid and sanitizer2_pid and sanitizer1_pid: 16 | if pid == sanitizer1_pid: 17 | kill_sanitizer2() 18 | 19 | if debug_level > 1: 20 | print("start_gdb: ", end="") 21 | print( 22 | " ".join( 23 | f"{k}={os.environ.get(k, '')}" 24 | for k in "DCC_PID DCC_SANITIZER1_PID DCC_SANITIZER2_PID DCC_BINARY".split() 25 | ) 26 | ) 27 | 28 | for key in os.environ: 29 | if key.startswith("PYTHON"): 30 | del os.environ[key] 31 | 32 | # gdb seems to need this for imports to work 33 | os.environ["PYTHONPATH"] = "." 34 | os.environ["DCC_RUN_INSIDE_GDB"] = "true" 35 | os.environ[ 36 | "PATH" 37 | ] = "/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:" + os.environ.get("PATH", "") 38 | os.environ[ 39 | "LC_ALL" 40 | ] = "C" # stop invalid utf-8 throwing Python exception with gdb - still needed? 41 | 42 | if os.path.exists(gdb_driver_file): 43 | command = [ 44 | "gdb", 45 | "--nx", 46 | "--batch", 47 | "-ex", 48 | f"python exec(open('{gdb_driver_file}', encoding='utf-8', errors='replace').read())", 49 | os.environ["DCC_BINARY"], 50 | ] 51 | else: 52 | from embedded_source import embedded_source_drive_gdb_py 53 | 54 | command = [ 55 | "gdb", 56 | "--nx", 57 | "--batch", 58 | "-ex", 59 | 'python exec(r"""' + embedded_source_drive_gdb_py + '""")', 60 | os.environ["DCC_BINARY"], 61 | ] 62 | 63 | if debug_level > 1: 64 | print("running:", command) 65 | 66 | # gdb puts confusing messages on stderr & stdout so send these to /dev/null 67 | # and use file descriptor 3 for our messages 68 | os.dup2(2, 3) 69 | # pylint: disable=consider-using-with 70 | try: 71 | if debug_level > 1: 72 | p = subprocess.Popen(command, stdin=subprocess.DEVNULL, close_fds=False) 73 | else: 74 | p = subprocess.Popen( 75 | command, 76 | stdin=subprocess.DEVNULL, 77 | stdout=subprocess.DEVNULL, 78 | stderr=subprocess.DEVNULL, 79 | close_fds=False, 80 | ) 81 | p.communicate() 82 | except OSError: 83 | print( 84 | "\ngdb not available to print program location and variable values\n", 85 | file=sys.stderr, 86 | ) 87 | if debug_level > 1: 88 | print("kill_all()") 89 | kill_all() 90 | 91 | 92 | # 93 | # ensure the program compiled with dcc terminates after error 94 | # 95 | def kill_all(): 96 | kill_sanitizer2() 97 | kill_env("DCC_SANITIZER1_PID") 98 | kill_env("DCC_PID") 99 | sys.exit(1) 100 | 101 | 102 | def kill_sanitizer2(which_signal=None): 103 | unlink_sanitizer2_executable() 104 | kill_env("DCC_SANITIZER2_PID", which_signal=which_signal) 105 | 106 | 107 | def pause_sanitizer1(): 108 | kill_env("DCC_SANITIZER1_PID", which_signal=signal.SIGUSR1) 109 | 110 | 111 | def kill_env(environment_variable_name, which_signal=None): 112 | if environment_variable_name in os.environ: 113 | try: 114 | kill(int(os.environ[environment_variable_name]), which_signal=which_signal) 115 | except ValueError: 116 | pass 117 | 118 | 119 | def kill(pid, which_signal=None): 120 | # print('killing', pid) 121 | try: 122 | if which_signal is None: 123 | # in some circumstance SIGPIPE can avoid killed message 124 | # also allows cleanup of temporaries 125 | os.kill(pid, signal.SIGPIPE) 126 | # allow process hopefully enough time to handle SIGPIPE 127 | # then send SIGKILL to make sure process terminates 128 | time.sleep(0.25) 129 | os.kill(pid, signal.SIGKILL) 130 | else: 131 | os.kill(pid, which_signal) 132 | except ProcessLookupError: 133 | pass 134 | 135 | 136 | def unlink_sanitizer2_executable(): 137 | if "DCC_UNLINK" in os.environ: 138 | try: 139 | os.unlink(os.environ["DCC_UNLINK"]) 140 | except OSError: 141 | pass 142 | 143 | 144 | if __name__ == "__main__": 145 | start_gdb() 146 | -------------------------------------------------------------------------------- /run_time_python/util.py: -------------------------------------------------------------------------------- 1 | ../compile_time_python/util.py -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | actual_stderr 2 | a.out 3 | extracted_compile_time_errors 4 | -------------------------------------------------------------------------------- /tests/check_output/birds/bird-EOF-byte.c: -------------------------------------------------------------------------------- 1 | // A simple C program that prints an ASCII bird 2 | // Written 1/3/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | 5 | #include 6 | 7 | int main(void) { 8 | printf(" ___\n"); 9 | printf(" ('v')\n"); 10 | printf("((_%c_))\n", EOF); 11 | printf(" ^ +\n"); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /tests/check_output/birds/bird-extra-newline.c: -------------------------------------------------------------------------------- 1 | // A simple C program that prints an ASCII bird 2 | // Written 1/3/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | 5 | #include 6 | 7 | int main(void) { 8 | printf(" ___\n"); 9 | printf(" ('v')\n"); 10 | printf("((___))\n"); 11 | printf(" ^ ^\n\n"); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /tests/check_output/birds/bird-line-missing-1-byte.c: -------------------------------------------------------------------------------- 1 | // A simple C program that prints an ASCII bird 2 | // Written 1/3/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | 5 | #include 6 | 7 | int main(void) { 8 | printf(" ___\n"); 9 | printf(" ('v')\n"); 10 | printf("((___)\n"); 11 | printf(" ^ ^\n"); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /tests/check_output/birds/bird-line-too-long.c: -------------------------------------------------------------------------------- 1 | // A simple C program that prints an ASCII bird 2 | // Written 1/3/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | 5 | #include 6 | 7 | int main(void) { 8 | for (int i = 0; i < 100000; i++) { 9 | printf("____________________________________________________________"); 10 | } 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /tests/check_output/birds/bird-line-wrong.c: -------------------------------------------------------------------------------- 1 | // A simple C program that prints an ASCII bird 2 | // Written 1/3/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | 5 | #include 6 | 7 | int main(void) { 8 | printf(" ___\n"); 9 | printf(" ('v')\n"); 10 | printf("((_+_))\n"); 11 | printf(" ^ ^\n"); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /tests/check_output/birds/bird-missing-newline.c: -------------------------------------------------------------------------------- 1 | // A simple C program that prints an ASCII bird 2 | // Written 1/3/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | 5 | #include 6 | 7 | int main(void) { 8 | printf(" ___\n"); 9 | printf(" ('v')\n"); 10 | printf("((___))\n"); 11 | printf(" ^ ^"); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /tests/check_output/birds/bird-no-output.c: -------------------------------------------------------------------------------- 1 | // A simple C program that prints an ASCII bird 2 | // Written 1/3/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | 5 | #include 6 | 7 | int main(void) { 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /tests/check_output/birds/bird-truncated.c: -------------------------------------------------------------------------------- 1 | // A simple C program that prints an ASCII bird 2 | // Written 1/3/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | 5 | #include 6 | 7 | int main(void) { 8 | printf(" ___\n"); 9 | printf(" ('v')\n"); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /tests/check_output/birds/bird-zero-byte.c: -------------------------------------------------------------------------------- 1 | // A simple C program that prints an ASCII bird 2 | // Written 1/3/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | 5 | #include 6 | 7 | int main(void) { 8 | printf(" ___\n"); 9 | printf(" ('v')\n"); 10 | printf("((_%c_))\n", 0); 11 | printf(" ^ +\n"); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /tests/check_output/birds/bird.c: -------------------------------------------------------------------------------- 1 | // A simple C program that prints an ASCII bird 2 | // Written 1/3/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | 5 | #include 6 | 7 | int main(void) { 8 | printf(" ___\n"); 9 | printf(" ('v')\n"); 10 | printf("((___))\n"); 11 | printf(" ^ ^\n"); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /tests/check_output/check_birds.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | dcc=${dcc:$1} 3 | 4 | export DCC_EXPECTED_STDOUT=" ___ 5 | ('v') 6 | ((___)) 7 | ^ ^ 8 | " 9 | 10 | for bird in birds/bird-*.c 11 | do 12 | basename "$bird" 1>&2 13 | $dcc "$bird" 14 | ./a.out >/dev/null || continue 15 | echo "Test $bird failed" 1>&2 16 | exit 1 17 | done 18 | echo "All Tests Correct" 1>&2 19 | exit 0 -------------------------------------------------------------------------------- /tests/check_output/simple_check_output.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dcc=${dcc:-./dcc} 4 | 5 | cat >tmp.c < 7 | int main(int argc, char *argv[]) {printf("%s", argv[1]);return 0;} 8 | eof 9 | 10 | $dcc tmp.c || exit 11 | 12 | export DCC_EXPECTED_STDOUT=$'Hello!\n' 13 | 14 | function run_test { 15 | label="$1" 16 | environment_variables="$2" 17 | actual_output="$3" 18 | 19 | test_number=$((test_number + 1)) 20 | 21 | ( 22 | echo "*** Test $test_number - $label" 1>&2 23 | echo "*** Test Environment $environment_variables" 1>&2 24 | echo "expected output: $DCC_EXPECTED_STDOUT" 1>&2 25 | echo "actual output : $actual_output" 1>&2 26 | 27 | eval "$environment_variables"' ./a.out "$actual_output" >/dev/null' 28 | exit_status=$? 29 | 30 | case "$label" in 31 | *fail*) expected_result_status=1;; 32 | *) expected_result_status=0 33 | esac 34 | 35 | if (((exit_status != 0) != $expected_result_status)) 36 | then 37 | echo "*** Test failed ***" 1>&2 38 | exit 1 39 | fi 40 | ) || exit 1 41 | } 42 | 43 | run_test default-1 "" $'Hello!\n' 44 | 45 | run_test no-output-1-fail "" $'' 46 | run_test one-byte-missing-fail "" $'Hello\n' 47 | run_test two-bytes-missing-fail "" $'Hell\n' 48 | 49 | run_test trailing-white-space-1 "" $'Hello! \n' 50 | run_test trailing-white-space-2-fail "DCC_IGNORE_TRAILING_WHITE_SPACE=0" $'Hello! \n' 51 | 52 | run_test extra-new-line-1-fail "" $'Hello!\n\n' 53 | run_test extra-new-line-2 "DCC_IGNORE_EMPTY_LINES=1" $'Hello!\n\n' 54 | 55 | run_test missing-new-line-1-fail "" $'Hello!' 56 | 57 | run_test ignore-case-1-fail "" $'hEllo!\n' 58 | run_test ignore-case-2 "DCC_IGNORE_CASE=1" $'hEllo!\n' 59 | 60 | run_test ignore-white-space-1-fail "" $'H ello\t!\n' 61 | run_test ignore-white-space-2 "DCC_IGNORE_WHITE_SPACE=1" $'H ello\t!\n' 62 | 63 | run_test ignore-characters-1 "DCC_IGNORE_CHARACTERS=+" $'+++Hello!+++\n' 64 | run_test ignore-characters-2-fail "DCC_IGNORE_CHARACTERS=lzn" $'Hen\n' 65 | run_test ignore-characters-3 "DCC_IGNORE_CHARACTERS=lzno!" $'Hen\n' 66 | 67 | run_test compare-only-characters-1-fail "DCC_COMPARE_ONLY_CHARACTERS=Hel" $'HiheHilloHi\t!\n' 68 | run_test compare-only-characters-2 "DCC_COMPARE_ONLY_CHARACTERS=el" $'HiheHilloHi\t!\n' 69 | run_test compare-only-characters-3-fail "DCC_COMPARE_ONLY_CHARACTERS=hel" $'HiheHilloHi\t!\n' 70 | run_test compare-only-characters-4 "DCC_IGNORE_CASE=1 DCC_COMPARE_ONLY_CHARACTERS=hel" $'Hell\n' 71 | 72 | 73 | echo All Tests Correct 1>&2 74 | 75 | -------------------------------------------------------------------------------- /tests/compile_time_errors/array_static_illegal_index.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a[5]; 3 | a[5] = 0; 4 | } 5 | -------------------------------------------------------------------------------- /tests/compile_time_errors/array_string_index.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a[5]; 3 | a["0"] = 0; 4 | } 5 | -------------------------------------------------------------------------------- /tests/compile_time_errors/error_after_warning.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int b; 3 | int a; 4 | if (a = b) { 5 | } 6 | 7 | a = c; 8 | } 9 | -------------------------------------------------------------------------------- /tests/compile_time_errors/main_wrong_type.c: -------------------------------------------------------------------------------- 1 | int main(int argc, int argv[]) { 2 | } 3 | -------------------------------------------------------------------------------- /tests/compile_time_errors/no_main.c: -------------------------------------------------------------------------------- 1 | int man(int argc, char *argv[]) { 2 | } 3 | -------------------------------------------------------------------------------- /tests/compile_time_errors/printf_int_string_mismatch.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | printf("%d\n", "hello!"); 5 | } 6 | -------------------------------------------------------------------------------- /tests/compile_time_errors/relational_expression_with_comma.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char *argv[]) { 2 | if (argc < 1, argc < 2) { 3 | return 1; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/compile_time_errors/uninitialized_local_variable.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char *argv[]) { 2 | int s; 3 | if (argc > 3) { 4 | s = 1; 5 | } else if (argc < 2) { 6 | s = 2; 7 | } 8 | 9 | return s; 10 | } 11 | -------------------------------------------------------------------------------- /tests/compile_time_errors/unistd_compile_error.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void read(void) { 4 | printf("hello world\n"); 5 | } 6 | 7 | void read(void) { 8 | printf("hello world\n"); 9 | } 10 | 11 | int main(void) { 12 | read(); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compile_time_errors/variable_used_in_own_initialization.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = x + 1; 3 | } 4 | -------------------------------------------------------------------------------- /tests/do_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | unset CDPATH 3 | export PATH=/bin:/usr/bin:. 4 | 5 | for var in $(env|egrep -v 'PATH|LOCALE|LC_|LANG'|grep '^[a-zA-Z0-9_]*='|cut -d= -f1) 6 | do 7 | unset $var 8 | done 9 | 10 | export tests_dir="$(dirname $(readlink -f $0))" 11 | export dcc="$(readlink -f ${1:-"./dcc"})" 12 | export c_compiler="${2:-clang}" 13 | export cpp_compiler="${3:-clang++}" 14 | 15 | command -v "$dcc" > /dev/null || { 16 | echo "$0: error: $dcc not found" 17 | exit 1 18 | } 19 | 20 | e="$tests_dir/extracted_compile_time_errors" 21 | mkdir -p "$e" 22 | ( 23 | cd "$e" || exit 24 | rm -f *.c 25 | python3 ../../compile_time_python/compiler_explanations.py --create_test_files 26 | ) 27 | 28 | export clang_version=$($c_compiler -v 2>&1|sed 's/.* version *//;s/ .*//;1q'|cut -d. -f1,2) 29 | export platform=$($c_compiler -v 2>&1|sed '1d;s/.* //;2q') 30 | n_processes=$(($(getconf _NPROCESSORS_ONLN) / 2 + 1)) 31 | initial_run=$( 32 | { 33 | ls "$tests_dir"/run_time_errors/*.* 34 | ls "$tests_dir"/extracted_compile_time_errors/*.c 35 | ls "$tests_dir"/compile_time_errors/*.c 36 | ls "$tests_dir"/run_time_no_errors/*.* 37 | ls "$tests_dir"/check_output/*.sh 38 | }| 39 | grep -E '\.(sh|c|cpp)$'| 40 | shuf| 41 | xargs -P$n_processes -n1 "$tests_dir"/single_test.sh --quick| 42 | sort 43 | ) 44 | 45 | echo "$initial_run"|grep '^Passed'|sort 46 | 47 | second_run=$( 48 | echo "$initial_run"| 49 | grep -v '^Passed'| 50 | sed ' 51 | s/ *#.*$// 52 | s/ *$// 53 | s/.* // 54 | ' 55 | ) 56 | 57 | tests_failed=0 58 | for src_file in $second_run 59 | do 60 | "$tests_dir"/single_test.sh "$src_file" 61 | test_result="$?" 62 | test "$test_result" = 0 && 63 | continue 64 | test "$test_result" = 2 && 65 | break 66 | tests_failed=$((tests_failed + 1)) 67 | done 68 | echo $tests_failed tests failed 69 | -------------------------------------------------------------------------------- /tests/expected_output/array_static_illegal_index/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | array_static_illegal_index.c:3:5: warning: array index 5 is past the end of the array (which contains 5 elements) [-Warray-bounds] 2 | a[5] = 0; 3 | ^ ~ 4 | array_static_illegal_index.c:2:5: note: array 'a' declared here 5 | int a[5]; 6 | ^ 7 | dcc explanation: remember arrays indices start at zero. 8 | The valid array indices for an array of size n are 0..n-1. 9 | For example, for an array of size 10 you can use 0..9 as indices. 10 | -------------------------------------------------------------------------------- /tests/expected_output/array_static_illegal_index/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | array_static_illegal_index.c:3:5: warning: array index 5 is past the end of the array (that has type 'int[5]') [-Warray-bounds] 2 | a[5] = 0; 3 | ^ ~ 4 | array_static_illegal_index.c:2:5: note: array 'a' declared here 5 | int a[5]; 6 | ^ 7 | dcc explanation: remember arrays indices start at zero. 8 | The valid array indices for an array of size n are 0..n-1. 9 | For example, for an array of size 10 you can use 0..9 as indices. 10 | -------------------------------------------------------------------------------- /tests/expected_output/array_string_index/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | array_string_index.c:3:6: error: array subscript is not an integer 2 | a["0"] = 0; 3 | ^~~~ 4 | dcc explanation: you are using a string as an array index. An array index has to be an integer. 5 | -------------------------------------------------------------------------------- /tests/expected_output/array_subscript_is_not_an_integer/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | array_subscript_is_not_an_integer.c:3:13: error: array subscript is not an integer 2 | return a["0"]; 3 | ^~~~ 4 | dcc explanation: you are using a string as an array index. An array index has to be an integer. 5 | -------------------------------------------------------------------------------- /tests/expected_output/assert_without_closing_parenthesis/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | assert_without_closing_parenthesis.c:4:5: error: unterminated function-like macro invocation 2 | assert(argc == 1; 3 | ^ 4 | dcc explanation: it looks like there is a missing closing bracket on the assert on line 4 of assert_without_closing_parenthesis.c. 5 | -------------------------------------------------------------------------------- /tests/expected_output/assign_array_to_int/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | assign_array_to_int.c:4:13: warning: incompatible pointer to integer conversion assigning to 'int' from 'int[3]' [-Wint-conversion] 2 | a[0][0] = a[1]; 3 | ^ ~~~~ 4 | dcc explanation: you are attempting to assign a[1] which is an array to an int variable. 5 | -------------------------------------------------------------------------------- /tests/expected_output/assign_array_to_int/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | assign_array_to_int.c:4:13: error: incompatible pointer to integer conversion assigning to 'int' from 'int[3]' [-Wint-conversion] 2 | a[0][0] = a[1]; 3 | ^ ~~~~ 4 | dcc explanation: you are attempting to assign a[1] which is an array to an int variable. 5 | -------------------------------------------------------------------------------- /tests/expected_output/assign_function_to_int/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | assign_function_to_int.c:2:9: warning: incompatible pointer to integer conversion initializing 'int' with an expression of type 'int (int, char **)' [-Wint-conversion] 2 | int a = main; 3 | ^ ~~~~ 4 | dcc explanation: you are attempting to assign main which is a function to an int variable. 5 | Perhaps you are trying to call the function and have forgotten the round brackets and any parameter values. 6 | 7 | See more information here: https://comp1511unsw.github.io/dcc/assign_function_to_int.html 8 | -------------------------------------------------------------------------------- /tests/expected_output/assign_function_to_int/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | assign_function_to_int.c:2:9: error: incompatible pointer to integer conversion initializing 'int' with an expression of type 'int (int, char **)' [-Wint-conversion] 2 | int a = main; 3 | ^ ~~~~ 4 | dcc explanation: you are attempting to assign main which is a function to an int variable. 5 | Perhaps you are trying to call the function and have forgotten the round brackets and any parameter values. 6 | 7 | See more information here: https://comp1511unsw.github.io/dcc/assign_function_to_int.html 8 | -------------------------------------------------------------------------------- /tests/expected_output/assign_pointer_to_int/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | assign_pointer_to_int.c:4:7: warning: incompatible pointer to integer conversion assigning to 'int' from 'int *'; remove & [-Wint-conversion] 2 | a = &a; 3 | ^ ~~ 4 | dcc explanation: you are attempting to assign &a which is not an int to an int variable. 5 | -------------------------------------------------------------------------------- /tests/expected_output/assign_pointer_to_int/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | assign_pointer_to_int.c:4:7: error: incompatible pointer to integer conversion assigning to 'int' from 'int *'; remove & [-Wint-conversion] 2 | a = &a; 3 | ^ ~~ 4 | dcc explanation: you are attempting to assign &a which is not an int to an int variable. 5 | -------------------------------------------------------------------------------- /tests/expected_output/assign_to_array/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | assign_to_array.c:3:7: error: array type 'int[1]' is not assignable 2 | a = b; 3 | ~ ^ 4 | dcc explanation: you are trying to assign to 'a' which is an array with 1 element. 5 | You can not assign to a whole array. 6 | You can use a loop to assign to each array element individually. 7 | 8 | See more information here: https://comp1511unsw.github.io/dcc/assign_to_array.html 9 | -------------------------------------------------------------------------------- /tests/expected_output/assign_to_multidimensional_array/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | assign_to_multidimensional_array.c:3:7: error: array type 'int[3][1]' is not assignable 2 | a = b; 3 | ~ ^ 4 | dcc explanation: you are trying to assign to 'a' which is an array. 5 | You can not assign to a whole array. 6 | You can use a nested loop to assign to each array element individually. 7 | -------------------------------------------------------------------------------- /tests/expected_output/braces_before_error/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in braces_before_error.c at line 18: 5 | 6 | a[42] = 42; 7 | --> printf("%d\n", a[argc]); 8 | } 9 | 10 | Values when execution stopped: 11 | 12 | a = { , 42, } 13 | argc = 1 14 | a[42] = 42 15 | a[argc] = 16 | 17 | -------------------------------------------------------------------------------- /tests/expected_output/break_statement_not_in_loop/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | break_statement_not_in_loop.c:2:5: error: 'break' statement not in loop or switch statement 2 | break; 3 | ^ 4 | dcc explanation: break statements can only be used inside a while loop, for loop or switch. 5 | Check the braces {} are correct on nearby statements. 6 | -------------------------------------------------------------------------------- /tests/expected_output/call_stack_null/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a value via a NULL pointer 3 | dcc explanation: You are using a pointer which is NULL 4 | A common error is accessing *p or p[index] when p == NULL. 5 | 6 | Execution stopped in f3(a=NULL) in call_stack_null.c at line 5: 7 | 8 | int f3(int *a) { 9 | int b[] = { 0 }; 10 | --> return b[*a]; 11 | } 12 | 13 | Values when execution stopped: 14 | 15 | a = NULL 16 | b = {0} 17 | 18 | Function call traceback: 19 | 20 | f3(a=NULL) called at line 8 of call_stack_null.c 21 | f2(a=NULL) called at line 12 of call_stack_null.c 22 | f1(a=NULL) called at line 16 of call_stack_null.c 23 | main() 24 | 25 | -------------------------------------------------------------------------------- /tests/expected_output/call_stack_uninitialized/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a value via a uninitialized pointer 3 | dcc explanation: You are using a pointer which has not been initialized 4 | A common error is accessing *p without first assigning a value to p. 5 | 6 | Execution stopped in f3(a=) in call_stack_uninitialized.c at line 4: 7 | 8 | int f3(int *a) { 9 | --> return *a; 10 | } 11 | 12 | Values when execution stopped: 13 | 14 | a = 15 | 16 | Function call traceback: 17 | 18 | f3(a=) called at line 7 of call_stack_uninitialized.c 19 | f2(a=) called at line 11 of call_stack_uninitialized.c 20 | f1(a=) called at line 17 of call_stack_uninitialized.c 21 | main() 22 | 23 | -------------------------------------------------------------------------------- /tests/expected_output/check-o/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a field via a NULL pointer 3 | dcc explanation: You are using a pointer which is NULL 4 | A common error is using p->field when p == NULL. 5 | 6 | Execution stopped in main() in example2.c at line 13: 7 | 8 | int main(void) { 9 | struct node *new_node = malloc(sizeof(struct node)); 10 | new_node->next = NULL; 11 | struct node *current = new_node->next; 12 | --> printf("%d\n", current->value); 13 | return 0; 14 | } 15 | 16 | Values when execution stopped: 17 | 18 | current = NULL 19 | new_node->next = NULL 20 | 21 | -------------------------------------------------------------------------------- /tests/expected_output/check_birds/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | bird-EOF-byte.c 2 | 3 | Execution stopped because a non-ASCII byte was printed. 4 | Byte 4 of line 3 of program output was a non-ascii byte \xff 5 | Here is line 3 with non-printable characters replaced with backslash-escaped equivalents: 6 | ((_\xff_))\n 7 | 8 | Have you accidentally printed the special EOF value getchar returns? 9 | For more information go to: https://comp1511unsw.github.io/dcc/eof_byte.html 10 | 11 | Execution stopped in main() in /home/andrewt/w/dcc/src/tests/check_output/birds/bird-EOF-byte.c at line 10: 12 | 13 | int main(void) { 14 | printf(" ___\n"); 15 | printf(" ('v')\n"); 16 | --> printf("((_%c_))\n", EOF); 17 | printf(" ^ +\n"); 18 | return 0; 19 | } 20 | 21 | bird-extra-newline.c 22 | 23 | Execution stopped because of unexpected extra output. 24 | The program produced all the expected output and then produced extra output. 25 | The extra line was an empty line (a '\n'). 26 | 27 | Execution stopped in main() in /home/andrewt/w/dcc/src/tests/check_output/birds/bird-extra-newline.c at line 11: 28 | 29 | int main(void) { 30 | printf(" ___\n"); 31 | printf(" ('v')\n"); 32 | printf("((___))\n"); 33 | --> printf(" ^ ^\n\n"); 34 | return 0; 35 | } 36 | 37 | bird-line-missing-1-byte.c 38 | 39 | Execution stopped because of an incorrect output line. 40 | Byte 7 of line 3 of program output was incorrect. 41 | A ')' was missing from the end of the output line. 42 | The correct output line was: 43 | ((___)) 44 | Your program printed this line: 45 | ((___) 46 | 47 | Execution stopped in main() in /home/andrewt/w/dcc/src/tests/check_output/birds/bird-line-missing-1-byte.c at line 10: 48 | 49 | int main(void) { 50 | printf(" ___\n"); 51 | printf(" ('v')\n"); 52 | --> printf("((___)\n"); 53 | printf(" ^ ^\n"); 54 | return 0; 55 | } 56 | 57 | bird-line-too-long.c 58 | 59 | Execution failed because program wrote a line containing over 65536 bytes. 60 | Do you have an infinite loop? 61 | The start of the line was: 62 | ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ ... 63 | 64 | Execution stopped in main() in /home/andrewt/w/dcc/src/tests/check_output/birds/bird-line-too-long.c at line 9: 65 | 66 | int main(void) { 67 | for (int i = 0; i < 100000; i++) { 68 | --> printf("____________________________________________________________"); 69 | } 70 | return 0; 71 | } 72 | 73 | Values when execution stopped: 74 | 75 | i = 1228 76 | 77 | bird-line-wrong.c 78 | 79 | Execution stopped because of an incorrect output line. 80 | Byte 4 of line 3 of program output was incorrect. 81 | The correct output line was: 82 | ((___)) 83 | Your program printed this line: 84 | ((_+_)) 85 | 86 | Execution stopped in main() in /home/andrewt/w/dcc/src/tests/check_output/birds/bird-line-wrong.c at line 10: 87 | 88 | int main(void) { 89 | printf(" ___\n"); 90 | printf(" ('v')\n"); 91 | --> printf("((_+_))\n"); 92 | printf(" ^ ^\n"); 93 | return 0; 94 | } 95 | 96 | bird-missing-newline.c 97 | 98 | Execution failed because the last newline was missing. 99 | Your program produced all the expected output, except the last newline ('\n') was missing. 100 | 101 | For more information go to https://comp1511unsw.github.io/dcc/missing_newline.html 102 | 103 | 104 | bird-no-output.c 105 | 106 | Execution failed because program produced no output. 107 | 4 lines of output were expected 108 | The first expected line was: 109 | ___ 110 | 111 | 112 | bird-truncated.c 113 | 114 | Execution failed because of missing output lines. 115 | Your program printed 3 lines of correct output but stopped before printing all the expected output. 116 | The next expected line was: 117 | ((___)) 118 | 119 | 120 | bird-zero-byte.c 121 | 122 | Execution failed because a zero byte ('\0') was printed. 123 | Byte 3 of line 3 of program's output was a zero byte ('\0') 124 | Here are the characters on the line before the zero byte: 125 | ((_ 126 | 127 | For more information go to: https://comp1511unsw.github.io/dcc/zero_byte.html 128 | 129 | Execution stopped in main() in /home/andrewt/w/dcc/src/tests/check_output/birds/bird-zero-byte.c at line 10: 130 | 131 | int main(void) { 132 | printf(" ___\n"); 133 | printf(" ('v')\n"); 134 | --> printf("((_%c_))\n", 0); 135 | printf(" ^ +\n"); 136 | return 0; 137 | } 138 | 139 | All Tests Correct 140 | -------------------------------------------------------------------------------- /tests/expected_output/check_birds/000001-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | bird-EOF-byte.c 2 | 3 | Execution stopped because a non-ASCII byte was printed. 4 | Byte 4 of line 3 of program output was a non-ascii byte \xff 5 | Here is line 3 with non-printable characters replaced with backslash-escaped equivalents: 6 | ((_\xff_))\n 7 | 8 | Have you accidentally printed the special EOF value getchar returns? 9 | For more information go to: https://comp1511unsw.github.io/dcc/eof_byte.html 10 | 11 | Execution stopped in main() in birds/bird-EOF-byte.c at line 10: 12 | 13 | int main(void) { 14 | printf(" ___\n"); 15 | printf(" ('v')\n"); 16 | --> printf("((_%c_))\n", EOF); 17 | printf(" ^ +\n"); 18 | return 0; 19 | } 20 | 21 | bird-extra-newline.c 22 | 23 | Execution stopped because of unexpected extra output. 24 | The program produced all the expected output and then produced extra output. 25 | The extra line was an empty line (a '\n'). 26 | 27 | Execution stopped in main() in birds/bird-extra-newline.c at line 11: 28 | 29 | int main(void) { 30 | printf(" ___\n"); 31 | printf(" ('v')\n"); 32 | printf("((___))\n"); 33 | --> printf(" ^ ^\n\n"); 34 | return 0; 35 | } 36 | 37 | bird-line-missing-1-byte.c 38 | 39 | Execution stopped because of an incorrect output line. 40 | Byte 7 of line 3 of program output was incorrect. 41 | A ')' was missing from the end of the output line. 42 | The correct output line was: 43 | ((___)) 44 | Your program printed this line: 45 | ((___) 46 | 47 | Execution stopped in main() in birds/bird-line-missing-1-byte.c at line 10: 48 | 49 | int main(void) { 50 | printf(" ___\n"); 51 | printf(" ('v')\n"); 52 | --> printf("((___)\n"); 53 | printf(" ^ ^\n"); 54 | return 0; 55 | } 56 | 57 | bird-line-too-long.c 58 | 59 | Execution failed because program wrote a line containing over 65536 bytes. 60 | Do you have an infinite loop? 61 | The start of the line was: 62 | ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ ... 63 | 64 | Execution stopped in main() in birds/bird-line-too-long.c at line 9: 65 | 66 | int main(void) { 67 | for (int i = 0; i < 100000; i++) { 68 | --> printf("____________________________________________________________"); 69 | } 70 | return 0; 71 | } 72 | 73 | Values when execution stopped: 74 | 75 | i = 1228 76 | 77 | bird-line-wrong.c 78 | 79 | Execution stopped because of an incorrect output line. 80 | Byte 4 of line 3 of program output was incorrect. 81 | The correct output line was: 82 | ((___)) 83 | Your program printed this line: 84 | ((_+_)) 85 | 86 | Execution stopped in main() in birds/bird-line-wrong.c at line 10: 87 | 88 | int main(void) { 89 | printf(" ___\n"); 90 | printf(" ('v')\n"); 91 | --> printf("((_+_))\n"); 92 | printf(" ^ ^\n"); 93 | return 0; 94 | } 95 | 96 | bird-missing-newline.c 97 | 98 | Execution failed because the last newline was missing. 99 | Your program produced all the expected output, except the last newline ('\n') was missing. 100 | 101 | For more information go to https://comp1511unsw.github.io/dcc/missing_newline.html 102 | 103 | 104 | bird-no-output.c 105 | 106 | Execution failed because program produced no output. 107 | 4 lines of output were expected 108 | The first expected line was: 109 | ___ 110 | 111 | 112 | bird-truncated.c 113 | 114 | Execution failed because of missing output lines. 115 | Your program printed 3 lines of correct output but stopped before printing all the expected output. 116 | The next expected line was: 117 | ((___)) 118 | 119 | 120 | bird-zero-byte.c 121 | 122 | Execution failed because a zero byte ('\0') was printed. 123 | Byte 3 of line 3 of program's output was a zero byte ('\0') 124 | Here are the characters on the line before the zero byte: 125 | ((_ 126 | 127 | For more information go to: https://comp1511unsw.github.io/dcc/zero_byte.html 128 | 129 | Execution stopped in main() in birds/bird-zero-byte.c at line 10: 130 | 131 | int main(void) { 132 | printf(" ___\n"); 133 | printf(" ('v')\n"); 134 | --> printf("((_%c_))\n", 0); 135 | printf(" ^ +\n"); 136 | return 0; 137 | } 138 | 139 | All Tests Correct 140 | -------------------------------------------------------------------------------- /tests/expected_output/check_exit_status/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/check_exit_status/000000-clang-14.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/comparison_between_pointer_and_integer_char_and_int/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | comparison_between_pointer_and_integer_char_and_int.c:4:37: warning: comparison between pointer and integer ('char *' and 'int') [-Wpointer-integer-compare] 2 | return fgets(a, sizeof a, stdin) == EOF; 3 | ~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~ 4 | dcc explanation: fgets returns a pointer. Compare it to NULL to detect fgets being unable to read a line. 5 | -------------------------------------------------------------------------------- /tests/expected_output/condition_has_identical_branches/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | condition_has_identical_branches.c: In function ‘main’: 2 | condition_has_identical_branches.c:2:8: warning: this condition has identical branches [-Wduplicated-branches] 3 | 2 | if (argc == 1) 4 | | ^ 5 | dcc explanation: your if statement has identical then and else parts. 6 | It is pointless to have an if statement which executes the same code 7 | when its condition is true and also when its condition is false. 8 | -------------------------------------------------------------------------------- /tests/expected_output/const0/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: division by zero 3 | dcc explanation: A common error is to evaluate x / y when y == 0 which is undefined. 4 | 5 | Execution stopped in main() in const0.c at line 9: 6 | 7 | int main(int argc, char *argv[]) { 8 | int i = 0; 9 | const int j = 2; 10 | if (argc == 0) { 11 | i = 1; 12 | } 13 | --> printf("%d\n", j / i); 14 | } 15 | 16 | Values when execution stopped: 17 | 18 | argc = 1 19 | i = 0 20 | j = 2 21 | 22 | -------------------------------------------------------------------------------- /tests/expected_output/continue_statement_not_in_loop/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | continue_statement_not_in_loop.c:2:5: error: 'continue' statement not in loop statement 2 | continue; 3 | ^ 4 | dcc explanation: continue statements can only be used inside a while or for loop. 5 | Check the braces {} are correct on nearby statements. 6 | -------------------------------------------------------------------------------- /tests/expected_output/data_argument_not_used_by_format_string/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | data_argument_not_used_by_format_string.c:4:29: warning: data argument not used by format string [-Wformat-extra-args] 2 | printf("%d %d", 27, 28, 29); 3 | ~~~~~~~ ^ 4 | dcc explanation: you have more argument values than % codes in the format string. 5 | You need to change the format string or change the number of arguments. 6 | -------------------------------------------------------------------------------- /tests/expected_output/declaration_shadows_a_local_variable/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | declaration_shadows_a_local_variable.c:3:13: warning: declaration shadows a local variable [-Wshadow] 2 | int argc = 42; 3 | ^ 4 | declaration_shadows_a_local_variable.c:1:14: note: previous declaration is here 5 | int main(int argc, char *argv[]) { 6 | ^ 7 | dcc explanation: you already have a variable named 'argc'. 8 | It is confusing to have a second overlapping declaration of the same variable name. 9 | -------------------------------------------------------------------------------- /tests/expected_output/dereference_null_with_arrow/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a field via a NULL pointer 3 | dcc explanation: You are using a pointer which is NULL 4 | A common error is using p->field when p == NULL. 5 | 6 | Execution stopped in main() in dereference_null_with_arrow.c at line 8: 7 | 8 | int main(void) { 9 | struct list_node *a = NULL; 10 | --> a->data = 42; 11 | } 12 | 13 | Values when execution stopped: 14 | 15 | a = NULL 16 | 17 | -------------------------------------------------------------------------------- /tests/expected_output/dereference_null_with_arrow_arrow/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a field via a NULL pointer 3 | dcc explanation: You are using a pointer which is NULL 4 | A common error is using p->field when p == NULL. 5 | 6 | Execution stopped in main() in dereference_null_with_arrow_arrow.c at line 9: 7 | 8 | int main(void) { 9 | struct list_node s = { 0 }; 10 | struct list_node *a = &s; 11 | --> a->next->next->data = 42; 12 | } 13 | 14 | Values when execution stopped: 15 | 16 | a = &s 17 | s = {next = NULL, data = 0} 18 | a->next = NULL 19 | 20 | -------------------------------------------------------------------------------- /tests/expected_output/dereference_null_with_arrow_arrow_arrow/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a field via a NULL pointer 3 | dcc explanation: You are using a pointer which is NULL 4 | A common error is using p->field when p == NULL. 5 | 6 | Execution stopped in main() in dereference_null_with_arrow_arrow_arrow.c at line 10: 7 | 8 | int main(void) { 9 | struct list_node s1, s2 = { 0 }; 10 | struct list_node *a = &s1; 11 | s1.next = &s2; 12 | --> a->next->next->data = 42; 13 | } 14 | 15 | Values when execution stopped: 16 | 17 | a = &s1 18 | s1 = {next = &s2, data = } 19 | s2 = {next = NULL, data = 0} 20 | a->next = &s2 21 | s1.next = &s2 22 | a->next->next = NULL 23 | 24 | -------------------------------------------------------------------------------- /tests/expected_output/dereference_null_with_asterisk/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: assigning to a value via a NULL pointer 3 | dcc explanation: You are using a pointer which is NULL 4 | A common error is assigning to *p when p == NULL. 5 | 6 | Execution stopped in main() in dereference_null_with_asterisk.c at line 4: 7 | 8 | int main(void) { 9 | int *a = NULL; 10 | --> *a = 42; 11 | } 12 | 13 | Values when execution stopped: 14 | 15 | a = NULL 16 | 17 | -------------------------------------------------------------------------------- /tests/expected_output/dereference_null_with_index/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a value via a NULL pointer 3 | dcc explanation: You are using a pointer which is NULL 4 | A common error is accessing p[index] when p == NULL. 5 | 6 | Execution stopped in main() in dereference_null_with_index.c at line 4: 7 | 8 | int main(void) { 9 | int *a = NULL; 10 | --> return a[0]; 11 | } 12 | 13 | Values when execution stopped: 14 | 15 | a = NULL 16 | 17 | -------------------------------------------------------------------------------- /tests/expected_output/dereference_uninitialized_char_star_with_asterisk/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Execution stopped because of an invalid pointer or string. 3 | Execution stopped in main() in dereference_uninitialized_char_star_with_asterisk.c at line 5: 4 | 5 | int main(int argc, char **argv) { 6 | char **a = (char **)malloc(2 * sizeof *a); 7 | a[argc] = NULL; 8 | --> return **a; 9 | } 10 | 11 | Values when execution stopped: 12 | 13 | argc = 1 14 | a[argc] = NULL 15 | 16 | -------------------------------------------------------------------------------- /tests/expected_output/dereference_uninitialized_with_arrow/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a field via an uninitialized pointer 3 | dcc explanation: You are using a pointer which has not been initialized 4 | A common error is using p->field without first assigning a value to p. 5 | 6 | Execution stopped in main() in dereference_uninitialized_with_arrow.c at line 12: 7 | 8 | int main(int argc, char **argv) { 9 | struct list_node *a = (struct list_node *)malloc(2 * sizeof *a); 10 | if (argc != 1) { 11 | a->next = NULL; 12 | } 13 | --> a->next->data = 42; 14 | } 15 | 16 | Values when execution stopped: 17 | 18 | argc = 1 19 | a->next = 20 | 21 | -------------------------------------------------------------------------------- /tests/expected_output/dereference_uninitialized_with_arrow_arrow_arrow/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a field via an uninitialized pointer 3 | dcc explanation: You are using a pointer which has not been initialized 4 | A common error is using p->field without first assigning a value to p. 5 | 6 | Execution stopped in main() in dereference_uninitialized_with_arrow_arrow_arrow.c at line 10: 7 | 8 | int main(void) { 9 | struct list_node *a = (struct list_node *)malloc(sizeof *a); 10 | a->next = (struct list_node *)malloc(sizeof *a); 11 | --> a->next->next->data = 42; 12 | } 13 | 14 | Values when execution stopped: 15 | 16 | a->next->next = 17 | 18 | -------------------------------------------------------------------------------- /tests/expected_output/dereference_uninitialized_with_asterisk/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a value via a uninitialized pointer 3 | dcc explanation: You are using a pointer which has not been initialized 4 | A common error is accessing *p without first assigning a value to p. 5 | 6 | Execution stopped in main() in dereference_uninitialized_with_asterisk.c at line 5: 7 | 8 | int main(int argc, char **argv) { 9 | int **a = (int **)malloc(2 * sizeof *a); 10 | a[argc] = NULL; 11 | --> return **a; 12 | } 13 | 14 | Values when execution stopped: 15 | 16 | argc = 1 17 | a[argc] = NULL 18 | 19 | -------------------------------------------------------------------------------- /tests/expected_output/dereference_uninitialized_with_index/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: accessing a value via a uninitialized pointer 3 | dcc explanation: You are using a pointer which has not been initialized 4 | A common error is accessing p[index] without first assigning a value to p. 5 | 6 | Execution stopped in main() in dereference_uninitialized_with_index.c at line 5: 7 | 8 | int main(int argc, char *argv[]) { 9 | int **a = (int **)malloc(2 * sizeof *a); 10 | a[argc] = NULL; 11 | --> return a[0][0]; 12 | } 13 | 14 | Values when execution stopped: 15 | 16 | argc = 1 17 | a[argc] = NULL 18 | 19 | -------------------------------------------------------------------------------- /tests/expected_output/display_pointer_value0/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in g(p=main:&i, q=main:&j[1], r=f:&j[1], s=f:&i) in display_pointer_value0.c at line 4: 5 | 6 | void g(int *p, int *q, int *r, int *s) { 7 | --> printf("%d %d %d %d\n", *p, *q, *r, *s); 8 | } 9 | 10 | Values when execution stopped: 11 | 12 | p = main:&i 13 | q = main:&j[1] 14 | r = f:&j[1] 15 | s = f:&i 16 | 17 | Function call traceback: 18 | 19 | g(p=main:&i, q=main:&j[1], r=f:&j[1], s=f:&i) called at line 9 of display_pointer_value0.c 20 | f(i=1, p=main:&i, q=main:&j[1]) called at line 21 of display_pointer_value0.c 21 | main() 22 | 23 | -------------------------------------------------------------------------------- /tests/expected_output/display_pointer_value1/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in f(k=main:&j[0]) in display_pointer_value1.c at line 4: 5 | 6 | void f(int k[2][3]) { 7 | --> printf("%d\n", k[0][0]); 8 | } 9 | 10 | Values when execution stopped: 11 | 12 | k = main:&j[0] 13 | k[0][0] = 14 | 15 | Function call traceback: 16 | 17 | f(k=main:&j[0]) called at line 12 of display_pointer_value1.c 18 | main() 19 | 20 | -------------------------------------------------------------------------------- /tests/expected_output/double_free/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: double free 4 | dcc explanation: attempt to free memory that has already been freed. 5 | Execution stopped in main() in double_free.c at line 6: 6 | 7 | int main(void) { 8 | void *p = malloc(4); 9 | free(p); 10 | --> free(p); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tests/expected_output/double_free/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: double free 4 | dcc explanation: attempt to free memory that has already been freed. 5 | Execution stopped in main() in double_free.c at line 6: 6 | 7 | int main(void) { 8 | void *p = malloc(4); 9 | if (p) free(p); 10 | --> free(p); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tests/expected_output/double_int_literal_conversion/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | double_int_literal_conversion.c:2:13: warning: implicit conversion from 'double' to 'int' changes value from 6.7 to 6 [-Wliteral-conversion] 2 | int i = 6.7; 3 | ~ ^~~ 4 | dcc explanation: you are assigning the floating point number 6.7 to the int variable i , if this is what you want, change 6.7 to 6 5 | -------------------------------------------------------------------------------- /tests/expected_output/duplicated-cond/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | duplicated-cond.c: In function ‘main’: 2 | duplicated-cond.c:4:19: warning: duplicated ‘if’ condition [-Wduplicated-cond] 3 | 4 | else if (argc == 1) 4 | | ~~~~~^~~~ 5 | duplicated-cond.c:2:14: note: previously used here 6 | 2 | if (argc == 1) 7 | | ~~~~~^~~~ 8 | dcc explanation: you have repeated the same condition in a chain of if statements. 9 | Only the first if statement using the condition can be executed. 10 | The others can never be executed. 11 | -------------------------------------------------------------------------------- /tests/expected_output/empty_main--leak-check/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/empty_main--leak-check/000000-clang-14.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/empty_main-fsanitize=address/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/empty_main-fsanitize=address/000000-clang-14.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/empty_main/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/empty_main/000000-clang-14.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/enum0/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: division by zero 3 | dcc explanation: A common error is to evaluate x / y when y == 0 which is undefined. 4 | 5 | Execution stopped in main() in enum0.c at line 10: 6 | 7 | int main(int argc, char *argv[]) { 8 | enum a i = A; 9 | if (argc == 0) { 10 | i = B; 11 | } 12 | --> printf("%d\n", 2 / i); 13 | } 14 | 15 | Values when execution stopped: 16 | 17 | argc = 1 18 | i = A 19 | 20 | -------------------------------------------------------------------------------- /tests/expected_output/error_after_warning/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | error_after_warning.c:4:11: warning: using the result of an assignment as a condition without parentheses [-Wparentheses] 2 | if (a = b) { 3 | ~~^~~ 4 | error_after_warning.c:4:11: note: place parentheses around the assignment to silence this warning 5 | if (a = b) { 6 | ^ 7 | ( ) 8 | error_after_warning.c:4:11: note: use '==' to turn this assignment into an equality comparison 9 | if (a = b) { 10 | ^ 11 | == 12 | dcc explanation: you use '=' to assign to a variable, you use '==' to compare values. 13 | error_after_warning.c:7:9: error: use of undeclared identifier 'c' 14 | a = c; 15 | ^ 16 | dcc explanation: you have used the name 'c' on line 7 of error_after_warning.c without previously declaring it. 17 | If you meant to use 'c' as a variable, check you have declared it by specifying its type 18 | Also check you have spelled 'c' correctly everywhere. 19 | -------------------------------------------------------------------------------- /tests/expected_output/expected_in_for_statement_specifier/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | expected_in_for_statement_specifier.c:2:28: error: expected ';' in 'for' statement specifier 2 | for (int i = 0; i < 10 i++) { 3 | ^ 4 | dcc explanation: the three parts of a ';' statment should be separated with ';' 5 | -------------------------------------------------------------------------------- /tests/expected_output/expression_is_not_assignable/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | expression_is_not_assignable.c:2:26: error: expression is not assignable 2 | if (argc = 1 || argc = 2) { 3 | ~~~~~~~~~ ^ 4 | dcc explanation: you are using = incorrectly perhaps you meant ==. 5 | Reminder: you use = to assign to a variable. 6 | You use == to compare values. 7 | 8 | -------------------------------------------------------------------------------- /tests/expected_output/expression_result_unused/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | expression_result_unused.c:2:5: warning: expression result unused [-Wunused-value] 2 | argc; 3 | ^~~~ 4 | dcc explanation: you are doing nothing with a value on line 2 of expression_result_unused.c. 5 | Did you mean to assign it to a varable? 6 | -------------------------------------------------------------------------------- /tests/expected_output/extra_tokens_at_end_of_include_directive/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | extra_tokens_at_end_of_include_directive.c:1:19: warning: extra tokens at end of #include directive [-Wextra-tokens] 2 | #include @ 3 | ^ 4 | // 5 | dcc explanation: you have unnecessary characters on your #include statement. 6 | -------------------------------------------------------------------------------- /tests/expected_output/fclose/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | for (int i = 0; i < 50000; i++) { 5 | fclose(fopen(__FILE__, "r")); 6 | } 7 | FILE *f = fopen(__FILE__, "r"); 8 | int c; 9 | while ((c = fgetc(f)) != EOF) { 10 | putchar(c); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/expected_output/fdopen-fsanitize=address,valgrind/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | //dcc_flags=-fsanitize=address,valgrind 2 | #include 3 | 4 | int main(void) { 5 | extern int open(const char *pathname, int flags); 6 | FILE *f = fdopen(open(__FILE__, 0), "r"); 7 | int c; 8 | while ((c = fgetc(f)) != EOF) { 9 | putchar(c); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/expected_output/fgetc_NULL/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Execution stopped because of an invalid pointer or string. 3 | Execution stopped in main() in fgetc_NULL.c at line 5: 4 | 5 | int main(void) { 6 | FILE *f = NULL; 7 | --> fgetc(f); 8 | } 9 | 10 | Values when execution stopped: 11 | 12 | f = NULL 13 | 14 | -------------------------------------------------------------------------------- /tests/expected_output/fgetc_NULL/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | fgetc_NULL.c: In function ‘main’: 2 | fgetc_NULL.c:5:5: warning: argument 1 null where non-null expected [-Wnonnull] 3 | 5 | fgetc(f); 4 | | ^~~~~~~~ 5 | dcc explanation: you are passing the variable f which always contains NULL as argument 1 to 'fgetc'. 6 | Argument 1 to 'fgetc' should never be NULL. 7 | In file included from fgetc_NULL.c:1: 8 | /usr/include/stdio.h:575:12: note: in a call to function ‘fgetc’ declared ‘nonnull’ 9 | 575 | extern int fgetc (FILE *__stream) __nonnull ((1)); 10 | | ^~~~~ 11 | -------------------------------------------------------------------------------- /tests/expected_output/fgetc_after_close/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: invalid memory access 3 | A common cause of this error is use of an invalid FILE * pointer. 4 | 5 | 6 | Execution stopped in main() in fgetc_after_close.c at line 5: 7 | 8 | int main(void) { 9 | fclose(stdin); 10 | --> fgetc(stdin); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tests/expected_output/fgetc_uninitialized/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Execution stopped because of an invalid pointer or string. 3 | Execution stopped in main() in fgetc_uninitialized.c at line 6: 4 | 5 | int main(int argc, char *argv[]) { 6 | FILE *f[2]; 7 | f[0] = NULL; 8 | --> fgetc(f[argc]); 9 | } 10 | 11 | Values when execution stopped: 12 | 13 | argc = 1 14 | f = {NULL, } 15 | f[0] = NULL 16 | f[argc] = 17 | 18 | -------------------------------------------------------------------------------- /tests/expected_output/fileno/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/fileno/000000-clang-14.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/fopen/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | FILE *f = fopen(__FILE__, "r"); 5 | int c; 6 | while ((c = fgetc(f)) != EOF) { 7 | putchar(c); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/expected_output/format_type_mismatch/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | format_type_mismatch.c:4:18: warning: format specifies type 'int' but the argument has type 'char *' [-Wformat] 2 | printf("%d", "hello!"); 3 | ~~ ^~~~~~~~ 4 | %s 5 | dcc explanation: make sure you are using the correct format code (e.g., `%d` for integers, `%lf` for floating-point values) in your format string on line 4 of format_type_mismatch.c. 6 | -------------------------------------------------------------------------------- /tests/expected_output/freopen/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | freopen(__FILE__, "r", stdin); 5 | int c; 6 | while ((c = getchar()) != EOF) { 7 | putchar(c); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/expected_output/function-variable-clash/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | function-variable-clash.c:3:16: error: called object type 'int' is not a function or function pointer 2 | return main(); 3 | ~~~~^ 4 | dcc explanation: 'main' is the name of a variable but you are trying to call it as a function. 5 | If 'main' is also the name of a function, you can avoid the clash, 6 | by changing the name of the variable 'main' to something else. 7 | See more information here: https://comp1511unsw.github.io/dcc/function-variable-clash.html 8 | -------------------------------------------------------------------------------- /tests/expected_output/function_definition_is_not_allowed_here/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | function_definition_is_not_allowed_here.c:4:16: error: function definition is not allowed here 2 | int main(void) { 3 | ^ 4 | dcc explanation: there is likely a closing brace (curly bracket) missing before line 4 of function_definition_is_not_allowed_here.c. 5 | Is a } missing in the previous function? 6 | See more information here: https://comp1511unsw.github.io/dcc/function_definition_is_not_allowed_here.html 7 | -------------------------------------------------------------------------------- /tests/expected_output/h_file_not_found/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | h_file_not_found.c:1:10: fatal error: 'studio.h' file not found 2 | #include 3 | ^~~~~~~~~~ 4 | dcc explanation: you are attempting to #include a file which does not exist. 5 | Did you mean: '#include ' 6 | -------------------------------------------------------------------------------- /tests/expected_output/has_empty_body/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | has_empty_body.c:2:14: warning: if statement has empty body [-Wempty-body] 2 | if (argc); { 3 | ^ 4 | has_empty_body.c:2:14: note: put the semicolon on a separate line to silence this warning 5 | dcc explanation: you may have an extra ';' that you should remove. 6 | -------------------------------------------------------------------------------- /tests/expected_output/hash_define/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: index 1000 out of bounds for type 'int[1000]' 3 | dcc explanation: You are using an illegal array index: 1000 4 | Valid indices for an array of size 1000 are 0..999 5 | Make sure the size of your array is correct. 6 | Make sure your array indices are correct. 7 | 8 | Execution stopped in main() in hash_define.c at line 10: 9 | 10 | int main(int argc, char **argv) { 11 | int a[ARRAY_SIZE]; 12 | int i; 13 | 14 | for (i = 0; i < ARRAY_SIZE; i++) { 15 | --> a[i + argc] = i + argc; 16 | } 17 | return a[0]; 18 | } 19 | 20 | Values when execution stopped: 21 | 22 | a = {, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, ...} 23 | argc = 1 24 | i = 999 25 | i + argc = 1000 26 | a[i + argc] = 27 | 28 | -------------------------------------------------------------------------------- /tests/expected_output/ignoring_return_value_of_function/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ignoring_return_value_of_function.c:3:5: warning: ignoring return value of function declared with pure attribute [-Wunused-value] 2 | atoi(argv[0]); 3 | ^~~~ ~~~~~~~ 4 | dcc explanation: you are not using the value returned by function atoi . 5 | Did you mean to assign it to a variable? 6 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_2d_array_access.cpp/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: stack buffer overflow 4 | dcc explanation: access past the end of a local variable. 5 | Make sure the size of your array is correct. 6 | Make sure your array indices are correct. 7 | Execution stopped in twod(b=main:&a[0]) in illegal_2d_array_access.cpp at line 4: 8 | 9 | void twod(int b[5][4]) { 10 | --> std::cout << b[5][2] << "\n"; 11 | } 12 | 13 | Values when execution stopped: 14 | 15 | b = main:&a[0] 16 | b[5][2] = 17 | 18 | Function call traceback: 19 | 20 | twod(b=main:&a[0]) called at line 9 of illegal_2d_array_access.cpp 21 | main() 22 | 23 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_2d_array_access/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: stack buffer overflow 4 | dcc explanation: access past the end of a local variable. 5 | Make sure the size of your array is correct. 6 | Make sure your array indices are correct. 7 | Execution stopped in twod(b=main:&a[0]) in illegal_2d_array_access.c at line 4: 8 | 9 | void twod(int b[5][4]) { 10 | --> printf("%d\n", b[5][2]); 11 | } 12 | 13 | Values when execution stopped: 14 | 15 | b = main:&a[0] 16 | b[5][2] = 17 | 18 | Function call traceback: 19 | 20 | twod(b=main:&a[0]) called at line 9 of illegal_2d_array_access.c 21 | main() 22 | 23 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_argv_index.cpp/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Execution stopped because of an invalid pointer or string. 3 | Execution stopped in main() in illegal_argv_index.cpp at line 4: 4 | 5 | int main(int argc, char **argv) { 6 | --> std::cout << argv[-1] << "\n"; 7 | } 8 | 9 | Values when execution stopped: 10 | 11 | argc = 1 12 | argv[-1] = 0x1 13 | 14 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_argv_index/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Execution stopped because of an invalid pointer or string. 3 | Execution stopped in main() in illegal_argv_index.c at line 4: 4 | 5 | int main(int argc, char **argv) { 6 | --> printf("%s\n", argv[-1]); 7 | } 8 | 9 | Values when execution stopped: 10 | 11 | argc = 1 12 | argv[-1] = 0x1 13 | 14 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_malloc_array_index--ifdef-main/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: malloc buffer overflow 4 | dcc explanation: access past the end of malloc'ed memory. 5 | Make sure you have allocated enough memory for the size of your struct/array. 6 | A common error is to use the size of a pointer instead of the size of the struct or array. 7 | 8 | For more information see: https://comp1511unsw.github.io/dcc/malloc_sizeof.html 9 | 10 | Execution stopped in main() in illegal_malloc_array_index.c at line 9: 11 | 12 | int main(int argc, char **argv) { 13 | int *a = (int *)malloc(1000 * sizeof(int)); 14 | --> a[999 + argc] = 42; 15 | return 0; 16 | } 17 | 18 | Values when execution stopped: 19 | 20 | argc = 1 21 | 999 + argc = 1000 22 | a[999 + argc] = 0 23 | 24 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_malloc_array_index-fsanitize=address/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: malloc buffer overflow 4 | dcc explanation: access past the end of malloc'ed memory. 5 | Make sure you have allocated enough memory for the size of your struct/array. 6 | A common error is to use the size of a pointer instead of the size of the struct or array. 7 | 8 | For more information see: https://comp1511unsw.github.io/dcc/malloc_sizeof.html 9 | 10 | Execution stopped in main() in illegal_malloc_array_index.c at line 9: 11 | 12 | int main(int argc, char **argv) { 13 | int *a = (int *)malloc(1000 * sizeof(int)); 14 | --> a[999 + argc] = 42; 15 | return 0; 16 | } 17 | 18 | Values when execution stopped: 19 | 20 | argc = 1 21 | 999 + argc = 1000 22 | a[999 + argc] = 0 23 | 24 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_malloc_array_index/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: malloc buffer overflow 4 | dcc explanation: access past the end of malloc'ed memory. 5 | Make sure you have allocated enough memory for the size of your struct/array. 6 | A common error is to use the size of a pointer instead of the size of the struct or array. 7 | 8 | For more information see: https://comp1511unsw.github.io/dcc/malloc_sizeof.html 9 | 10 | Execution stopped in main() in illegal_malloc_array_index.c at line 9: 11 | 12 | int main(int argc, char **argv) { 13 | int *a = (int *)malloc(1000 * sizeof(int)); 14 | --> a[999 + argc] = 42; 15 | return 0; 16 | } 17 | 18 | Values when execution stopped: 19 | 20 | argc = 1 21 | 999 + argc = 1000 22 | a[999 + argc] = 0 23 | 24 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_malloc_array_index_uninitialized--ifdef-main/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: malloc buffer overflow 4 | dcc explanation: access past the end of malloc'ed memory. 5 | Make sure you have allocated enough memory for the size of your struct/array. 6 | A common error is to use the size of a pointer instead of the size of the struct or array. 7 | 8 | For more information see: https://comp1511unsw.github.io/dcc/malloc_sizeof.html 9 | 10 | Execution stopped in main() in illegal_malloc_array_index_uninitialized.c at line 10: 11 | 12 | int main(int argc, char **argv) { 13 | int *a = (int *)malloc(1000 * sizeof(int)); 14 | --> a[999 + argc] = 42; 15 | printf("%d\n", a[0]); 16 | } 17 | 18 | Values when execution stopped: 19 | 20 | argc = 1 21 | 999 + argc = 1000 22 | a[0] = 23 | a[999 + argc] = 0 24 | 25 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_malloc_array_index_uninitialized-fsanitize=address/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: malloc buffer overflow 4 | dcc explanation: access past the end of malloc'ed memory. 5 | Make sure you have allocated enough memory for the size of your struct/array. 6 | A common error is to use the size of a pointer instead of the size of the struct or array. 7 | 8 | For more information see: https://comp1511unsw.github.io/dcc/malloc_sizeof.html 9 | 10 | Execution stopped in main() in illegal_malloc_array_index_uninitialized.c at line 10: 11 | 12 | int main(int argc, char **argv) { 13 | int *a = (int *)malloc(1000 * sizeof(int)); 14 | --> a[999 + argc] = 42; 15 | printf("%d\n", a[0]); 16 | } 17 | 18 | Values when execution stopped: 19 | 20 | argc = 1 21 | 999 + argc = 1000 22 | a[0] = 23 | a[999 + argc] = 0 24 | 25 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_malloc_array_index_uninitialized/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: malloc buffer overflow 4 | dcc explanation: access past the end of malloc'ed memory. 5 | Make sure you have allocated enough memory for the size of your struct/array. 6 | A common error is to use the size of a pointer instead of the size of the struct or array. 7 | 8 | For more information see: https://comp1511unsw.github.io/dcc/malloc_sizeof.html 9 | 10 | Execution stopped in main() in illegal_malloc_array_index_uninitialized.c at line 10: 11 | 12 | int main(int argc, char **argv) { 13 | int *a = (int *)malloc(1000 * sizeof(int)); 14 | --> a[999 + argc] = 42; 15 | printf("%d\n", a[0]); 16 | } 17 | 18 | Values when execution stopped: 19 | 20 | argc = 1 21 | 999 + argc = 1000 22 | a[0] = 23 | a[999 + argc] = 0 24 | 25 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_nested_array_assignment/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: index 4 out of bounds for type 'int[4]' 3 | dcc explanation: You are using an illegal array index: 4 4 | Valid indices for an array of size 4 are 0..3 5 | Make sure the size of your array is correct. 6 | Make sure your array indices are correct. 7 | 8 | Execution stopped in main() in illegal_nested_array_assignment.c at line 3: 9 | 10 | int main(int argc, char **argv) { 11 | int a[] = { 1, 2, 3, 4 }; 12 | --> a[a[a[a[a[0]]]]] = 1; 13 | } 14 | 15 | Values when execution stopped: 16 | 17 | a = {1, 2, 3, 4} 18 | argc = 1 19 | a[0] = 1 20 | a[a[0]] = 2 21 | a[a[a[0]]] = 3 22 | a[a[a[a[0]]]] = 4 23 | a[a[a[a[a[0]]]]] = 24 | 25 | -------------------------------------------------------------------------------- /tests/expected_output/illegal_vla_index/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: index 1000 out of bounds for type 'int[600 + argc]' 3 | dcc explanation: You are using an illegal array index: 1000 4 | Make sure the size of your array is correct. 5 | Make sure your array indices are correct. 6 | 7 | Execution stopped in main() in illegal_vla_index.c at line 3: 8 | 9 | int main(int argc, char **argv) { 10 | int a[600 + argc]; 11 | --> a[1000] = argc; 12 | return a[1000]; 13 | } 14 | 15 | Values when execution stopped: 16 | 17 | a = { } 18 | argc = 1 19 | a[1000] = 0 20 | 21 | -------------------------------------------------------------------------------- /tests/expected_output/implicit_function_declaration/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | implicit_function_declaration.c:2:5: warning: implicit declaration of function 'f' is invalid in C99 [-Wimplicit-function-declaration] 2 | f(); 3 | ^ 4 | dcc explanation: you are calling a function named f line 2 of implicit_function_declaration.c but dcc does not recognize f as a function. 5 | There are several possible causes: 6 | a) You might have misspelt the function name. 7 | b) You might need to add a #include line at the top of implicit_function_declaration.c. 8 | c) You might need to add a prototype for f. 9 | -------------------------------------------------------------------------------- /tests/expected_output/implicit_function_declaration/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | implicit_function_declaration.c:2:5: error: call to undeclared function 'f'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 2 | f(); 3 | ^ 4 | dcc explanation: you are calling a function named f line 2 of implicit_function_declaration.c but dcc does not recognize f as a function. 5 | There are several possible causes: 6 | a) You might have misspelt the function name. 7 | b) You might need to add a #include line at the top of implicit_function_declaration.c. 8 | c) You might need to add a prototype for f. 9 | -------------------------------------------------------------------------------- /tests/expected_output/incremental_compilation/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | /home/andrewt/w/dcc/src/tests/single_test.sh: ./incremental_compilation.sh: /: bad interpreter: Permission denied 2 | -------------------------------------------------------------------------------- /tests/expected_output/indexing_one_too_far/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | indexing_one_too_far.c:3:12: warning: array index 42 is past the end of the array (which contains 42 elements) [-Warray-bounds] 2 | return a[42]; 3 | ^ ~~ 4 | indexing_one_too_far.c:2:5: note: array 'a' declared here 5 | int a[42] = { 0 }; 6 | ^ 7 | dcc explanation: remember arrays indices start at zero. 8 | The valid array indices for an array of size n are 0..n-1. 9 | For example, for an array of size 10 you can use 0..9 as indices. 10 | -------------------------------------------------------------------------------- /tests/expected_output/indexing_one_too_far/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | indexing_one_too_far.c:3:12: warning: array index 42 is past the end of the array (that has type 'int[42]') [-Warray-bounds] 2 | return a[42]; 3 | ^ ~~ 4 | indexing_one_too_far.c:2:5: note: array 'a' declared here 5 | int a[42] = { 0 }; 6 | ^ 7 | dcc explanation: remember arrays indices start at zero. 8 | The valid array indices for an array of size n are 0..n-1. 9 | For example, for an array of size 10 you can use 0..9 as indices. 10 | -------------------------------------------------------------------------------- /tests/expected_output/indirection-requires-pointer-operand/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | indirection-requires-pointer-operand.c:2:12: error: indirection requires pointer operand ('int' invalid) 2 | return *argc; 3 | ^~~~~ 4 | dcc explanation: you are trying to use 'argc' as a pointer. 5 | You can not do this because 'argc' is of type int. 6 | -------------------------------------------------------------------------------- /tests/expected_output/int_overflow/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int' 3 | dcc explanation: There are limits in the range of values that can be represented in all types. 4 | Your program has produced a value outside that range. 5 | 6 | Execution stopped in main() in int_overflow.c at line 5: 7 | 8 | int main(int argc, char **argv) { 9 | int k = INT_MAX; 10 | --> k += argc; 11 | } 12 | 13 | Values when execution stopped: 14 | 15 | argc = 1 16 | k = 2147483647 17 | 18 | -------------------------------------------------------------------------------- /tests/expected_output/invalid_equal_equal_at_end_of_declaration/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | invalid_equal_equal_at_end_of_declaration.c:2:11: error: invalid '==' at end of declaration; did you mean '='? 2 | int i == 0; 3 | ^~ 4 | = 5 | dcc explanation: remember '=' is used to assign a value to a variable, '==' is used to compare values, 6 | -------------------------------------------------------------------------------- /tests/expected_output/invalid_preprocessing_directive/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | invalid_preprocessing_directive.c:1:2: error: invalid preprocessing directive 2 | #inclde 3 | ^ 4 | dcc explanation: you have an invalid line begining with '#'. 5 | Did you mean #include or #define ? 6 | -------------------------------------------------------------------------------- /tests/expected_output/is_uninitialized_when_used_here/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | is_uninitialized_when_used_here.c:2:9: warning: unused variable 'x' [-Wunused-variable] 2 | int x; 3 | ^ 4 | -------------------------------------------------------------------------------- /tests/expected_output/is_uninitialized_when_used_within_its_own_initialization/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | is_uninitialized_when_used_within_its_own_initialization.c:2:9: warning: unused variable 'x' [-Wunused-variable] 2 | int x; 3 | ^ 4 | -------------------------------------------------------------------------------- /tests/expected_output/leak_simple--leak-check/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Error: free not called for memory allocated with malloc in function main in leak_simple.c at line 6. 3 | -------------------------------------------------------------------------------- /tests/expected_output/leak_then_exit--leak-check/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Error: free not called for memory allocated with malloc in function main in leak_then_exit.c at line 6. 3 | -------------------------------------------------------------------------------- /tests/expected_output/leak_valgrind--leak-check/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Error: free not called for memory allocated with malloc in function main in leak_valgrind.c at line 6. 3 | -------------------------------------------------------------------------------- /tests/expected_output/logical-and-always-false/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | logical-and-always-false.c:3:18: warning: overlapping comparisons always evaluate to false [-Wtautological-overlap-compare] 2 | if (argc > 1 && argc < 1) 3 | ~~~~~~~~~^~~~~~~~~~~ 4 | dcc explanation: Your '&&' expression is always false, no matter what value variables have. 5 | Perhaps you meant to use '||' ? 6 | -------------------------------------------------------------------------------- /tests/expected_output/logical-equal-expressions/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | logical-equal-expressions.c: In function ‘main’: 2 | logical-equal-expressions.c:2:18: warning: logical ‘or’ of equal expressions [-Wlogical-op] 3 | 2 | if (argc > 1 ||argc > 1) 4 | | ^~ 5 | dcc explanation: you have used '||' with same lefthand and righthand operands. 6 | If this what you meant, it can be simplified: x || x can be replaced with just x. 7 | -------------------------------------------------------------------------------- /tests/expected_output/logical-or-always-true/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | logical-or-always-true.c:3:18: warning: overlapping comparisons always evaluate to true [-Wtautological-overlap-compare] 2 | if (argc > 1 || argc < 3) 3 | ~~~~~~~~~^~~~~~~~~~~ 4 | dcc explanation: Your '||' expression is always true, no matter what value variables have. 5 | Perhaps you meant to use '&&' ? 6 | -------------------------------------------------------------------------------- /tests/expected_output/main_wrong_type/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | main_wrong_type.c:1:5: error: second parameter of 'main' (argument array) must be of type 'char **' 2 | int main(int argc, int argv[]) { 3 | ^ 4 | dcc explanation: your declaration of 'main' is incorrect. 5 | Try either 'int main(void)' or 'int main(int argc, char *argv[])' 6 | -------------------------------------------------------------------------------- /tests/expected_output/missing_function_return_type/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | missing_function_return_type.c:1:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int] 2 | square (int x) { 3 | ^ 4 | dcc explanation: have you given a return type for square? 5 | You must specify the return type of a function just before its name. 6 | -------------------------------------------------------------------------------- /tests/expected_output/missing_function_return_type/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | missing_function_return_type.c:1:1: error: type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int] 2 | square (int x) { 3 | ^ 4 | int 5 | dcc explanation: have you given a return type for square? 6 | You must specify the return type of a function just before its name. 7 | -------------------------------------------------------------------------------- /tests/expected_output/missing_library_include/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | missing_library_include.c:2:5: warning: implicitly declaring library function 'printf' with type 'int (const char *, ...)' [-Wimplicit-function-declaration] 2 | printf("hello"); 3 | ^ 4 | dcc explanation: you are calling printf on line 2 of missing_library_include.c but 5 | dcc does not recognize printf as a function. 6 | Do you have #include at the top of your file? 7 | -------------------------------------------------------------------------------- /tests/expected_output/missing_library_include/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | missing_library_include.c:2:5: error: call to undeclared library function 'printf' with type 'int (const char *, ...)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 2 | printf("hello"); 3 | ^ 4 | dcc explanation: you are calling printf on line 2 of missing_library_include.c but 5 | dcc does not recognize printf as a function. 6 | Do you have #include at the top of your file? 7 | -------------------------------------------------------------------------------- /tests/expected_output/missing_parameter_type/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | missing_parameter_type.c:1:16: warning: type specifier missing, defaults to 'int' [-Wimplicit-int] 2 | int add(int b, c) { 3 | ^ 4 | dcc explanation: have you given a type for c? 5 | You must specify the type of each function parameter. 6 | -------------------------------------------------------------------------------- /tests/expected_output/missing_parameter_type/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | missing_parameter_type.c:1:16: error: type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int] 2 | int add(int b, c) { 3 | ^ 4 | int 5 | dcc explanation: have you given a type for c? 6 | You must specify the type of each function parameter. 7 | -------------------------------------------------------------------------------- /tests/expected_output/missing_semicolon_line_before_assert/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | missing_semicolon_line_before_assert.c:5:5: error: called object type 'int' is not a function or function pointer 2 | assert(i == 10); 3 | ^ 4 | /usr/include/assert.h:108:3: note: expanded from macro 'assert' 5 | ((void) sizeof ((expr) ? 1 : 0), __extension__ ({ \ 6 | ^ 7 | dcc explanation: there is probably a syntax error such as missing semi-colon on line 4 of missing_semicolon_line_before_assert.c or an earlier line 8 | -------------------------------------------------------------------------------- /tests/expected_output/misspelt_printf/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | misspelt_printf.c:3:5: warning: implicit declaration of function 'print' is invalid in C99 [-Wimplicit-function-declaration] 2 | print("hello"); 3 | ^ 4 | dcc explanation: you are calling a function named print on line 3 of misspelt_printf.c but dcc does not recognize print as a function. 5 | Maybe you meant printf? 6 | -------------------------------------------------------------------------------- /tests/expected_output/misspelt_printf/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | misspelt_printf.c:3:5: error: call to undeclared function 'print'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 2 | print("hello"); 3 | ^ 4 | misspelt_printf.c:3:5: note: did you mean 'printf'? 5 | /usr/include/stdio.h:356:12: note: 'printf' declared here 6 | extern int printf (const char *__restrict __format, ...); 7 | ^ 8 | dcc explanation: you are calling a function named print on line 3 of misspelt_printf.c but dcc does not recognize print as a function. 9 | Maybe you meant printf? 10 | -------------------------------------------------------------------------------- /tests/expected_output/mod_zero-fsanitize=memory/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Execution stopped by an arithmetic error. 3 | Often this is caused by division (or %) by zero. 4 | Execution stopped in main() in mod_zero.c at line 7: 5 | 6 | int main(int argc, char **argv) { 7 | --> printf("%d\n", 42 % (argc - 1)); 8 | } 9 | 10 | Values when execution stopped: 11 | 12 | argc = 1 13 | 14 | -------------------------------------------------------------------------------- /tests/expected_output/mod_zero-fsanitize=valgrind/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: division by zero 3 | dcc explanation: A common error is to evaluate x % y when y == 0 which is undefined. 4 | 5 | Execution stopped in () in mod_zero.c at line 7: 6 | 7 | int main(int argc, char **argv) { 8 | --> printf("%d\n", 42 % (argc - 1)); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /tests/expected_output/mod_zero-fsanitize=valgrind/000001-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: division by zero 3 | dcc explanation: A common error is to evaluate x % y when y == 0 which is undefined. 4 | 5 | Execution stopped in main() in mod_zero.c at line 7: 6 | 7 | int main(int argc, char **argv) { 8 | --> printf("%d\n", 42 % (argc - 1)); 9 | } 10 | 11 | Values when execution stopped: 12 | 13 | argc = 1 14 | 15 | -------------------------------------------------------------------------------- /tests/expected_output/mod_zero.cpp/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: division by zero 3 | dcc explanation: A common error is to evaluate x % y when y == 0 which is undefined. 4 | 5 | Execution stopped in main() in mod_zero.cpp at line 4: 6 | 7 | int main(int argc, char **argv) { 8 | --> std::cout << 42 % (argc - 1) << "\n"; 9 | } 10 | 11 | Values when execution stopped: 12 | 13 | argc = 1 14 | 15 | -------------------------------------------------------------------------------- /tests/expected_output/mod_zero/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: division by zero 3 | dcc explanation: A common error is to evaluate x % y when y == 0 which is undefined. 4 | 5 | Execution stopped in main() in mod_zero.c at line 7: 6 | 7 | int main(int argc, char **argv) { 8 | --> printf("%d\n", 42 % (argc - 1)); 9 | } 10 | 11 | Values when execution stopped: 12 | 13 | argc = 1 14 | 15 | -------------------------------------------------------------------------------- /tests/expected_output/more_conversions_than_data_arguments/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | more_conversions_than_data_arguments.c:4:23: warning: more '%' conversions than data arguments [-Wformat-insufficient-args] 2 | printf("%d %d %d %d", 27, 28, 29); 3 | ~^ 4 | dcc explanation: you have less argument values than % codes in the format string. 5 | You need to change the format string or change the number of arguments. 6 | -------------------------------------------------------------------------------- /tests/expected_output/multiple_unsequenced_modifications/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | multiple_unsequenced_modifications.c:2:16: warning: multiple unsequenced modifications to 'argc' [-Wunsequenced] 2 | argc = argc--; 3 | ~ ^ 4 | dcc explanation: you are changing a variable multiple times in the one statement. 5 | `++` and `--` change the variable, there is no need to also assign the result to the variable. 6 | -------------------------------------------------------------------------------- /tests/expected_output/no_leak_printf--leak-check/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | this causes a spurious memory leak with some libc versions 2 | -------------------------------------------------------------------------------- /tests/expected_output/no_leak_simple--leak-check/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/no_leak_simple--leak-check/000000-clang-14.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/no_main/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | error: your program does not contain a main function - a C program must contain a main function 2 | -------------------------------------------------------------------------------- /tests/expected_output/non_void_function_does_not_return_a_value/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | non_void_function_does_not_return_a_value.c:2:1: warning: non-void function does not return a value [-Wreturn-type] 2 | } 3 | ^ 4 | dcc explanation: your function has no return statement. 5 | Unless a function is of type void, it must return a value using a return statement. 6 | -------------------------------------------------------------------------------- /tests/expected_output/non_void_function_does_not_return_a_value_in_all_control_paths/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | non_void_function_does_not_return_a_value_in_all_control_paths.c:5:1: warning: non-void function does not return a value in all control paths [-Wreturn-type] 2 | } 3 | ^ 4 | dcc explanation: Your function contains a return but it is possible for execution 5 | to reach the end of the function without a return statment being executed. 6 | -------------------------------------------------------------------------------- /tests/expected_output/nonnull/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | nonnull.c: In function ‘main’: 2 | nonnull.c:5:5: warning: argument 2 null where non-null expected [-Wnonnull] 3 | 5 | faccessat(0, pathname, 0, 0); 4 | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 | dcc explanation: you are passing the variable pathname which always contains NULL as argument 2 to 'faccessat'. 6 | Argument 2 to 'faccessat' should never be NULL. 7 | In file included from nonnull.c:1: 8 | /usr/include/unistd.h:309:12: note: in a call to function ‘faccessat’ declared ‘nonnull’ 9 | 309 | extern int faccessat (int __fd, const char *__file, int __type, int __flag) 10 | | ^~~~~~~~~ 11 | -------------------------------------------------------------------------------- /tests/expected_output/parameter_o_main/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | parameter_o_main.c:1:5: warning: only one parameter on 'main' declaration [-Wmain] 2 | int main(int argc) { 3 | ^ 4 | dcc explanation: your declaration of 'main' is incorrect. 5 | Try either 'int main(void)' or 'int main(int argc, char *argv[])' 6 | -------------------------------------------------------------------------------- /tests/expected_output/popen/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | popen 2 | -------------------------------------------------------------------------------- /tests/expected_output/posix_spawn/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/posix_spawn/000000-clang-14.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/print_path/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/print_path/000000-clang-16.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/printf_int_string_mismatch/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | printf_int_string_mismatch.c:4:20: warning: format specifies type 'int' but the argument has type 'char *' [-Wformat] 2 | printf("%d\n", "hello!"); 3 | ~~ ^~~~~~~~ 4 | %s 5 | dcc explanation: make sure you are using the correct format code (e.g., `%d` for integers, `%lf` for floating-point values) in your format string on line 4 of printf_int_string_mismatch.c. 6 | -------------------------------------------------------------------------------- /tests/expected_output/relational_comparison_result_unused/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | relational_comparison_result_unused.c:2:17: warning: relational comparison result unused [-Wunused-comparison] 2 | return argc < 0, argc < 23; 3 | ~~~~~^~~ 4 | dcc explanation: you appear to be combining combining comparison incorrectly. 5 | Perhaps you are using ',' instead of '&&' or '||'. 6 | -------------------------------------------------------------------------------- /tests/expected_output/relational_expression_with_comma/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | relational_expression_with_comma.c:2:14: warning: relational comparison result unused [-Wunused-comparison] 2 | if (argc < 1, argc < 2) { 3 | ~~~~~^~~ 4 | dcc explanation: you appear to be combining combining comparison incorrectly. 5 | Perhaps you are using ',' instead of '&&' or '||'. 6 | -------------------------------------------------------------------------------- /tests/expected_output/rename/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/rename/000000-clang-14.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/result_of_comparison_against_a_string_literal_is_unspecified/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | result_of_comparison_against_a_string_literal_is_unspecified.c:2:20: warning: result of comparison against a string literal is unspecified (use an explicit string comparison function instead) [-Wstring-compare] 2 | return argv[0] < ""; 3 | ^ ~~ 4 | dcc explanation: you can not compare strings with '<', '>' etc. 5 | 'string.h' has functions which can compare strings, e.g. 'strcmp' 6 | -------------------------------------------------------------------------------- /tests/expected_output/return_type_of_main_is_not_int/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | return_type_of_main_is_not_int.c:1:1: warning: return type of 'main' is not 'int' [-Wmain-return-type] 2 | void main(void) { 3 | ^ 4 | return_type_of_main_is_not_int.c:1:1: note: change return type to 'int' 5 | void main(void) { 6 | ^~~~ 7 | int 8 | dcc explanation: 'main' must always have return type int. 9 | -------------------------------------------------------------------------------- /tests/expected_output/scanf_missing_ampersand/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | scanf_missing_ampersand.c:5:17: warning: format specifies type 'int *' but the argument has type 'int' [-Wformat] 2 | scanf("%d", i); 3 | ~~ ^ 4 | dcc explanation: Perhaps you have forgotten an '&' before 'i' on line 5 of scanf_missing_ampersand.c. 5 | -------------------------------------------------------------------------------- /tests/expected_output/seek/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ; 2 | } 3 | } 4 | -------------------------------------------------------------------------------- /tests/expected_output/stack_use_after_return/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | stack_use_after_return.c:3:13: warning: address of stack memory associated with local variable 'i' returned [-Wreturn-stack-address] 2 | return &i; 3 | ^ 4 | dcc explanation: you are trying to return a pointer to the local variable 'i'. 5 | You can not do this because i will not exist after the function returns. 6 | 7 | See more information here: https://comp1511unsw.github.io/dcc/stack_use_after_return.html 8 | -------------------------------------------------------------------------------- /tests/expected_output/string/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/string/000000-clang-16.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/subscripted_value_is_not_an_array/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | subscripted_value_is_not_an_array.c:2:16: error: subscripted value is not an array, pointer, or vector 2 | return argc[0]; 3 | ~~~~^~ 4 | dcc explanation: you appear to be incorrectly trying to use argc as an array . 5 | -------------------------------------------------------------------------------- /tests/expected_output/synchronization-time/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/synchronization-time/000000-clang-14.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/too_many_arguments_to_function_call_expected_d_have_d/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | too_many_arguments_to_function_call_expected_d_have_d.c:3:20: error: too many arguments to function call, expected 0, have 3 2 | return getchar(0, 0, 0); 3 | ~~~~~~~ ^~~~~~~ 4 | /usr/include/stdio.h:520:12: note: 'getchar' declared here 5 | extern int getchar (void); 6 | ^ 7 | dcc explanation: function getchar() takes 0 arguments but you have given it 3 arguments. 8 | -------------------------------------------------------------------------------- /tests/expected_output/two_main_functions/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | /bin/ld: /tmp/two_main_functions-468d5a.o: in function `main': 2 | /tmp/tmp.zs9sLtK32g/two_main_functions.c:3: multiple definition of `main'; /tmp/two_main_functions-fdd4e4.o:/tmp/tmp.zs9sLtK32g/two_main_functions.c:3: first defined here 3 | clang: error: linker command failed with exit code 1 (use -v to see invocation) 4 | dcc explanation: Your program contains more than one main function - a C program can only contain one main function. 5 | -------------------------------------------------------------------------------- /tests/expected_output/two_uninitialized_values/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: signed integer overflow: -1094795586 + -1094795586 cannot be represented in type 'int' 3 | dcc explanation: Your program looks to be using an uninitialized value. 4 | -1094795586 is probably actually an uninitialized value. 5 | 6 | Execution stopped in main() in two_uninitialized_values.c at line 4: 7 | 8 | int main(int argc, char *argv[]) { 9 | int a[2]; 10 | a[argc] = 1; 11 | --> return a[0] + a[0]; 12 | } 13 | 14 | Values when execution stopped: 15 | 16 | a = {, 1} 17 | argc = 1 18 | a[argc] = 1 19 | 20 | -------------------------------------------------------------------------------- /tests/expected_output/two_uninitialized_values/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: exit value is uninitialized 3 | Main is returning an uninitialized value or exit has been passed an uninitialized value. 4 | 5 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-array-element-if-fsanitize=address,memory/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-array-element-if.c at line 9: 5 | 6 | int main(int argc, char **argv) { 7 | int a[100]; 8 | a[42] = 42; 9 | --> if (a[argc]) { 10 | a[43] = 43; 11 | } 12 | } 13 | 14 | Values when execution stopped: 15 | 16 | a = { , 42, } 17 | argc = 1 18 | a[42] = 42 19 | a[43] = 20 | a[argc] = 21 | 22 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-array-element-if-fsanitize=memory/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable used 3 | Execution stopped in main() in uninitialized-array-element-if.c at line 9: 4 | 5 | int main(int argc, char **argv) { 6 | int a[100]; 7 | a[42] = 42; 8 | --> if (a[argc]) { 9 | a[43] = 43; 10 | } 11 | } 12 | 13 | Values when execution stopped: 14 | 15 | a = { , 42, , 1464690352, 32741, ...} 16 | argc = 1 17 | a[42] = 42 18 | a[43] = 19 | a[argc] = 20 | 21 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-array-element-if-fsanitize=valgrind/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-array-element-if.c at line 9: 5 | 6 | int main(int argc, char **argv) { 7 | int a[100]; 8 | a[42] = 42; 9 | --> if (a[argc]) { 10 | a[43] = 43; 11 | } 12 | } 13 | 14 | Values when execution stopped: 15 | 16 | a = { , 42, } 17 | argc = 1 18 | a[42] = 42 19 | a[43] = 20 | a[argc] = 21 | 22 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-array-element-if/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-array-element-if.c at line 9: 5 | 6 | int main(int argc, char **argv) { 7 | int a[100]; 8 | a[42] = 42; 9 | --> if (a[argc]) { 10 | a[43] = 43; 11 | } 12 | } 13 | 14 | Values when execution stopped: 15 | 16 | a = { , 42, } 17 | argc = 1 18 | a[42] = 42 19 | a[43] = 20 | a[argc] = 21 | 22 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-array-element-printf.cpp/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-array-element-printf.cpp at line 6: 5 | 6 | int main(int argc, char **argv) { 7 | int a[1000]; 8 | a[42] = 42; 9 | --> std::cout << a[argc] << "\n"; 10 | } 11 | 12 | Values when execution stopped: 13 | 14 | a = { , 42, } 15 | argc = 1 16 | a[42] = 42 17 | a[argc] = 18 | 19 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-array-element-printf/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-array-element-printf.c at line 8: 5 | 6 | int main(int argc, char **argv) { 7 | int a[1000]; 8 | a[42] = 42; 9 | --> printf("%d\n", a[argc]); 10 | } 11 | 12 | Values when execution stopped: 13 | 14 | a = { , 42, } 15 | argc = 1 16 | a[42] = 42 17 | a[argc] = 18 | 19 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-array-element-sum/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-array-element-sum.c at line 7: 5 | 6 | int main(void) { 7 | int i, a[1000], sum = 0; 8 | a[42] = 42; 9 | for (i = 0; i < 1000; i++) { 10 | sum += a[i] % 2; 11 | } 12 | --> if (sum < 1000) { 13 | return sum; 14 | } 15 | return 0; 16 | 17 | Values when execution stopped: 18 | 19 | a = { , 42, } 20 | i = 1000 21 | sum = 0 22 | a[1000] = 23 | a[42] = 42 24 | a[i] = 25 | 26 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-char-array-fsanitize=valgrind/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-char-array.c at line 7: 5 | 6 | int main(int argc, char **argv) { 7 | char input[2][10]; 8 | --> printf("%s", input[0]); 9 | } 10 | 11 | Values when execution stopped: 12 | 13 | argc = 1 14 | input = {"<10 uninitialized values>", "<10 uninitialized values>"} 15 | input[0] = "<10 uninitialized values>" 16 | 17 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-char-array-large.cpp/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-char-array-large.cpp at line 7: 5 | 6 | int main(int argc, char *argv[]) { 7 | char input[8192]; 8 | input[argc] = 0; 9 | --> std::cout << input[0]; 10 | } 11 | 12 | Values when execution stopped: 13 | 14 | argc = 1 15 | input = "\000", <8190 uninitialized values> 16 | input[0] = 17 | input[argc] = 0 = '\0' 18 | 19 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-char-array-large/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-char-array-large.c at line 7: 5 | 6 | int main(int argc, char *argv[]) { 7 | char input[8192]; 8 | input[argc] = 0; 9 | --> printf("%c", input[0]); 10 | } 11 | 12 | Values when execution stopped: 13 | 14 | argc = 1 15 | input = "\000", <8190 uninitialized values> 16 | input[0] = 17 | input[argc] = 0 = '\0' 18 | 19 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-char-array.cpp-fsanitize=valgrind/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-char-array.cpp at line 8: 5 | 6 | int main(int argc, char **argv) { 7 | char input[2][10]; 8 | input[argc][argc] = 0; 9 | --> std::cout << input[0]; 10 | } 11 | 12 | Values when execution stopped: 13 | 14 | argc = 1 15 | input = {"<10 uninitialized values>", "\000<8 uninitialized values>"} 16 | input[0] = "<10 uninitialized values>" 17 | input[argc][argc] = 0 = '\0' 18 | 19 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-local-variable/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | uninitialized-local-variable.c: In function ‘main’: 2 | uninitialized-local-variable.c:3:13: warning: ‘a’ is used uninitialized [-Wuninitialized] 3 | 3 | return a[0]; 4 | | ~^~~ 5 | uninitialized-local-variable.c:2:9: note: ‘a’ declared here 6 | 2 | int a[1]; 7 | | ^ 8 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-overflow/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: signed integer overflow: -1094795587 * 8 cannot be represented in type 'int' 3 | dcc explanation: Arithmetic on an an uninitialized value has produced a value that can not be represented. 4 | 5 | Execution stopped in main() in uninitialized-overflow.c at line 5: 6 | 7 | int main(int argc, char **argv) { 8 | int x[2]; 9 | x[argc] = 1; 10 | --> printf("%d\n", (x[0] - 1) * 8); 11 | } 12 | 13 | Values when execution stopped: 14 | 15 | argc = 1 16 | x = {, 1} 17 | x[0] = 18 | x[argc] = 1 19 | 20 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-overflow/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-overflow.c at line 5: 5 | 6 | int main(int argc, char **argv) { 7 | int x[2]; 8 | x[argc] = 1; 9 | --> printf("%d\n", (x[0] - 1) * 8); 10 | } 11 | 12 | Values when execution stopped: 13 | 14 | argc = 1 15 | x = {, 1} 16 | x[0] = 17 | x[argc] = 1 18 | 19 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-pointer-array/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Execution stopped because of an invalid pointer or string. 3 | Execution stopped in main() in uninitialized-pointer-array.c at line 6: 4 | 5 | int main(int argc, char *argv[]) { 6 | char *p[2]; 7 | p[argc] = NULL; 8 | --> printf("%s", p[0]); 9 | } 10 | 11 | Values when execution stopped: 12 | 13 | argc = 1 14 | p = {, NULL} 15 | p[0] = 16 | p[argc] = NULL 17 | 18 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-struct-field/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: member access within misaligned address 0x000000000005 for type 'struct b', which requires 4 byte align 3 | Execution stopped in main() in uninitialized-struct-field.c at line 6: 4 | 5 | int main(void) { 6 | struct b { 7 | int a; 8 | }; 9 | struct b *s = (struct b *)0x5; 10 | --> return s->a; 11 | } 12 | 13 | Values when execution stopped: 14 | 15 | s = 0x5 16 | 17 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-struct-field1/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in print_car_space(car_space=...) in uninitialized-struct-field1.c at line 16: 5 | 6 | void print_car_space(struct car_space car_space) { 7 | --> if (car_space.parking_rate == NORMAL) { 8 | printf("N"); 9 | } 10 | } 11 | 12 | Values when execution stopped: 13 | 14 | car_space = {} 15 | car_space.parking_rate = 16 | 17 | Function call traceback: 18 | 19 | print_car_space(car_space=...) called at line 24 of uninitialized-struct-field1.c 20 | main() 21 | 22 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-types-illegal-index/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: stack buffer overflow 4 | dcc explanation: access past the end of a local variable. 5 | Make sure the size of your array is correct. 6 | Make sure your array indices are correct. 7 | Execution stopped in main() in uninitialized-types-illegal-index.c at line 34: 8 | 9 | struct f f; 10 | struct c c; 11 | if (!argc) { 12 | i.i8 = 1; 13 | f.d = 1; 14 | } 15 | --> c.a[argc+20] = 0; 16 | printf("%d %lf %c\n", i.i8, f.d, c.a[0]); 17 | } 18 | 19 | Values when execution stopped: 20 | 21 | argc = 1 22 | c = {} 23 | f = {} 24 | i = {} 25 | c.a = <16 uninitialized values> 26 | f.d = 27 | i.i8 = 28 | 29 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-types-malloc/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-types-malloc.c at line 36: 5 | 6 | struct c *c = malloc(sizeof *c); 7 | if (!argc) { 8 | i->i8 = 1; 9 | f->d = 1; 10 | c->c = 1; 11 | } 12 | --> printf("%d %lf %c\n", i->i8, f->d, c->c); 13 | } 14 | 15 | Values when execution stopped: 16 | 17 | argc = 1 18 | c = 0x4b55770 19 | f = 0x4b55710 20 | i = 0x4b556a0 21 | c->c = 22 | f->d = 23 | i->i8 = 24 | 25 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-types/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-types.c at line 35: 5 | 6 | struct c c; 7 | if (!argc) { 8 | i.i8 = 1; 9 | f.d = 1; 10 | c.c = 1; 11 | } 12 | --> printf("%d %lf %c\n", i.i8, f.d, c.c); 13 | } 14 | 15 | Values when execution stopped: 16 | 17 | argc = 1 18 | c = {c = , s = , a = <16 uninitialized values>} 19 | f = {} 20 | i = {} 21 | c.c = 22 | f.d = 23 | i.i8 = 24 | 25 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized-types/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in uninitialized-types.c at line 35: 5 | 6 | struct c c; 7 | if (!argc) { 8 | i.i8 = 1; 9 | f.d = 1; 10 | c.a[0] = 1; 11 | } 12 | --> printf("%d %lf %c\n", i.i8, f.d, c.a[0]); 13 | } 14 | 15 | Values when execution stopped: 16 | 17 | argc = 1 18 | c = {} 19 | f = {} 20 | i = {} 21 | c.a = <16 uninitialized values> 22 | f.d = 23 | i.i8 = 24 | 25 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized_exit_status.cpp/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: exit value is uninitialized 3 | Main is returning an uninitialized value or exit has been passed an uninitialized value. 4 | 5 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized_exit_status/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: exit value is uninitialized 3 | Main is returning an uninitialized value or exit has been passed an uninitialized value. 4 | 5 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized_local_variable/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | uninitialized_local_variable.c:5:16: warning: variable 's' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] 2 | } else if (argc < 2) { 3 | ^~~~~~~~ 4 | uninitialized_local_variable.c:9:12: note: uninitialized use occurs here 5 | return s; 6 | ^ 7 | uninitialized_local_variable.c:5:12: note: remove the 'if' if its condition is always true 8 | } else if (argc < 2) { 9 | ^~~~~~~~~~~~~~ 10 | uninitialized_local_variable.c:2:10: note: initialize the variable 's' to silence this warning 11 | int s; 12 | ^ 13 | = 0 14 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized_posix_spawn-fsanitize=valgrind/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: invalid parameters to process creation 3 | An error has occurred in process creation. 4 | This is likely an invalid argument to posix_spawn, posix_spawnp or clone. 5 | Check all arguments are initialized. 6 | 7 | -------------------------------------------------------------------------------- /tests/expected_output/uninitialized_posix_spawnp-fsanitize=valgrind/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: invalid parameters to process creation 3 | An error has occurred in process creation. 4 | This is likely an invalid argument to posix_spawn, posix_spawnp or clone. 5 | Check all arguments are initialized. 6 | 7 | -------------------------------------------------------------------------------- /tests/expected_output/unistd_compile_error/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | unistd_compile_error.c:7:6: error: redefinition of 'read' 2 | void read(void) { 3 | ^ 4 | -------------------------------------------------------------------------------- /tests/expected_output/unistd_name_clash/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | hello world 2 | -------------------------------------------------------------------------------- /tests/expected_output/unistd_use/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/COMP1511UNSW/dcc/0a888fdb2bfe130c611fb84514fdbf52d3efe149/tests/expected_output/unistd_use/000000-clang-14.0-x86_64-pc-linux-gnu.txt -------------------------------------------------------------------------------- /tests/expected_output/unknown_escape_sequence/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | unknown_escape_sequence.c:2:17: warning: unknown escape sequence '\_' [-Wunknown-escape-sequence] 2 | return (int)"\_/"; 3 | ^~ 4 | dcc explanation: if you want an actual backslash in your string use \\ 5 | -------------------------------------------------------------------------------- /tests/expected_output/unknown_type_name_define/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | unknown_type_name_define.c:1:1: error: unknown type name 'define' 2 | define X 42 3 | ^ 4 | dcc explanation: you appear to have left out a '#'. 5 | Use #define to define a constant, for example: #define PI 3.14159 6 | -------------------------------------------------------------------------------- /tests/expected_output/unknown_type_name_include/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | unknown_type_name_include.c:1:1: error: unknown type name 'define' 2 | define X 42 3 | ^ 4 | dcc explanation: you appear to have left out a '#'. 5 | Use #define to define a constant, for example: #define PI 3.14159 6 | -------------------------------------------------------------------------------- /tests/expected_output/unterminated-strcmp/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in unterminated-strcmp.c at line 8: 5 | 6 | int main(void) { 7 | char i[2]; 8 | char j[2]; 9 | i[0] = 'H'; 10 | j[0] = 'H'; 11 | --> return strcmp(i, j); 12 | } 13 | 14 | Values when execution stopped: 15 | 16 | i = "H" 17 | j = "H" 18 | i[0] = 72 = 'H' 19 | j[0] = 72 = 'H' 20 | 21 | -------------------------------------------------------------------------------- /tests/expected_output/unterminated-strcmp/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: stack buffer overflow 4 | dcc explanation: access past the end of a local variable. 5 | Make sure the size of your array is correct. 6 | Make sure your array indices are correct. 7 | Execution stopped in main() in unterminated-strcmp.c at line 8: 8 | 9 | int main(void) { 10 | char i[2]; 11 | char j[2]; 12 | i[0] = 'H'; 13 | j[0] = 'H'; 14 | --> return strcmp(i, j); 15 | } 16 | 17 | Values when execution stopped: 18 | 19 | i = "H" 20 | j = "H" 21 | i[0] = 72 = 'H' 22 | j[0] = 72 = 'H' 23 | 24 | -------------------------------------------------------------------------------- /tests/expected_output/unterminated-strcpy/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: illegal array, pointer or other operation 3 | Execution stopped in main() in unterminated-strcpy.c at line 7: 4 | 5 | int main(void) { 6 | char i[2]; 7 | char o[2]; 8 | i[0] = 'H'; 9 | --> strcpy(o, i); 10 | } 11 | 12 | Values when execution stopped: 13 | 14 | i = "H" 15 | o = "<2 uninitialized values>" 16 | i[0] = 72 = 'H' 17 | 18 | -------------------------------------------------------------------------------- /tests/expected_output/unterminated-strcpy/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: stack buffer overflow 4 | dcc explanation: access past the end of a local variable. 5 | Make sure the size of your array is correct. 6 | Make sure your array indices are correct. 7 | Execution stopped in main() in unterminated-strcpy.c at line 7: 8 | 9 | int main(void) { 10 | char i[2]; 11 | char o[2]; 12 | i[0] = 'H'; 13 | --> strcpy(o, i); 14 | } 15 | 16 | Values when execution stopped: 17 | 18 | i = "H" 19 | o = "H" 20 | i[0] = 72 = 'H' 21 | 22 | -------------------------------------------------------------------------------- /tests/expected_output/unterminated-strlen/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in unterminated-strlen.c at line 6: 5 | 6 | int main(void) { 7 | char i[2]; 8 | i[0] = 'H'; 9 | --> return strlen(i); 10 | } 11 | 12 | Values when execution stopped: 13 | 14 | i = "H" 15 | i[0] = 72 = 'H' 16 | 17 | -------------------------------------------------------------------------------- /tests/expected_output/unterminated-strlen/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: stack buffer overflow 4 | dcc explanation: access past the end of a local variable. 5 | Make sure the size of your array is correct. 6 | Make sure your array indices are correct. 7 | Execution stopped in main() in unterminated-strlen.c at line 6: 8 | 9 | int main(void) { 10 | char i[2]; 11 | i[0] = 'H'; 12 | --> return strlen(i); 13 | } 14 | 15 | Values when execution stopped: 16 | 17 | i = "H" 18 | i[0] = 72 = 'H' 19 | 20 | -------------------------------------------------------------------------------- /tests/expected_output/unterminated-strncmp/000000-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: uninitialized variable accessed. 3 | 4 | Execution stopped in main() in unterminated-strncmp.c at line 8: 5 | 6 | int main(void) { 7 | char i[2]; 8 | char j[2]; 9 | i[0] = 'H'; 10 | j[0] = 'H'; 11 | --> return strncmp(i, j, 2); 12 | } 13 | 14 | Values when execution stopped: 15 | 16 | i = "H" 17 | j = "H" 18 | i[0] = 72 = 'H' 19 | j[0] = 72 = 'H' 20 | 21 | -------------------------------------------------------------------------------- /tests/expected_output/unterminated_strcat/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: stack buffer overflow 4 | dcc explanation: access past the end of a local variable. 5 | Make sure the size of your array is correct. 6 | Make sure your array indices are correct. 7 | Execution stopped in main() in unterminated_strcat.c at line 7: 8 | 9 | int main(void) { 10 | char c = 'd'; 11 | char s[5]; 12 | --> strcat(s, &c); 13 | } 14 | 15 | Values when execution stopped: 16 | 17 | c = 100 = 'd' 18 | s = "<5 uninitialized values>" 19 | 20 | -------------------------------------------------------------------------------- /tests/expected_output/unterminated_string/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: stack buffer overflow 4 | dcc explanation: access past the end of a local variable. 5 | Make sure the size of your array is correct. 6 | Make sure your array indices are correct. 7 | Execution stopped in main() in unterminated_string.c at line 7: 8 | 9 | int main(void) { 10 | char str[10]; 11 | str[0] = 'H'; 12 | str[1] = 'i'; 13 | --> printf("%s", str); 14 | return 0; 15 | } 16 | 17 | Values when execution stopped: 18 | 19 | str = "Hi<8 uninitialized values>" 20 | str[0] = 72 = 'H' 21 | str[1] = 105 = 'i' 22 | 23 | -------------------------------------------------------------------------------- /tests/expected_output/use_after_free/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: malloc use after free 4 | dcc explanation: access to memory that has already been freed. 5 | Execution stopped in main() in use_after_free.c at line 9: 6 | 7 | int main(int argc, char *argv[]) { 8 | int *p = (int *)malloc(sizeof(int *)); 9 | *p = 1; 10 | if (argc > 0) { 11 | free(p); 12 | } 13 | --> return *p; 14 | } 15 | 16 | Values when execution stopped: 17 | 18 | argc = 1 19 | 20 | -------------------------------------------------------------------------------- /tests/expected_output/use_after_return--use-after-return/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | ================================================================= 2 | 3 | Runtime error: stack use after return 4 | dcc explanation: You have used a pointer to a local variable that no longer exists. 5 | When a function returns its local variables are destroyed. 6 | 7 | For more information see: https://comp1511unsw.github.io/dcc/stack_use_after_return.html 8 | Execution stopped in main() in use_after_return.c at line 25: 9 | 10 | int main(void) { 11 | --> printf("%d\n", *f(50)); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /tests/expected_output/use_after_return/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: invalid memory access 3 | A common cause of this error is use of an invalid FILE * pointer. 4 | 5 | 6 | Execution stopped in main() in use_after_return.c at line 25: 7 | 8 | int main(void) { 9 | --> printf("%d\n", *f(50)); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /tests/expected_output/use_of_undeclared_identifier/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | use_of_undeclared_identifier.c:2:12: error: use of undeclared identifier 'x' 2 | return x; 3 | ^ 4 | dcc explanation: you have used the name 'x' on line 2 of use_of_undeclared_identifier.c without previously declaring it. 5 | If you meant to use 'x' as a variable, check you have declared it by specifying its type 6 | Also check you have spelled 'x' correctly everywhere. 7 | -------------------------------------------------------------------------------- /tests/expected_output/using_the_result_of_an_assignment_as_a_condition_without_parenthese/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | using_the_result_of_an_assignment_as_a_condition_without_parenthese.c:2:14: warning: using the result of an assignment as a condition without parentheses [-Wparentheses] 2 | if (argc = 4) { 3 | ~~~~~^~~ 4 | using_the_result_of_an_assignment_as_a_condition_without_parenthese.c:2:14: note: place parentheses around the assignment to silence this warning 5 | if (argc = 4) { 6 | ^ 7 | ( ) 8 | using_the_result_of_an_assignment_as_a_condition_without_parenthese.c:2:14: note: use '==' to turn this assignment into an equality comparison 9 | if (argc = 4) { 10 | ^ 11 | == 12 | dcc explanation: you use '=' to assign to a variable, you use '==' to compare values. 13 | -------------------------------------------------------------------------------- /tests/expected_output/variable_used_in_own_initialization/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | variable_used_in_own_initialization.c:2:13: warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized] 2 | int x = x + 1; 3 | ~ ^ 4 | dcc explanation: you are using variable 'x' as part of its own initialization. 5 | You can not use a variable to initialize itself. 6 | -------------------------------------------------------------------------------- /tests/expected_output/void_function_should_not_return_a_value/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | void_function_should_not_return_a_value.c:2:5: error: void function 'f' should not return a value [-Wreturn-type] 2 | return 1; 3 | ^ ~ 4 | dcc explanation: you are trying to return a value from function f which is of type void. 5 | You need to change the return type of f or change the return statement. 6 | -------------------------------------------------------------------------------- /tests/expected_output/warning_unknown_escape_sequence/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | warning_unknown_escape_sequence.c:2:13: warning: unknown escape sequence '\ ' [-Wunknown-escape-sequence] 2 | return "\ "[0]; 3 | ^~ 4 | dcc explanation: you have a space after a backslash which is not permitted. 5 | -------------------------------------------------------------------------------- /tests/expected_output/write_null_stream/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | write_null_stream.c: In function ‘main’: 2 | write_null_stream.c:4:5: warning: argument 1 null where non-null expected [-Wnonnull] 3 | 4 | fprintf(NULL, "Hello world\n"); 4 | | ^~~~~~~ 5 | dcc explanation: you are passing a NULL value as argument 1 to 'fprintf'. 6 | Argument 1 to 'fprintf' should never be NULL. 7 | In file included from write_null_stream.c:1: 8 | /usr/include/stdio.h:350:12: note: in a call to function ‘fprintf’ declared ‘nonnull’ 9 | 350 | extern int fprintf (FILE *__restrict __stream, 10 | | ^~~~~~~ 11 | write_null_stream.c:4:5: warning: argument 4 null where non-null expected [-Wnonnull] 12 | 4 | fprintf(NULL, "Hello world\n"); 13 | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 14 | write_null_stream.c:4:5: note: in a call to built-in function ‘__builtin_fwrite’ 15 | dcc explanation: you are passing a NULL value as argument 4 to 'fprintf'. 16 | Argument 4 to 'fprintf' should never be NULL. 17 | -------------------------------------------------------------------------------- /tests/expected_output/write_null_stream/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | write_null_stream.c:4:13: warning: null passed to a callee that requires a non-null argument [-Wnonnull] 2 | fprintf(NULL, "Hello world\n"); 3 | ^~~~ 4 | /usr/lib/llvm-16/lib/clang/16/include/stddef.h:89:16: note: expanded from macro 'NULL' 5 | # define NULL ((void*)0) 6 | ^~~~~~~~~~ 7 | -------------------------------------------------------------------------------- /tests/expected_output/zero_size_array/000000-clang-14.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: index 0 out of bounds for type 'int[0]' 3 | dcc explanation: You have created a array of size 0 which is illegal. 4 | Make sure the size of your array is correct. 5 | Make sure your array indices are correct. 6 | 7 | Execution stopped in main() in zero_size_array.c at line 3: 8 | 9 | int main(void) { 10 | int a[0]; 11 | --> return a[0]; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /tests/expected_output/zero_size_array/000001-clang-16.0-x86_64-pc-linux-gnu.txt: -------------------------------------------------------------------------------- 1 | 2 | Runtime error: exit value is uninitialized 3 | Main is returning an uninitialized value or exit has been passed an uninitialized value. 4 | 5 | -------------------------------------------------------------------------------- /tests/run_time_errors/braces_before_error.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // check we don't shows uninformative closing braces or next function in error context 4 | int main(int argc, char **argv) { 5 | int a[1000]; 6 | if (argc > 1) { 7 | if (argc > 2) { 8 | if (argc > 3) { 9 | if (argc > 4) { 10 | if (argc > 5) { 11 | } 12 | } 13 | } 14 | } 15 | } 16 | 17 | a[42] = 42; 18 | printf("%d\n", a[argc]); 19 | } 20 | int f(void) { 21 | return 42; 22 | } 23 | -------------------------------------------------------------------------------- /tests/run_time_errors/call_stack_null.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int f3(int *a) { 4 | int b[] = { 0 }; 5 | return b[*a]; 6 | } 7 | int f2(int *a) { 8 | return f3(a); 9 | } 10 | 11 | int f1(int *a) { 12 | return f2(a); 13 | } 14 | 15 | int main(void) { 16 | return f1(NULL); 17 | } 18 | -------------------------------------------------------------------------------- /tests/run_time_errors/call_stack_uninitialized.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int f3(int *a) { 4 | return *a; 5 | } 6 | int f2(int *a) { 7 | return f3(a); 8 | } 9 | 10 | int f1(int *a) { 11 | return f2(a); 12 | } 13 | 14 | int main(int argc, char **argv) { 15 | int **i = (int **)malloc(2 * sizeof(int *)); 16 | i[argc] = NULL; 17 | return f1(i[0]); 18 | } 19 | -------------------------------------------------------------------------------- /tests/run_time_errors/check-o.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat >example2.c < 5 | #include 6 | 7 | struct node { 8 | int value; 9 | struct node *next; 10 | }; 11 | 12 | int main(void) { 13 | struct node *new_node = malloc(sizeof(struct node)); 14 | new_node->next = NULL; 15 | struct node *current = new_node->next; 16 | printf("%d\n", current->value); 17 | return 0; 18 | } 19 | eof 20 | 21 | $dcc example2.c -o example2 && ./example2 22 | 23 | rm -f example2.c example2 -------------------------------------------------------------------------------- /tests/run_time_errors/const0.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | int i = 0; 5 | const int j = 2; 6 | if (argc == 0) { 7 | i = 1; 8 | } 9 | printf("%d\n", j / i); 10 | } 11 | -------------------------------------------------------------------------------- /tests/run_time_errors/dereference_null_with_arrow.c: -------------------------------------------------------------------------------- 1 | #include 2 | struct list_node { 3 | struct list_node *next; 4 | int data; 5 | }; 6 | int main(void) { 7 | struct list_node *a = NULL; 8 | a->data = 42; 9 | } 10 | -------------------------------------------------------------------------------- /tests/run_time_errors/dereference_null_with_arrow_arrow.c: -------------------------------------------------------------------------------- 1 | #include 2 | struct list_node { 3 | struct list_node *next; 4 | int data; 5 | }; 6 | int main(void) { 7 | struct list_node s = { 0 }; 8 | struct list_node *a = &s; 9 | a->next->next->data = 42; 10 | } 11 | -------------------------------------------------------------------------------- /tests/run_time_errors/dereference_null_with_arrow_arrow_arrow.c: -------------------------------------------------------------------------------- 1 | #include 2 | struct list_node { 3 | struct list_node *next; 4 | int data; 5 | }; 6 | int main(void) { 7 | struct list_node s1, s2 = { 0 }; 8 | struct list_node *a = &s1; 9 | s1.next = &s2; 10 | a->next->next->data = 42; 11 | } 12 | -------------------------------------------------------------------------------- /tests/run_time_errors/dereference_null_with_asterisk.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(void) { 3 | int *a = NULL; 4 | *a = 42; 5 | } 6 | -------------------------------------------------------------------------------- /tests/run_time_errors/dereference_null_with_index.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(void) { 3 | int *a = NULL; 4 | return a[0]; 5 | } 6 | -------------------------------------------------------------------------------- /tests/run_time_errors/dereference_uninitialized_char_star_with_asterisk.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(int argc, char **argv) { 3 | char **a = (char **)malloc(2 * sizeof *a); 4 | a[argc] = NULL; 5 | return **a; 6 | } 7 | -------------------------------------------------------------------------------- /tests/run_time_errors/dereference_uninitialized_with_arrow.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | struct list_node { 4 | struct list_node *next; 5 | int data; 6 | }; 7 | int main(int argc, char **argv) { 8 | struct list_node *a = (struct list_node *)malloc(2 * sizeof *a); 9 | if (argc != 1) { 10 | a->next = NULL; 11 | } 12 | a->next->data = 42; 13 | } 14 | -------------------------------------------------------------------------------- /tests/run_time_errors/dereference_uninitialized_with_arrow_arrow_arrow.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | struct list_node { 4 | struct list_node *next; 5 | int data; 6 | }; 7 | int main(void) { 8 | struct list_node *a = (struct list_node *)malloc(sizeof *a); 9 | a->next = (struct list_node *)malloc(sizeof *a); 10 | a->next->next->data = 42; 11 | } 12 | -------------------------------------------------------------------------------- /tests/run_time_errors/dereference_uninitialized_with_asterisk.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(int argc, char **argv) { 3 | int **a = (int **)malloc(2 * sizeof *a); 4 | a[argc] = NULL; 5 | return **a; 6 | } 7 | -------------------------------------------------------------------------------- /tests/run_time_errors/dereference_uninitialized_with_index.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(int argc, char *argv[]) { 3 | int **a = (int **)malloc(2 * sizeof *a); 4 | a[argc] = NULL; 5 | return a[0][0]; 6 | } 7 | -------------------------------------------------------------------------------- /tests/run_time_errors/display_pointer_value0.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void g(int *p, int *q, int *r, int *s) { 4 | printf("%d %d %d %d\n", *p, *q, *r, *s); 5 | } 6 | 7 | void f(int i, int *p, int *q) { 8 | int j[10]; 9 | g(p, q, &j[i], &i); 10 | } 11 | 12 | int main(int argc, char *argv[]) { 13 | int i; 14 | int j[10]; 15 | int *p = &i; 16 | int *q = &j[argc]; 17 | if (argc == 0) { 18 | i = 0; 19 | j[0] = 0; 20 | } 21 | f(argc, p, q); 22 | } 23 | -------------------------------------------------------------------------------- /tests/run_time_errors/display_pointer_value1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void f(int k[2][3]) { 4 | printf("%d\n", k[0][0]); 5 | } 6 | 7 | int main(int argc, char *argv[]) { 8 | int j[2][3]; 9 | if (argc == 0) { 10 | j[0][0] = 0; 11 | } 12 | f(j); 13 | } 14 | -------------------------------------------------------------------------------- /tests/run_time_errors/double_free.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | void *p = malloc(4); 5 | if (p) free(p); 6 | free(p); 7 | } 8 | -------------------------------------------------------------------------------- /tests/run_time_errors/enum0.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum a { A, B }; 4 | 5 | int main(int argc, char *argv[]) { 6 | enum a i = A; 7 | if (argc == 0) { 8 | i = B; 9 | } 10 | printf("%d\n", 2 / i); 11 | } 12 | -------------------------------------------------------------------------------- /tests/run_time_errors/fgetc_NULL.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | FILE *f = NULL; 5 | fgetc(f); 6 | } 7 | -------------------------------------------------------------------------------- /tests/run_time_errors/fgetc_after_close.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | fclose(stdin); 5 | fgetc(stdin); 6 | } 7 | -------------------------------------------------------------------------------- /tests/run_time_errors/fgetc_uninitialized.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | FILE *f[2]; 5 | f[0] = NULL; 6 | fgetc(f[argc]); 7 | } 8 | -------------------------------------------------------------------------------- /tests/run_time_errors/hash_define.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ARRAY_SIZE 1000 4 | 5 | int main(int argc, char **argv) { 6 | int a[ARRAY_SIZE]; 7 | int i; 8 | 9 | for (i = 0; i < ARRAY_SIZE; i++) { 10 | a[i + argc] = i + argc; 11 | } 12 | return a[0]; 13 | } 14 | -------------------------------------------------------------------------------- /tests/run_time_errors/illegal_2d_array_access.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void twod(int b[5][4]) { 4 | printf("%d\n", b[5][2]); 5 | } 6 | 7 | int main(int argc, char **argv) { 8 | int a[5][4] = { { 0 } }; 9 | twod(a); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /tests/run_time_errors/illegal_2d_array_access.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void twod(int b[5][4]) { 4 | std::cout << b[5][2] << "\n"; 5 | } 6 | 7 | int main(int argc, char **argv) { 8 | int a[5][4] = { { 0 } }; 9 | twod(a); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /tests/run_time_errors/illegal_argv_index.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) { 4 | printf("%s\n", argv[-1]); 5 | } 6 | -------------------------------------------------------------------------------- /tests/run_time_errors/illegal_argv_index.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) { 4 | std::cout << argv[-1] << "\n"; 5 | } 6 | -------------------------------------------------------------------------------- /tests/run_time_errors/illegal_malloc_array_index.c: -------------------------------------------------------------------------------- 1 | //dcc_flags= 2 | //dcc_flags=-fsanitize=address 3 | //dcc_flags=--ifdef-main 4 | 5 | #include 6 | 7 | int main(int argc, char **argv) { 8 | int *a = (int *)malloc(1000 * sizeof(int)); 9 | a[999 + argc] = 42; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /tests/run_time_errors/illegal_malloc_array_index_uninitialized.c: -------------------------------------------------------------------------------- 1 | //dcc_flags= 2 | //dcc_flags=-fsanitize=address 3 | //dcc_flags=--ifdef-main 4 | 5 | #include 6 | #include 7 | 8 | int main(int argc, char **argv) { 9 | int *a = (int *)malloc(1000 * sizeof(int)); 10 | a[999 + argc] = 42; 11 | printf("%d\n", a[0]); 12 | } 13 | -------------------------------------------------------------------------------- /tests/run_time_errors/illegal_nested_array_assignment.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { 2 | int a[] = { 1, 2, 3, 4 }; 3 | a[a[a[a[a[0]]]]] = 1; 4 | } 5 | -------------------------------------------------------------------------------- /tests/run_time_errors/illegal_vla_index.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char **argv) { 2 | int a[600 + argc]; 3 | a[1000] = argc; 4 | return a[1000]; 5 | } 6 | -------------------------------------------------------------------------------- /tests/run_time_errors/incremental_compilation.sh: -------------------------------------------------------------------------------- 1 | #!/ bin / sh 2 | 3 | cat > tmp1.c << eof 4 | #include 5 | void 6 | f(void) { 7 | fprintf(stderr, "incremental compilation works\n"); 8 | } 9 | eof 10 | 11 | cat > tmp2.c << eof extern void f(void); 12 | int main(void) { 13 | f(); 14 | } 15 | eof 16 | 17 | $dcc - 18 | c tmp1.c $dcc - 19 | c tmp2.c $dcc tmp1.o tmp2.o./ a.out $dcc tmp1.o tmp2.c./ a.out 20 | -------------------------------------------------------------------------------- /tests/run_time_errors/int_overflow.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) { 4 | int k = INT_MAX; 5 | k += argc; 6 | } 7 | -------------------------------------------------------------------------------- /tests/run_time_errors/leak_simple.c: -------------------------------------------------------------------------------- 1 | //dcc_flags=--leak-check 2 | 3 | #include 4 | 5 | int main(void) { 6 | int *p = malloc(sizeof(*p)); 7 | } 8 | -------------------------------------------------------------------------------- /tests/run_time_errors/leak_then_exit.c: -------------------------------------------------------------------------------- 1 | //dcc_flags=--leak-check 2 | 3 | #include 4 | 5 | int main(void) { 6 | char *p = (char *)malloc(1); 7 | exit(!p); 8 | } 9 | -------------------------------------------------------------------------------- /tests/run_time_errors/leak_valgrind.c: -------------------------------------------------------------------------------- 1 | //dcc_flags=--leak-check 2 | 3 | #include 4 | 5 | int main(void) { 6 | malloc(1); 7 | } 8 | -------------------------------------------------------------------------------- /tests/run_time_errors/mod_zero.c: -------------------------------------------------------------------------------- 1 | //dcc_flags= 2 | //dcc_flags=-fsanitize=memory 3 | //dcc_flags=-fsanitize=valgrind 4 | 5 | #include 6 | int main(int argc, char **argv) { 7 | printf("%d\n", 42 % (argc - 1)); 8 | } 9 | -------------------------------------------------------------------------------- /tests/run_time_errors/mod_zero.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) { 4 | std::cout << 42 % (argc - 1) << "\n"; 5 | } 6 | -------------------------------------------------------------------------------- /tests/run_time_errors/two_uninitialized_values.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char *argv[]) { 2 | int a[2]; 3 | a[argc] = 1; 4 | return a[0] + a[0]; 5 | } 6 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-array-element-if.c: -------------------------------------------------------------------------------- 1 | //dcc_flags= 2 | //dcc_flags=-fsanitize=memory 3 | //dcc_flags=-fsanitize=address,memory 4 | //dcc_flags=-fsanitize=valgrind 5 | 6 | int main(int argc, char **argv) { 7 | int a[100]; 8 | a[42] = 42; 9 | if (a[argc]) { 10 | a[43] = 43; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-array-element-printf.c: -------------------------------------------------------------------------------- 1 | //--memory doesn't detect this error 2 | 3 | #include 4 | 5 | int main(int argc, char **argv) { 6 | int a[1000]; 7 | a[42] = 42; 8 | printf("%d\n", a[argc]); 9 | } 10 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-array-element-printf.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) { 4 | int a[1000]; 5 | a[42] = 42; 6 | std::cout << a[argc] << "\n"; 7 | } 8 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-array-element-sum.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int i, a[1000], sum = 0; 3 | a[42] = 42; 4 | for (i = 0; i < 1000; i++) { 5 | sum += a[i] % 2; 6 | } 7 | if (sum < 1000) { 8 | return sum; 9 | } 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-char-array-large.c: -------------------------------------------------------------------------------- 1 | // --memory does not detect this 2 | #include 3 | 4 | int main(int argc, char *argv[]) { 5 | char input[8192]; 6 | input[argc] = 0; 7 | printf("%c", input[0]); 8 | } 9 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-char-array-large.cpp: -------------------------------------------------------------------------------- 1 | // --memory does not detect this 2 | #include 3 | 4 | int main(int argc, char *argv[]) { 5 | char input[8192]; 6 | input[argc] = 0; 7 | std::cout << input[0]; 8 | } 9 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-char-array.c: -------------------------------------------------------------------------------- 1 | //dcc_flags=-fsanitize=valgrind 2 | // --memory does not detect this 3 | #include 4 | 5 | int main(int argc, char **argv) { 6 | char input[2][10]; 7 | printf("%s", input[0]); 8 | } 9 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-char-array.cpp: -------------------------------------------------------------------------------- 1 | //dcc_flags=-fsanitize=valgrind 2 | // --memory does not detect this 3 | #include 4 | 5 | int main(int argc, char **argv) { 6 | char input[2][10]; 7 | input[argc][argc] = 0; 8 | std::cout << input[0]; 9 | } 10 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-overflow.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(int argc, char **argv) { 3 | int x[2]; 4 | x[argc] = 1; 5 | printf("%d\n", (x[0] - 1) * 8); 6 | } 7 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-pointer-array.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | char *p[2]; 5 | p[argc] = NULL; 6 | printf("%s", p[0]); 7 | } 8 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-struct-field.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | struct b { 3 | int a; 4 | }; 5 | struct b *s = (struct b *)0x5; 6 | return s->a; 7 | } 8 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-struct-field1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum space_type { 4 | NORMAL, 5 | PREMIUM, 6 | }; 7 | 8 | struct car_space { 9 | enum space_type type; 10 | int parking_rate; 11 | int licence_plate; 12 | int occupied_since; 13 | }; 14 | 15 | void print_car_space(struct car_space car_space) { 16 | if (car_space.parking_rate == NORMAL) { 17 | printf("N"); 18 | } 19 | } 20 | 21 | int main(void) { 22 | struct car_space carpark[2][2]; 23 | carpark[1][1].type = PREMIUM; 24 | print_car_space(carpark[0][0]); 25 | } 26 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-types-illegal-index.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct i { 5 | int8_t i8; 6 | uint8_t u8; 7 | int32_t i32; 8 | uint32_t u32; 9 | int64_t i64; 10 | uint64_t u64; 11 | int *ip; 12 | }; 13 | 14 | struct f { 15 | float f; 16 | double d; 17 | double *dp; 18 | }; 19 | 20 | struct c { 21 | char c; 22 | char *s; 23 | char a[16]; 24 | }; 25 | 26 | int main(int argc, char *argv[]) { 27 | struct i i; 28 | struct f f; 29 | struct c c; 30 | if (!argc) { 31 | i.i8 = 1; 32 | f.d = 1; 33 | } 34 | c.a[argc+20] = 0; 35 | printf("%d %lf %c\n", i.i8, f.d, c.a[0]); 36 | } 37 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-types-malloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct i { 6 | int8_t i8; 7 | uint8_t u8; 8 | int32_t i32; 9 | uint32_t u32; 10 | int64_t i64; 11 | uint64_t u64; 12 | int *ip; 13 | }; 14 | 15 | struct f { 16 | float f; 17 | double d; 18 | double *dp; 19 | }; 20 | 21 | struct c { 22 | char c; 23 | char *s; 24 | char a[16]; 25 | }; 26 | 27 | int main(int argc, char *argv[]) { 28 | struct i *i = malloc(sizeof *i); 29 | struct f *f = malloc(sizeof *f); 30 | struct c *c = malloc(sizeof *c); 31 | if (!argc) { 32 | i->i8 = 1; 33 | f->d = 1; 34 | c->c = 1; 35 | } 36 | printf("%d %lf %c\n", i->i8, f->d, c->c); 37 | } 38 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized-types.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct i { 5 | int8_t i8; 6 | uint8_t u8; 7 | int32_t i32; 8 | uint32_t u32; 9 | int64_t i64; 10 | uint64_t u64; 11 | int *ip; 12 | }; 13 | 14 | struct f { 15 | float f; 16 | double d; 17 | double *dp; 18 | }; 19 | 20 | struct c { 21 | char c; 22 | char *s; 23 | char a[16]; 24 | }; 25 | 26 | int main(int argc, char *argv[]) { 27 | struct i i; 28 | struct f f; 29 | struct c c; 30 | if (!argc) { 31 | i.i8 = 1; 32 | f.d = 1; 33 | c.a[0] = 1; 34 | } 35 | printf("%d %lf %c\n", i.i8, f.d, c.a[0]); 36 | } 37 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized_exit_status.c: -------------------------------------------------------------------------------- 1 | // A simple C program that attempts to be punny 2 | // Written 23/2/2017 3 | // by Angela Finlayson (angf@cse.unsw.edu.au) 4 | // for COMP1511 Lab 01 Exercise 1 5 | 6 | #include 7 | 8 | int main(int argc, char *argv[]) { 9 | int a[2]; 10 | a[0] = 0; 11 | printf("Hello, it is good to C you!\n"); 12 | 13 | return a[argc]; 14 | } 15 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized_exit_status.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | int a[2]; 5 | a[0] = 0; 6 | std::cout << "Hello, it is good to C you!\n"; 7 | return a[argc]; 8 | } 9 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized_posix_spawn.c: -------------------------------------------------------------------------------- 1 | //dcc_flags=-fsanitize=valgrind 2 | #include 3 | int main(int argc, char *argv[]) { 4 | pid_t p; 5 | char *a[] = { (char *)"/bin/true", NULL }; 6 | posix_spawn_file_actions_t file_actions; 7 | if (argc != 1) { 8 | posix_spawn_file_actions_init(&file_actions); 9 | } 10 | posix_spawn(&p, a[0], &file_actions, NULL, a, NULL); 11 | } 12 | -------------------------------------------------------------------------------- /tests/run_time_errors/uninitialized_posix_spawnp.c: -------------------------------------------------------------------------------- 1 | //dcc_flags=-fsanitize=valgrind 2 | #include 3 | 4 | int main(int argc, char *argv[]) { 5 | pid_t p; 6 | char *a[] = { (char *)"/bin/true", NULL }; 7 | posix_spawn_file_actions_t file_actions; 8 | if (argc != 1) { 9 | posix_spawn_file_actions_init(&file_actions); 10 | } 11 | posix_spawnp(&p, a[0], &file_actions, NULL, a, NULL); 12 | } 13 | -------------------------------------------------------------------------------- /tests/run_time_errors/unterminated-strcmp.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | char i[2]; 5 | char j[2]; 6 | i[0] = 'H'; 7 | j[0] = 'H'; 8 | return strcmp(i, j); 9 | } 10 | -------------------------------------------------------------------------------- /tests/run_time_errors/unterminated-strcpy.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | char i[2]; 5 | char o[2]; 6 | i[0] = 'H'; 7 | strcpy(o, i); 8 | } 9 | -------------------------------------------------------------------------------- /tests/run_time_errors/unterminated-strlen.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | char i[2]; 5 | i[0] = 'H'; 6 | return strlen(i); 7 | } 8 | -------------------------------------------------------------------------------- /tests/run_time_errors/unterminated-strncmp.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | char i[2]; 5 | char j[2]; 6 | i[0] = 'H'; 7 | j[0] = 'H'; 8 | return strncmp(i, j, 2); 9 | } 10 | -------------------------------------------------------------------------------- /tests/run_time_errors/unterminated_strcat.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | char c = 'd'; 5 | char s[5]; 6 | strcat(s, &c); 7 | } 8 | -------------------------------------------------------------------------------- /tests/run_time_errors/unterminated_string.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | char str[10]; 5 | str[0] = 'H'; 6 | str[1] = 'i'; 7 | printf("%s", str); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /tests/run_time_errors/use_after_free.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | int *p = (int *)malloc(sizeof(int *)); 5 | *p = 1; 6 | if (argc > 0) { 7 | free(p); 8 | } 9 | return *p; 10 | } 11 | -------------------------------------------------------------------------------- /tests/run_time_errors/use_after_return.c: -------------------------------------------------------------------------------- 1 | //dcc_flags= 2 | //dcc_flags=--use-after-return 3 | 4 | #include 5 | 6 | int *f(int num) { 7 | int factors[50]; 8 | int count = 1; 9 | int localNum = num; 10 | for (int x = 2; x <= localNum - 1; x++) { 11 | if (num % x == 0) { 12 | factors[count] = x; 13 | count++; 14 | } 15 | } 16 | factors[0] = count; 17 | int *factorPointer = factors; 18 | if (num == 0) { 19 | factorPointer = NULL; 20 | } 21 | return factorPointer; 22 | } 23 | 24 | int main(void) { 25 | printf("%d\n", *f(50)); 26 | } 27 | -------------------------------------------------------------------------------- /tests/run_time_errors/write_null_stream.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) { 4 | fprintf(NULL, "Hello world\n"); 5 | } 6 | -------------------------------------------------------------------------------- /tests/run_time_errors/zero_size_array.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a[0]; 3 | return a[0]; 4 | } 5 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/check_exit_status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | temp_dir=$(mktemp -d /tmp/test_teaching_software.XXXXXXXXXX) || exit 1 3 | trap 'rm -fr $temp_dir' EXIT 4 | 5 | cat >$temp_dir/exit_42.c < 7 | int main(void) {exit(42);} 8 | eof 9 | 10 | cat >$temp_dir/return_42.c <&2 22 | done 23 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/empty_main.c: -------------------------------------------------------------------------------- 1 | //dcc_flags= 2 | //dcc_flags=-fsanitize=address 3 | //dcc_flags=--leak-check 4 | 5 | int main(void) { 6 | } 7 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/fclose.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | for (int i = 0; i < 50000; i++) { 5 | fclose(fopen(__FILE__, "r")); 6 | } 7 | FILE *f = fopen(__FILE__, "r"); 8 | int c; 9 | while ((c = fgetc(f)) != EOF) { 10 | putchar(c); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/fdopen.c: -------------------------------------------------------------------------------- 1 | //dcc_flags=-fsanitize=address,valgrind 2 | #include 3 | 4 | int main(void) { 5 | extern int open(const char *pathname, int flags); 6 | FILE *f = fdopen(open(__FILE__, 0), "r"); 7 | int c; 8 | while ((c = fgetc(f)) != EOF) { 9 | putchar(c); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/fileno.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) { 5 | assert(fileno(stdin) == 0); 6 | assert(fileno(stdout) == 1); 7 | assert(fileno(stderr) == 2); 8 | assert(fileno(fopen(__FILE__, "r")) == 3); 9 | } 10 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/fopen.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | FILE *f = fopen(__FILE__, "r"); 5 | int c; 6 | while ((c = fgetc(f)) != EOF) { 7 | putchar(c); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/freopen.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | freopen(__FILE__, "r", stdin); 5 | int c; 6 | while ((c = getchar()) != EOF) { 7 | putchar(c); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/no_leak_printf.c: -------------------------------------------------------------------------------- 1 | //dcc_flags=--leak-check 2 | 3 | #include 4 | 5 | int main(void) { 6 | printf("this causes a spurious memory leak with some libc versions\n"); 7 | } 8 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/no_leak_simple.c: -------------------------------------------------------------------------------- 1 | //dcc_flags=--leak-check 2 | 3 | #include 4 | 5 | int main(void) { 6 | int *p = malloc(sizeof(*p)); 7 | free(p); 8 | } 9 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/popen.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(void) { 3 | pclose(popen("echo popen", "w")); 4 | } 5 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/posix_spawn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main(void) { 4 | pid_t p; 5 | char *a[] = { "/bin/true", NULL }; 6 | assert(0 == posix_spawn(&p, a[0], NULL, NULL, a, NULL)); 7 | assert(0 == posix_spawnp(&p, "true", NULL, NULL, a, NULL)); 8 | } 9 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/print_path.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | temp_dir=$(mktemp -d /tmp/test_teaching_software.XXXXXXXXXX) || exit 1 3 | trap 'rm -fr $temp_dir' EXIT 4 | 5 | cat >$temp_dir/print_path.c < 7 | #include 8 | int main(void) { 9 | puts(getenv("PATH")); 10 | } 11 | eof 12 | 13 | "${dcc-dcc}" $temp_dir/print_path.c -o $temp_dir/print_path|| 14 | continue 15 | 16 | test_path="hello_dcc" 17 | stdout=$(PATH="$test_path" $temp_dir/print_path) 18 | 19 | test "$stdout" = "$test_path" && 20 | exit 0 21 | 22 | echo "$0: $source incorrect PATH '$stdout' versus '$test_path'" 1>&2 23 | exit 1 24 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/rename.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) { 5 | FILE *f = fopen("tmp.1", "w"); 6 | fclose(f); 7 | remove("tmp.2"); 8 | rename("tmp.1", "tmp.2"); 9 | assert(fopen("tmp.2", "r")); 10 | remove("tmp.2"); 11 | } 12 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/seek.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | FILE *f = fopen(__FILE__, "r"); 5 | fseek(f, -10, SEEK_END); 6 | int c; 7 | while ((c = fgetc(f)) != EOF) { 8 | putchar(c); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/string.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) { 5 | char a[40]; 6 | assert(a == strcpy(a, "hello")); 7 | assert(a == strcat(a, "there")); 8 | assert(strcmp("hellothere", a) == 0); 9 | assert(strlen(a) == 10); 10 | char b[40] = {0}; 11 | assert(b == strncpy(b, "hello", argc + 1)); 12 | assert(strcmp(b, "he") == 0); 13 | assert(b == strncat(b, "there", argc + 2)); 14 | assert(strcmp("hethe", b) == 0); 15 | assert(strncmp("hehe", b, 2) == 0); 16 | assert(strncmp("hehe", b, 3) < 0); 17 | char c[40]; 18 | assert(c + 5 == stpcpy(c, "hello")); 19 | assert(strcmp("hello", c) == 0); 20 | char d[40] = {0}; 21 | assert(d + argc + 1 == stpncpy(d, "hello", argc + 1)); 22 | assert(strcmp("he", d) == 0); 23 | assert(strspn("hello", "there") == 2); 24 | assert(strspn("hello", "HELLO") == 0); 25 | assert(strcspn("hello", "HELLO") == 5); 26 | } 27 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/synchronization-time.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) { 5 | exit(time(NULL) % 64); 6 | } 7 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/unistd_name_clash.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void read(void) { 4 | printf("hello world\n"); 5 | } 6 | 7 | int main(void) { 8 | read(); 9 | } 10 | -------------------------------------------------------------------------------- /tests/run_time_no_errors/unistd_use.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | extern int close(int fd); 5 | close(0); 6 | } 7 | -------------------------------------------------------------------------------- /tests/single_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | command -v "$dcc" > /dev/null || exit 1 4 | 5 | tmpdir=$(mktemp -d) 6 | trap 'cd /;rm -fr "$tmpdir"' EXIT 7 | 8 | quick="" 9 | if test "$1" == --quick 10 | then 11 | quick=1 12 | shift 13 | fi 14 | original_src_file="$1" 15 | 16 | rsync -a $(dirname $(readlink -f "$original_src_file"))/ $tmpdir/ 17 | src_file=$(basename "$1") 18 | cd $tmpdir 19 | # some values reported in errors are not determinate (e.g. variable addresses) 20 | # and will vary between execution and definitely between platforms 21 | # so delete them before diff-ing errors 22 | # 23 | # also remove absolute pathnames 24 | # so expected output is not filesystem location dependent 25 | # 26 | # and remove line/column numbers from error messages 27 | # so minor changes to tests do not affect expected output 28 | 29 | 30 | REMOVE_NON_DETERMINATE_VALUES=' 31 | s/^\([a-z].* = \)[0-9][0-9]*$/\1 /g 32 | s/0x[0-9a-f]*/0x/g 33 | s/-*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]*//g 34 | s?/tmp/[^ ]*\.o??g 35 | s?^/.*:?? 36 | s?^ *[0-9]* *|?? 37 | s?^ *~*\^~* *$?? 38 | s?clang-[0-9]*?clang? 39 | s?^\([^: ]*\):[0-9]*:[0-9]*:?\1? 40 | s? called at line [0-9]* of ? called at line ? 41 | s? at line [0-9]*:? at line:? 42 | s?: [0-9]* Killed?Killed? 43 | s?/[^ ]*/?/? 44 | s?tests.*/?? 45 | ' 46 | 47 | # don't change the name of the variable src_file some rely on it 48 | compile_options_list=$(egrep '^//dcc_flags=' "$src_file"|sed 's?//??;s/ /#/g') 49 | compile_options_list=${compile_options_list:-'dcc_flags=""'} 50 | 51 | case "$src_file" in 52 | *.cpp) compiler="$cpp_compiler";; 53 | *) compiler="$c_compiler" 54 | esac 55 | 56 | for compile_options in $compile_options_list 57 | do 58 | rm -f a.out tmp.actual_* 59 | compile_options=$(echo "$compile_options"|sed 's/#/ /g') 60 | case "$src_file" in 61 | *.c|*.cpp) 62 | dcc_flags= 63 | suffix=`echo $compile_options|sed 's/^dcc_flags=//;s/ /_/g;s/["$]//g;s/src_file//;s?/?_?g'` 64 | eval $compile_options 65 | expected_output_basename="`basename $src_file .c`$suffix" 66 | #echo "$dcc" --c-compiler=$compiler $dcc_flags "$src_file" 67 | "$dcc" --c-compiler=$compiler $dcc_flags "$src_file" 2>tmp.actual_stderr >/dev/null 68 | test ! -s tmp.actual_stderr && DCC_DEBUG=1 ./a.out >tmp.actual_stderr >tmp.actual_stdout 69 | ;; 70 | 71 | *.sh) 72 | expected_output_basename="`basename $src_file .sh`" 73 | $src_file tmp.actual_stderr >tmp.actual_stdout 74 | ;; 75 | 76 | *) 77 | echo Ignoring $src_file 78 | exit 0 79 | esac 80 | 81 | case "$original_src_file" in 82 | *no_error*) 83 | if test -s tmp.actual_stderr 84 | then 85 | echo FAILED: dcc $dcc_flags $original_src_file "# error messages" 86 | test -z "$quick" && 87 | cat tmp.actual_stderr 88 | exit 1 89 | fi 90 | actual_output_file=tmp.actual_stdout 91 | ;; 92 | *) 93 | if test ! -s tmp.actual_stderr 94 | then 95 | echo FAILED: dcc $dcc_flags $original_src_file "# no error messages" 96 | exit 1 97 | fi 98 | actual_output_file=tmp.actual_stderr 99 | esac 100 | sed -e "$REMOVE_NON_DETERMINATE_VALUES" "$actual_output_file" >tmp.corrected_output 101 | 102 | expected_output_dir="$tests_dir/expected_output/$expected_output_basename" 103 | mkdir -p "$expected_output_dir" 104 | expected_output_last_version=$(ls $expected_output_dir/*.txt 2>/dev/null|sed 1q) 105 | 106 | default_expected_output_dir="$tests_dir/expected_output/default" 107 | 108 | default_expected_output="$default_expected_output_dir/$expected_output_file" 109 | version_expected_output="$version_expected_output_dir/$expected_output_file" 110 | 111 | 112 | if test -z "$expected_output_last_version" 113 | then 114 | if test -n "$quick" 115 | then 116 | echo "NEW: $original_src_file " 117 | exit 0 118 | fi 119 | new_expected_output_file="$expected_output_dir/000000-clang-$clang_version-$platform.txt" 120 | echo 121 | echo "'$new_expected_output_file' does not exist, creating with these contents:" 122 | echo 123 | cat "$actual_output_file" 124 | cp "$actual_output_file" "$new_expected_output_file" 125 | echo 126 | echo "if above is not correct output for this test: rm '$new_expected_output_file' " 127 | continue 128 | fi 129 | 130 | # check if the output if we have matches any correct version 131 | passed= 132 | for expected_output_version in $expected_output_dir/*.txt 133 | do 134 | sed -e "$REMOVE_NON_DETERMINATE_VALUES" "$expected_output_version" >tmp.expected_output 135 | if diff -iBw tmp.expected_output tmp.corrected_output >/dev/null 136 | then 137 | echo Passed: dcc $dcc_flags $original_src_file 138 | # echo -n . 139 | passed=1 140 | break 141 | fi 142 | done 143 | test -n "$passed" && continue 144 | 145 | sed -e "$REMOVE_NON_DETERMINATE_VALUES" $expected_output_last_version >tmp.expected_output 146 | 147 | echo "FAILED: dcc $dcc_flags $original_src_file # error messages different to expected" 148 | test -n "$quick" && 149 | exit 1 150 | echo Differences are: 151 | echo 152 | diff --color -u -iBw tmp.expected_output tmp.corrected_output 153 | echo 154 | echo "Enter y to add this output to accepted versions." 155 | echo "Enter n to leave expected output versions unchanged." 156 | echo "Enter q to exit." 157 | 158 | echo -n "Action? " 159 | read response 160 | case "$response" in 161 | y*) 162 | last_version_number=$(basename $expected_output_last_version|cut -d- -f1) 163 | version_number=$(printf "%06d" $(($last_version_number + 1))) 164 | new_expected_output_file="$expected_output_dir/$version_number-clang-$clang_version-$platform.txt" 165 | cp -p "$actual_output_file" "$new_expected_output_file" 166 | ;; 167 | q) 168 | exit 2 169 | esac 170 | done 171 | -------------------------------------------------------------------------------- /tests/unused/infinite_recursion.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char *argv[]) { if (argc) return 1 + main(argc, argv);} 2 | -------------------------------------------------------------------------------- /unhandled_run_time_errors/copy_uninitialized_double_to_int.c: -------------------------------------------------------------------------------- 1 | int main(int argc, char *argv[]) { 2 | double d; 3 | int i; 4 | if (!argc) d = 0; 5 | if (!argc) d = 0; 6 | i = d; 7 | if (!argc) return i; 8 | } 9 | -------------------------------------------------------------------------------- /unhandled_run_time_errors/short_overflow.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) { 4 | short s = 0; 5 | for (int i = 0; i < 100000; i++) { 6 | s += argc; 7 | printf("%d\n", s); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /unhandled_run_time_errors/write_input_stream.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char **argv) { 4 | fprintf(fopen("/dev/null", "r"), "Hello world\n"); 5 | } 6 | -------------------------------------------------------------------------------- /wrapper_c/dcc_io.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define STDIOBUF_BUFFER_SIZE 8192 5 | #define STDIOBUF_PUSHBACK_MAX 4 6 | 7 | // redirect cin, cout, cerr to stdin, stdout, stderr 8 | // to allow dcc to synchronize across 9 | 10 | // similar code at http://ilab.usc.edu/rjpeters/groovx/stdiobuf_8cc-source.html 11 | // documentation at https://cplusplus.com/reference/streambuf/streambuf/ 12 | 13 | class stdiobuf: public std::streambuf { 14 | FILE *stdio_stream; 15 | char buffer[STDIOBUF_PUSHBACK_MAX + STDIOBUF_BUFFER_SIZE] = {0}; 16 | public: 17 | stdiobuf(FILE *f) { 18 | stdio_stream = f; 19 | char *b = buffer + STDIOBUF_PUSHBACK_MAX; 20 | setp(b, b); 21 | setg(buffer, b, b); 22 | } 23 | 24 | 25 | // input methods 26 | int underflow() { 27 | if (gptr() == egptr()) { 28 | char *b = buffer + STDIOBUF_PUSHBACK_MAX; 29 | // just get one character to avoid introducing inappropriate buffering 30 | // bufferring will still be happening in stdio 31 | int c = fgetc(stdio_stream); 32 | if (c != EOF) { 33 | b[0] = c; 34 | } 35 | setg(buffer, b, b + 1); 36 | } 37 | return gptr() == egptr() ? traits_type::eof() : traits_type::to_int_type(*gptr()); 38 | } 39 | 40 | // do we need to implement pbackfail? 41 | 42 | 43 | // output methods 44 | int overflow(int c) { 45 | if (c != EOF) { 46 | *pptr() = c; 47 | pbump(1); 48 | } 49 | return flush_buffer() == EOF ? EOF : traits_type::to_int_type(c); 50 | } 51 | 52 | int sync() { 53 | return flush_buffer() == EOF ? -1 : 0; 54 | } 55 | 56 | // helper function 57 | int flush_buffer() { 58 | const size_t num = pptr() - pbase(); 59 | if (fwrite(pbase(), 1, num, stdio_stream) != num) { 60 | return EOF; 61 | } 62 | pbump(-num); 63 | return num; 64 | } 65 | }; 66 | 67 | 68 | static std::streambuf *original_cin_streambuf; 69 | 70 | extern "C" void __dcc_replace_cin(FILE *stream) { 71 | original_cin_streambuf = std::cin.rdbuf(new stdiobuf(stream)); 72 | } 73 | 74 | extern "C" void __dcc_restore_cin(void) { 75 | if (original_cin_streambuf) { 76 | delete std::cin.rdbuf(original_cin_streambuf); 77 | } 78 | } 79 | 80 | 81 | static std::streambuf *original_cout_streambuf; 82 | 83 | extern "C" void __dcc_replace_cout(FILE *stream) { 84 | original_cout_streambuf = std::cout.rdbuf(new stdiobuf(stream)); 85 | } 86 | 87 | extern "C" void __dcc_restore_cout() { 88 | if (original_cout_streambuf) { 89 | std::cout << std::flush; 90 | delete std::cout.rdbuf(original_cout_streambuf); 91 | } 92 | } 93 | 94 | 95 | static std::streambuf *original_cerr_streambuf; 96 | 97 | extern "C" void __dcc_replace_cerr(FILE *stream) { 98 | original_cerr_streambuf = std::cerr.rdbuf(new stdiobuf(stream)); 99 | } 100 | 101 | extern "C" void __dcc_restore_cerr() { 102 | if (original_cerr_streambuf) { 103 | std::cerr << std::flush; 104 | delete std::cerr.rdbuf(original_cerr_streambuf); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /wrapper_c/dcc_save_stdin.c: -------------------------------------------------------------------------------- 1 | #if __SAVE_STDIN_BUFFER_SIZE__ 2 | 3 | unsigned int __dcc_save_stdin_buffer_size = __SAVE_STDIN_BUFFER_SIZE__; 4 | unsigned int __dcc_save_stdin_n_bytes_seen = 0; 5 | char __dcc_save_stdin_buffer[__SAVE_STDIN_BUFFER_SIZE__]; 6 | 7 | static void __dcc_save_stdin(const char *buf, size_t size) { 8 | for (size_t i = 0; i < size; i++) { 9 | __dcc_save_stdin_buffer[__dcc_save_stdin_n_bytes_seen++ % __SAVE_STDIN_BUFFER_SIZE__] = buf[i]; 10 | } 11 | debug_printf(3, "__dcc_save_stdin_buffer %d\n", (int)__dcc_save_stdin_n_bytes_seen); 12 | } 13 | 14 | #else 15 | 16 | static void __dcc_save_stdin(const char *buf, size_t size) { 17 | (void)buf; // avoid unused parameter warning 18 | (void)size; // avoid unused parameter warning 19 | } 20 | 21 | #endif 22 | --------------------------------------------------------------------------------