├── .github └── workflows │ ├── check_autogen_files.yml │ ├── test_all_commits.yaml │ └── test_tests.yaml ├── .gitignore ├── LICENSE ├── README.md ├── expected_results.json ├── gen_from_templates.py ├── generate_expected_results.py ├── templates ├── chapter_20_templates │ ├── alignment_check_wrapper.s.jinja │ ├── bin_uses_operands.c.jinja │ ├── briggs_coalesce.c.jinja │ ├── clobber_xmm_regs.s.jinja │ ├── division_interference.c.jinja │ ├── division_uses_ax.c.jinja │ ├── force_spill.c.jinja │ ├── fourteen_pseudos_interfere.c.jinja │ ├── funcall_generates_args.c.jinja │ ├── george_coalesce.c.jinja │ ├── george_off_by_one.c.jinja │ ├── reg_live_at_exit.c.jinja │ ├── rewrite_regression_test.c.jinja │ ├── twelve_pseudos_interfere.c.jinja │ ├── use_all_hardregs.c.jinja │ └── wrapper.s.jinja ├── includes │ ├── regalloc_macros.c.jinja │ ├── spill_var.c.jinja │ ├── twelve_regs_conflict.c.jinja │ ├── twelve_regs_conflict_validation.c.jinja │ └── wrapper_base.s.jinja ├── pre_ch20_spill_var.c.jinja ├── stack_alignment_check.s.jinja └── validate_return_pointer.s.jinja ├── test_compiler ├── test_framework ├── __init__.py ├── basic.py ├── parser │ ├── __init__.py │ ├── asm.py │ ├── parse.py │ └── tokenize.py ├── regalloc.py ├── runner.py ├── tacky │ ├── __init__.py │ ├── common.py │ ├── const_fold.py │ ├── copy_prop.py │ ├── dead_store_elim.py │ ├── pipeline.py │ ├── suite.py │ └── unreachable.py └── test_tests │ ├── __init__.py │ ├── test_parse.py │ ├── test_programs.py │ ├── test_tokenize.py │ └── test_toplevel.py ├── test_properties.json └── tests ├── chapter_1 ├── invalid_lex │ ├── at_sign.c │ ├── backslash.c │ ├── backtick.c │ ├── invalid_identifier.c │ └── invalid_identifier_2.c ├── invalid_parse │ ├── end_before_expr.c │ ├── extra_junk.c │ ├── invalid_function_name.c │ ├── keyword_wrong_case.c │ ├── missing_type.c │ ├── misspelled_keyword.c │ ├── no_semicolon.c │ ├── not_expression.c │ ├── space_in_keyword.c │ ├── switched_parens.c │ ├── unclosed_brace.c │ └── unclosed_paren.c └── valid │ ├── multi_digit.c │ ├── newlines.c │ ├── no_newlines.c │ ├── return_0.c │ ├── return_2.c │ ├── spaces.c │ └── tabs.c ├── chapter_10 ├── invalid_declarations │ ├── conflicting_local_declarations.c │ ├── extern_follows_local_var.c │ ├── extern_follows_static_local_var.c │ ├── local_var_follows_extern.c │ ├── out_of_scope_extern_var.c │ ├── redefine_param_as_identifier_with_linkage.c │ └── undeclared_global_variable.c ├── invalid_labels │ └── extra_credit │ │ └── goto_global_var.c ├── invalid_parse │ ├── extern_param.c │ ├── extra_credit │ │ ├── extern_label.c │ │ ├── file_scope_label.c │ │ └── static_label.c │ ├── missing_parameter_list.c │ ├── missing_type_specifier.c │ ├── multi_storage_class_fun.c │ ├── multi_storage_class_var.c │ ├── static_and_extern.c │ └── static_param.c ├── invalid_types │ ├── conflicting_function_linkage.c │ ├── conflicting_function_linkage_2.c │ ├── conflicting_global_definitions.c │ ├── conflicting_variable_linkage.c │ ├── conflicting_variable_linkage_2.c │ ├── extern_for_loop_counter.c │ ├── extern_variable_initializer.c │ ├── extra_credit │ │ └── static_var_case.c │ ├── non_constant_static_initializer.c │ ├── non_constant_static_local_initializer.c │ ├── redeclare_file_scope_var_as_fun.c │ ├── redeclare_fun_as_file_scope_var.c │ ├── redeclare_fun_as_var.c │ ├── static_block_scope_function_declaration.c │ ├── static_for_loop_counter.c │ └── use_file_scope_variable_as_fun.c └── valid │ ├── data_on_page_boundary_linux.s │ ├── data_on_page_boundary_osx.s │ ├── distinct_local_and_extern.c │ ├── extern_block_scope_variable.c │ ├── extra_credit │ ├── bitwise_ops_file_scope_vars.c │ ├── compound_assignment_static_var.c │ ├── goto_skip_static_initializer.c │ ├── increment_global_vars.c │ ├── label_file_scope_var_same_name.c │ ├── label_static_var_same_name.c │ ├── libraries │ │ ├── same_label_same_fun.c │ │ └── same_label_same_fun_client.c │ ├── switch_on_extern.c │ ├── switch_skip_extern_decl.c │ └── switch_skip_static_initializer.c │ ├── libraries │ ├── external_linkage_function.c │ ├── external_linkage_function_client.c │ ├── external_tentative_var.c │ ├── external_tentative_var_client.c │ ├── external_var_scoping.c │ ├── external_var_scoping_client.c │ ├── external_variable.c │ ├── external_variable_client.c │ ├── internal_hides_external_linkage.c │ ├── internal_hides_external_linkage_client.c │ ├── internal_linkage_function.c │ ├── internal_linkage_function_client.c │ ├── internal_linkage_var.c │ └── internal_linkage_var_client.c │ ├── multiple_static_file_scope_vars.c │ ├── multiple_static_local.c │ ├── push_arg_on_page_boundary.c │ ├── shadow_static_local_var.c │ ├── static_local_multiple_scopes.c │ ├── static_local_uninitialized.c │ ├── static_recursive_call.c │ ├── static_then_extern.c │ ├── static_variables_in_expressions.c │ ├── tentative_definition.c │ └── type_before_storage_class.c ├── chapter_11 ├── invalid_labels │ └── extra_credit │ │ ├── bitshift_duplicate_cases.c │ │ ├── switch_duplicate_cases.c │ │ └── switch_duplicate_cases_2.c ├── invalid_lex │ ├── invalid_suffix.c │ └── invalid_suffix2.c ├── invalid_parse │ ├── bad_specifiers.c │ ├── empty_cast.c │ ├── fun_name_long.c │ ├── invalid_cast.c │ ├── invalid_suffix.c │ ├── long_constant_as_var.c │ ├── missing_cast_parentheses.c │ └── var_name_long.c ├── invalid_types │ ├── call_long_as_function.c │ ├── cast_lvalue.c │ ├── conflicting_function_types.c │ ├── conflicting_global_types.c │ └── conflicting_variable_types.c └── valid │ ├── explicit_casts │ ├── sign_extend.c │ └── truncate.c │ ├── extra_credit │ ├── bitshift.c │ ├── bitwise_long_op.c │ ├── compound_assign_to_int.c │ ├── compound_assign_to_long.c │ ├── compound_bitshift.c │ ├── compound_bitwise.c │ ├── increment_long.c │ ├── switch_int.c │ └── switch_long.c │ ├── implicit_casts │ ├── common_type.c │ ├── convert_by_assignment.c │ ├── convert_function_arguments.c │ ├── convert_static_initializer.c │ └── long_constants.c │ ├── libraries │ ├── long_args.c │ ├── long_args_client.c │ ├── long_global_var.c │ ├── long_global_var_client.c │ ├── maintain_stack_alignment.c │ ├── maintain_stack_alignment_client.c │ ├── return_long.c │ └── return_long_client.c │ └── long_expressions │ ├── arithmetic_ops.c │ ├── assign.c │ ├── comparisons.c │ ├── large_constants.c │ ├── logical.c │ ├── long_and_int_locals.c │ ├── long_args.c │ ├── multi_op.c │ ├── return_long.c │ ├── rewrite_large_multiply_regression.c │ ├── simple.c │ ├── static_long.c │ └── type_specifiers.c ├── chapter_12 ├── invalid_labels │ └── extra_credit │ │ └── switch_duplicate_cases.c ├── invalid_lex │ ├── invalid_suffix.c │ └── invalid_suffix_2.c ├── invalid_parse │ ├── bad_specifiers.c │ └── bad_specifiers_2.c ├── invalid_types │ ├── conflicting_signed_unsigned.c │ └── conflicting_uint_ulong.c └── valid │ ├── explicit_casts │ ├── chained_casts.c │ ├── extension.c │ ├── rewrite_movz_regression.c │ ├── round_trip_casts.c │ ├── same_size_conversion.c │ └── truncate.c │ ├── extra_credit │ ├── bitwise_unsigned_ops.c │ ├── bitwise_unsigned_shift.c │ ├── compound_assign_uint.c │ ├── compound_bitshift.c │ ├── compound_bitwise.c │ ├── postfix_precedence.c │ ├── switch_uint.c │ └── unsigned_incr_decr.c │ ├── implicit_casts │ ├── common_type.c │ ├── convert_by_assignment.c │ ├── promote_constants.c │ └── static_initializers.c │ ├── libraries │ ├── unsigned_args.c │ ├── unsigned_args_client.c │ ├── unsigned_global_var.c │ └── unsigned_global_var_client.c │ ├── type_specifiers │ ├── signed_type_specifiers.c │ └── unsigned_type_specifiers.c │ └── unsigned_expressions │ ├── arithmetic_ops.c │ ├── arithmetic_wraparound.c │ ├── comparisons.c │ ├── locals.c │ ├── logical.c │ ├── simple.c │ └── static_variables.c ├── chapter_13 ├── helper_libs │ └── nan.c ├── invalid_lex │ ├── another_bad_constant.c │ ├── bad_exponent_suffix.c │ ├── malformed_const.c │ ├── malformed_exponent.c │ ├── missing_exponent.c │ ├── missing_negative_exponent.c │ └── yet_another_bad_constant.c ├── invalid_parse │ ├── invalid_type_specifier.c │ └── invalid_type_specifier_2.c ├── invalid_types │ ├── complement_double.c │ ├── extra_credit │ │ ├── bitwise_and.c │ │ ├── bitwise_or.c │ │ ├── bitwise_shift_double.c │ │ ├── bitwise_shift_double_2.c │ │ ├── bitwise_xor.c │ │ ├── compound_bitwise_and.c │ │ ├── compound_bitwise_xor.c │ │ ├── compound_left_bitshift.c │ │ ├── compound_mod.c │ │ ├── compound_mod_2.c │ │ ├── compound_right_bitshift.c │ │ ├── switch_double_case.c │ │ └── switch_on_double.c │ ├── mod_double.c │ └── mod_double_2.c └── valid │ ├── constants │ ├── constant_doubles.c │ └── round_constants.c │ ├── explicit_casts │ ├── cvttsd2si_rewrite.c │ ├── double_to_signed.c │ ├── double_to_unsigned.c │ ├── rewrite_cvttsd2si_regression.c │ ├── signed_to_double.c │ └── unsigned_to_double.c │ ├── extra_credit │ ├── compound_assign.c │ ├── compound_assign_implicit_cast.c │ ├── incr_and_decr.c │ ├── nan.c │ ├── nan_compound_assign.c │ └── nan_incr_and_decr.c │ ├── floating_expressions │ ├── arithmetic_ops.c │ ├── comparisons.c │ ├── logical.c │ ├── loop_controlling_expression.c │ ├── simple.c │ └── static_initialized_double.c │ ├── function_calls │ ├── double_and_int_parameters.c │ ├── double_and_int_params_recursive.c │ ├── double_parameters.c │ ├── push_xmm.c │ ├── return_double.c │ ├── standard_library_call.c │ └── use_arg_after_fun_call.c │ ├── implicit_casts │ ├── common_type.c │ ├── complex_arithmetic_common_type.c │ ├── convert_for_assignment.c │ └── static_initializers.c │ ├── libraries │ ├── double_and_int_params_recursive.c │ ├── double_and_int_params_recursive_client.c │ ├── double_parameters.c │ ├── double_parameters_client.c │ ├── double_params_and_result.c │ ├── double_params_and_result_client.c │ ├── extern_double.c │ ├── extern_double_client.c │ ├── use_arg_after_fun_call.c │ └── use_arg_after_fun_call_client.c │ └── special_values │ ├── infinity.c │ ├── negative_zero.c │ └── subnormal_not_zero.c ├── chapter_14 ├── invalid_declarations │ └── extra_credit │ │ ├── addr_of_label.c │ │ └── deref_label.c ├── invalid_parse │ ├── abstract_function_declarator.c │ ├── cast_to_declarator.c │ ├── malformed_abstract_declarator.c │ ├── malformed_declarator.c │ ├── malformed_function_declarator.c │ └── malformed_function_declarator_2.c ├── invalid_types │ ├── address_of_address.c │ ├── address_of_assignment.c │ ├── address_of_constant.c │ ├── address_of_ternary.c │ ├── assign_int_to_pointer.c │ ├── assign_int_var_to_pointer.c │ ├── assign_to_address.c │ ├── assign_wrong_pointer_type.c │ ├── bad_null_pointer_constant.c │ ├── cast_double_to_pointer.c │ ├── cast_pointer_to_double.c │ ├── compare_mixed_pointer_types.c │ ├── compare_pointer_to_ulong.c │ ├── complement_pointer.c │ ├── dereference_non_pointer.c │ ├── divide_pointer.c │ ├── extra_credit │ │ ├── bitwise_and_pointer.c │ │ ├── bitwise_compound_assign_to_pointer.c │ │ ├── bitwise_compound_assign_with_pointer.c │ │ ├── bitwise_lshift_pointer.c │ │ ├── bitwise_or_pointer.c │ │ ├── bitwise_rshift_pointer.c │ │ ├── bitwise_xor_pointer.c │ │ ├── compound_assign_thru_ptr_not_lval.c │ │ ├── compound_assignment_not_lval.c │ │ ├── compound_divide_pointer.c │ │ ├── compound_mod_pointer.c │ │ ├── compound_multiply_pointer.c │ │ ├── postfix_decr_not_lvalue.c │ │ ├── prefix_incr_not_lvalue.c │ │ └── switch_on_pointer.c │ ├── invalid_pointer_initializer.c │ ├── invalid_static_initializer.c │ ├── multiply_pointers.c │ ├── multiply_pointers_2.c │ ├── negate_pointer.c │ ├── pass_pointer_as_int.c │ ├── return_wrong_pointer_type.c │ └── ternary_mixed_pointer_types.c └── valid │ ├── casts │ ├── cast_between_pointer_types.c │ ├── null_pointer_conversion.c │ └── pointer_int_casts.c │ ├── comparisons │ ├── compare_pointers.c │ ├── compare_to_null.c │ └── pointers_as_conditions.c │ ├── declarators │ ├── abstract_declarators.c │ ├── declarators.c │ └── declare_pointer_in_for_loop.c │ ├── dereference │ ├── address_of_dereference.c │ ├── dereference_expression_result.c │ ├── multilevel_indirection.c │ ├── read_through_pointers.c │ ├── simple.c │ ├── static_var_indirection.c │ └── update_through_pointers.c │ ├── extra_credit │ ├── bitshift_dereferenced_ptrs.c │ ├── bitwise_ops_with_dereferenced_ptrs.c │ ├── compound_assign_conversion.c │ ├── compound_assign_through_pointer.c │ ├── compound_bitwise_dereferenced_ptrs.c │ ├── eval_compound_lhs_once.c │ ├── incr_and_decr_through_pointer.c │ └── switch_dereferenced_pointer.c │ ├── function_calls │ ├── address_of_argument.c │ ├── return_pointer.c │ └── update_value_through_pointer_parameter.c │ └── libraries │ ├── global_pointer.c │ ├── global_pointer_client.c │ ├── static_pointer.c │ └── static_pointer_client.c ├── chapter_15 ├── invalid_parse │ ├── array_of_functions.c │ ├── array_of_functions_2.c │ ├── double_declarator.c │ ├── empty_initializer_list.c │ ├── malformed_abstract_array_declarator.c │ ├── malformed_abstract_array_declarator_2.c │ ├── malformed_array_declarator.c │ ├── malformed_array_declarator_2.c │ ├── malformed_array_declarator_3.c │ ├── malformed_type_name.c │ ├── malformed_type_name_2.c │ ├── mismatched_subscript.c │ ├── negative_array_dimension.c │ ├── parenthesized_array_of_functions.c │ ├── return_array.c │ ├── unclosed_initializer.c │ ├── unclosed_nested_initializer.c │ └── unclosed_subscript.c ├── invalid_types │ ├── add_two_pointers.c │ ├── assign_incompatible_pointer_types.c │ ├── assign_to_array.c │ ├── assign_to_array_2.c │ ├── assign_to_array_3.c │ ├── bad_arg_type.c │ ├── cast_to_array_type.c │ ├── cast_to_array_type_2.c │ ├── cast_to_array_type_3.c │ ├── compare_different_pointer_types.c │ ├── compare_explicit_and_implict_addr.c │ ├── compare_pointer_to_int.c │ ├── compare_pointer_to_zero.c │ ├── compound_initializer_for_scalar.c │ ├── compound_initializer_for_static_scalar.c │ ├── compound_initializer_too_long_static.c │ ├── compound_inititializer_too_long.c │ ├── conflicting_array_declarations.c │ ├── conflicting_function_declarations.c │ ├── double_subscript.c │ ├── extra_credit │ │ ├── compound_add_double_to_pointer.c │ │ ├── compound_add_two_pointers.c │ │ ├── compound_assign_to_array.c │ │ ├── compound_assign_to_nested_array.c │ │ ├── compound_sub_pointer_from_int.c │ │ ├── postfix_incr_array.c │ │ ├── postfix_incr_nested_array.c │ │ ├── prefix_decr_array.c │ │ ├── prefix_decr_nested_array.c │ │ └── switch_on_array.c │ ├── function_returns_array.c │ ├── incompatible_elem_type_compound_init.c │ ├── incompatible_elem_type_static_compound_init.c │ ├── null_ptr_array_initializer.c │ ├── null_ptr_static_array_initializer.c │ ├── scalar_initializer_for_array.c │ ├── scalar_initializer_for_static_array.c │ ├── static_non_const_array.c │ ├── sub_different_pointer_types.c │ ├── sub_double_from_ptr.c │ ├── sub_ptr_from_int.c │ ├── subscript_both_pointers.c │ └── subscript_non_ptr.c └── valid │ ├── allocation │ └── test_alignment.c │ ├── casts │ ├── cast_array_of_pointers.c │ ├── implicit_and_explicit_conversions.c │ └── multi_dim_casts.c │ ├── declarators │ ├── array_as_argument.c │ ├── big_array.c │ ├── equivalent_declarators.c │ ├── for_loop_array.c │ └── return_nested_array.c │ ├── extra_credit │ ├── bitwise_subscript.c │ ├── compound_assign_and_increment.c │ ├── compound_assign_array_of_pointers.c │ ├── compound_assign_to_nested_subscript.c │ ├── compound_assign_to_subscripted_val.c │ ├── compound_bitwise_subscript.c │ ├── compound_lval_evaluated_once.c │ ├── compound_nested_pointer_assignment.c │ ├── compound_pointer_assignment.c │ ├── incr_and_decr_nested_pointers.c │ ├── incr_and_decr_pointers.c │ ├── incr_decr_subscripted_vals.c │ └── postfix_prefix_precedence.c │ ├── initialization │ ├── automatic.c │ ├── automatic_nested.c │ ├── static.c │ ├── static_nested.c │ └── trailing_comma_initializer.c │ ├── libraries │ ├── global_array.c │ ├── global_array_client.c │ ├── return_pointer_to_array.c │ ├── return_pointer_to_array_client.c │ ├── set_array_val.c │ └── set_array_val_client.c │ ├── pointer_arithmetic │ ├── add_dereference_and_assign.c │ ├── compare.c │ ├── pointer_add.c │ └── pointer_diff.c │ └── subscripting │ ├── addition_subscript_equivalence.c │ ├── array_of_pointers_to_arrays.c │ ├── complex_operands.c │ ├── simple.c │ ├── simple_subscripts.c │ ├── subscript_nested.c │ ├── subscript_pointer.c │ └── subscript_precedence.c ├── chapter_16 ├── invalid_labels │ └── extra_credit │ │ └── duplicate_case_char_const.c ├── invalid_lex │ ├── char_bad_escape_sequence.c │ ├── newline.c │ ├── string_bad_escape_sequence.c │ ├── unescaped_backslash.c │ ├── unescaped_double_quote.c │ ├── unescaped_single_quote.c │ ├── unterminated_char_constant.c │ └── unterminated_string.c ├── invalid_parse │ ├── extra_credit │ │ ├── character_const_goto.c │ │ ├── character_const_label.c │ │ ├── string_literal_goto.c │ │ └── string_literal_label.c │ ├── invalid_type_specifier.c │ ├── invalid_type_specifier_2.c │ ├── misplaced_char_literal.c │ └── string_literal_varname.c ├── invalid_types │ ├── assign_to_string_literal.c │ ├── char_and_schar_conflict.c │ ├── char_and_uchar_conflict.c │ ├── compound_initializer_for_pointer.c │ ├── extra_credit │ │ ├── bit_shift_string.c │ │ ├── bitwise_operation_on_string.c │ │ ├── case_statement_string.c │ │ ├── compound_assign_from_string.c │ │ ├── compound_assign_to_string.c │ │ ├── postfix_incr_string.c │ │ ├── prefix_incr_string.c │ │ └── switch_on_string.c │ ├── implicit_conversion_between_char_pointers.c │ ├── implicit_conversion_pointers_to_different_size_arrays.c │ ├── negate_char_pointer.c │ ├── string_initializer_for_multidim_array.c │ ├── string_initializer_too_long.c │ ├── string_initializer_too_long_nested.c │ ├── string_initializer_too_long_nested_static.c │ ├── string_initializer_too_long_static.c │ ├── string_initializer_wrong_type.c │ ├── string_initializer_wrong_type_nested.c │ ├── string_initializer_wrong_type_nested_static.c │ ├── string_literal_is_plain_char_pointer.c │ └── string_literal_is_plain_char_pointer_static.c └── valid │ ├── char_constants │ ├── char_constant_operations.c │ ├── control_characters.c │ ├── escape_sequences.c │ └── return_char_constant.c │ ├── chars │ ├── access_through_char_pointer.c │ ├── chained_casts.c │ ├── char_arguments.c │ ├── char_expressions.c │ ├── common_type.c │ ├── convert_by_assignment.c │ ├── data_on_page_boundary_linux.s │ ├── data_on_page_boundary_osx.s │ ├── explicit_casts.c │ ├── integer_promotion.c │ ├── partial_initialization.c │ ├── push_arg_on_page_boundary.c │ ├── return_char.c │ ├── rewrite_movz_regression.c │ ├── static_initializers.c │ └── type_specifiers.c │ ├── extra_credit │ ├── bitshift_chars.c │ ├── bitwise_ops_character_constants.c │ ├── bitwise_ops_chars.c │ ├── char_consts_as_cases.c │ ├── compound_assign_chars.c │ ├── compound_bitwise_ops_chars.c │ ├── incr_decr_chars.c │ ├── incr_decr_unsigned_chars.c │ ├── promote_switch_cond.c │ ├── promote_switch_cond_2.c │ └── switch_on_char_const.c │ ├── libraries │ ├── char_arguments.c │ ├── char_arguments_client.c │ ├── global_char.c │ ├── global_char_client.c │ ├── return_char.c │ └── return_char_client.c │ ├── strings_as_initializers │ ├── adjacent_strings_in_initializer.c │ ├── array_init_special_chars.c │ ├── literals_and_compound_initializers.c │ ├── partial_initialize_via_string.c │ ├── simple.c │ ├── terminating_null_bytes.c │ ├── test_alignment.c │ ├── transfer_by_eightbyte.c │ └── write_to_array.c │ └── strings_as_lvalues │ ├── addr_of_string.c │ ├── adjacent_strings.c │ ├── array_of_strings.c │ ├── cast_string_pointer.c │ ├── empty_string.c │ ├── pointer_operations.c │ ├── simple.c │ ├── standard_library_calls.c │ ├── string_special_characters.c │ └── strings_in_function_calls.c ├── chapter_17 ├── invalid_parse │ ├── bad_specifier.c │ ├── bad_specifier_2.c │ ├── sizeof_cast.c │ └── sizeof_type_no_parens.c ├── invalid_types │ ├── extra_credit │ │ ├── bitshift_void.c │ │ ├── bitwise_void.c │ │ ├── compound_add_void_pointer.c │ │ ├── compound_sub_void_pointer.c │ │ ├── compound_void_rval.c │ │ ├── compound_void_rval_add.c │ │ ├── compound_void_rval_bitshift.c │ │ ├── postfix_decr_void.c │ │ ├── postfix_decr_void_pointer.c │ │ ├── postfix_incr_void_pointer.c │ │ ├── prefix_decr_void_pointer.c │ │ ├── prefix_incr_void.c │ │ ├── prefix_incr_void_pointer.c │ │ └── switch_void.c │ ├── incomplete_types │ │ ├── add_void_pointer.c │ │ ├── sizeof_function.c │ │ ├── sizeof_void.c │ │ ├── sizeof_void_array.c │ │ ├── sizeof_void_expression.c │ │ ├── sub_void_pointer.c │ │ ├── subscript_void.c │ │ ├── subscript_void_pointer_conditional.c │ │ ├── void_array.c │ │ ├── void_array_in_cast.c │ │ ├── void_array_in_param_type.c │ │ ├── void_array_nested_in_declaration.c │ │ ├── void_array_pointer_in_declaration.c │ │ └── void_array_pointer_in_param_type.c │ ├── pointer_conversions │ │ ├── compare_void_ptr_to_int.c │ │ ├── compare_void_to_other_pointer.c │ │ ├── convert_ulong_to_void_ptr.c │ │ ├── convert_void_ptr_to_int.c │ │ └── usual_arithmetic_conversions_ptr.c │ ├── scalar_expressions │ │ ├── and_void.c │ │ ├── cast_void.c │ │ ├── not_void.c │ │ ├── or_void.c │ │ ├── void_condition_do_loop.c │ │ ├── void_condition_for_loop.c │ │ ├── void_condition_while_loop.c │ │ ├── void_if_condition.c │ │ └── void_ternary_condition.c │ └── void │ │ ├── assign_to_void_lvalue.c │ │ ├── assign_to_void_var.c │ │ ├── assign_void_rval.c │ │ ├── define_void.c │ │ ├── initialized_void.c │ │ ├── mismatched_conditional.c │ │ ├── negate_void.c │ │ ├── no_return_value.c │ │ ├── non_void_return.c │ │ ├── return_void_as_pointer.c │ │ ├── subscript_void.c │ │ ├── void_compare.c │ │ ├── void_equality.c │ │ └── void_fun_params.c └── valid │ ├── extra_credit │ ├── sizeof_bitwise.c │ ├── sizeof_compound.c │ ├── sizeof_compound_bitwise.c │ └── sizeof_incr.c │ ├── libraries │ ├── pass_alloced_memory.c │ ├── pass_alloced_memory_client.c │ ├── sizeof_extern.c │ ├── sizeof_extern_client.c │ ├── test_for_memory_leaks.c │ └── test_for_memory_leaks_client.c │ ├── sizeof │ ├── simple.c │ ├── sizeof_array.c │ ├── sizeof_basic_types.c │ ├── sizeof_consts.c │ ├── sizeof_derived_types.c │ ├── sizeof_expressions.c │ ├── sizeof_not_evaluated.c │ └── sizeof_result_is_ulong.c │ ├── void │ ├── cast_to_void.c │ ├── ternary.c │ ├── void_for_loop.c │ └── void_function.c │ └── void_pointer │ ├── array_of_pointers_to_void.c │ ├── common_pointer_type.c │ ├── conversion_by_assignment.c │ ├── explicit_cast.c │ ├── memory_management_functions.c │ └── simple.c ├── chapter_18 ├── invalid_lex │ ├── dot_bad_token.c │ └── dot_bad_token_2.c ├── invalid_parse │ ├── arrow_missing_member.c │ ├── dot_invalid_member.c │ ├── dot_no_left_expr.c │ ├── dot_operator_in_declarator.c │ ├── empty_initializer_list.c │ ├── extra_credit │ │ ├── case_struct_decl.c │ │ ├── default_kw_member_name.c │ │ ├── goto_kw_struct_tag.c │ │ ├── label_inside_struct_decl.c │ │ ├── labeled_struct_decl.c │ │ ├── struct_union.c │ │ ├── two_union_kws.c │ │ ├── union_bad_type_spec.c │ │ ├── union_decl_bad_type_specifier.c │ │ ├── union_decl_empty_member_list.c │ │ ├── union_decl_extra_semicolon.c │ │ ├── union_empty_initializer.c │ │ ├── union_member_initializer.c │ │ ├── union_member_is_function.c │ │ ├── union_member_name_kw.c │ │ ├── union_member_no_declarator.c │ │ ├── union_member_no_type.c │ │ ├── union_member_storage_class.c │ │ ├── union_struct_tag.c │ │ ├── union_two_tags.c │ │ ├── union_var_bad_tag.c │ │ └── union_var_tag_paren.c │ ├── misplaced_storage_class.c │ ├── struct_decl_double_semicolon.c │ ├── struct_decl_empty_member_list.c │ ├── struct_decl_extra_semicolon.c │ ├── struct_decl_kw_wrong_order.c │ ├── struct_decl_missing_end_semicolon.c │ ├── struct_decl_tag_kw.c │ ├── struct_decl_two_kws.c │ ├── struct_member_initializer.c │ ├── struct_member_is_function.c │ ├── struct_member_name_kw.c │ ├── struct_member_no_declarator.c │ ├── struct_member_no_semicolon.c │ ├── struct_member_no_type.c │ ├── struct_member_storage_class.c │ ├── var_decl_bad_tag_1.c │ ├── var_decl_bad_tag_2.c │ ├── var_decl_bad_type_specifier.c │ ├── var_decl_missing_struct_kw.c │ ├── var_decl_two_struct_kws.c │ └── var_decl_two_tags.c ├── invalid_struct_tags │ ├── array_of_undeclared.c │ ├── cast_undeclared.c │ ├── deref_undeclared.c │ ├── extra_credit │ │ ├── sizeof_undeclared_union.c │ │ └── var_undeclared_union_type.c │ ├── file_scope_var_type_undeclared.c │ ├── for_loop_scope.c │ ├── for_loop_scope_2.c │ ├── member_type_undeclared.c │ ├── param_undeclared.c │ ├── return_type_undeclared.c │ ├── sizeof_undeclared.c │ └── var_type_undeclared.c ├── invalid_types │ ├── extra_credit │ │ ├── README.md │ │ ├── bad_union_member_access │ │ │ ├── nested_non_member.c │ │ │ ├── union_bad_member.c │ │ │ └── union_bad_pointer_member.c │ │ ├── incompatible_union_types │ │ │ ├── assign_different_union_type.c │ │ │ ├── assign_scalar_to_union.c │ │ │ ├── return_type_mismatch.c │ │ │ ├── union_branch_mismatch.c │ │ │ └── union_pointer_branch_mismatch.c │ │ ├── incomplete_unions │ │ │ ├── define_incomplete_union.c │ │ │ └── sizeof_incomplete_union_type.c │ │ ├── invalid_union_lvalues │ │ │ ├── address_of_non_lvalue_union_member.c │ │ │ └── assign_non_lvalue_union_member.c │ │ ├── other_features │ │ │ ├── bitwise_op_structure.c │ │ │ ├── compound_assign_struct_rval.c │ │ │ ├── compound_assign_to_nested_struct.c │ │ │ ├── compound_assign_to_struct.c │ │ │ ├── duplicate_struct_types_after_label.c │ │ │ ├── postfix_decr_struct_arrow.c │ │ │ ├── postfix_incr_struct.c │ │ │ ├── prefix_decr_struct.c │ │ │ ├── prefix_incr_nested_struct.c │ │ │ └── switch_on_struct.c │ │ ├── scalar_required │ │ │ ├── cast_between_unions.c │ │ │ ├── cast_union_to_int.c │ │ │ ├── compare_unions.c │ │ │ ├── switch_on_union.c │ │ │ └── union_as_controlling_expression.c │ │ ├── union_initializers │ │ │ ├── initializer_too_long.c │ │ │ ├── nested_init_wrong_type.c │ │ │ ├── nested_union_init_too_long.c │ │ │ ├── scalar_union_initializer.c │ │ │ ├── static_aggregate_init_wrong_type.c │ │ │ ├── static_nested_init_not_const.c │ │ │ ├── static_nested_init_too_long.c │ │ │ ├── static_scalar_union_initializer.c │ │ │ ├── static_too_long.c │ │ │ ├── static_union_init_not_constant.c │ │ │ ├── static_union_init_wrong_type.c │ │ │ └── union_init_wrong_type.c │ │ ├── union_struct_conflicts │ │ │ ├── conflicting_tag_decl_and_use.c │ │ │ ├── conflicting_tag_decl_and_use_self_reference.c │ │ │ ├── conflicting_tag_declarations.c │ │ │ ├── struct_shadowed_by_union.c │ │ │ ├── tag_decl_conflicts_with_def.c │ │ │ ├── tag_def_conflicts_with_decl.c │ │ │ └── union_shadowed_by_incomplete_struct.c │ │ ├── union_tag_resolution │ │ │ ├── address_of_wrong_union_type.c │ │ │ ├── compare_struct_and_union_ptrs.c │ │ │ ├── conflicting_param_union_types.c │ │ │ ├── distinct_union_types.c │ │ │ ├── union_type_shadows_struct.c │ │ │ └── union_wrong_member.c │ │ └── union_type_declarations │ │ │ ├── array_of_incomplete_union_type.c │ │ │ ├── duplicate_union_def.c │ │ │ ├── incomplete_union_member.c │ │ │ ├── member_name_conflicts.c │ │ │ └── union_self_reference.c │ ├── incompatible_types │ │ ├── assign_different_pointer_type.c │ │ ├── assign_different_struct_type.c │ │ ├── branch_mismatch.c │ │ ├── branch_mismatch_2.c │ │ ├── compare_different_struct_pointers.c │ │ ├── return_wrong_struct_type.c │ │ ├── struct_param_mismatch.c │ │ └── struct_pointer_param_mismatch.c │ ├── initializers │ │ ├── compound_initializer_too_long.c │ │ ├── init_struct_with_string.c │ │ ├── initialize_nested_static_struct_member_wrong_type.c │ │ ├── initialize_static_struct_with_zero.c │ │ ├── initialize_struct_member_wrong_type.c │ │ ├── initialize_struct_with_scalar.c │ │ ├── initialize_struct_wrong_type.c │ │ ├── nested_compound_initializer_too_long.c │ │ ├── nested_static_compound_initializer_too_long.c │ │ ├── nested_struct_initializer_wrong_type.c │ │ ├── non_constant_static_elem_init.c │ │ ├── non_constant_static_init.c │ │ └── static_initializer_too_long.c │ ├── invalid_incomplete_structs │ │ ├── assign_to_incomplete_var.c │ │ ├── cast_incomplete_struct.c │ │ ├── deref_incomplete_struct_pointer.c │ │ ├── incomplete_arg_funcall.c │ │ ├── incomplete_array_element.c │ │ ├── incomplete_local_var.c │ │ ├── incomplete_param.c │ │ ├── incomplete_ptr_addition.c │ │ ├── incomplete_ptr_subtraction.c │ │ ├── incomplete_return_type_fun_def.c │ │ ├── incomplete_return_type_funcall.c │ │ ├── incomplete_struct_conditional.c │ │ ├── incomplete_struct_full_expr.c │ │ ├── incomplete_struct_member.c │ │ ├── incomplete_subscript.c │ │ ├── incomplete_tentative_def.c │ │ ├── initialize_incomplete.c │ │ ├── sizeof_incomplete.c │ │ └── sizeof_incomplete_expr.c │ ├── invalid_lvalues │ │ ├── address_of_non_lvalue.c │ │ ├── assign_nested_non_lvalue.c │ │ ├── assign_to_array.c │ │ └── assign_to_non_lvalue.c │ ├── invalid_member_operators │ │ ├── arrow_pointer_to_non_struct.c │ │ ├── bad_member.c │ │ ├── bad_pointer_member.c │ │ ├── member_of_non_struct.c │ │ ├── member_pointer_non_struct_pointer.c │ │ ├── nested_arrow_pointer_to_non_struct.c │ │ └── postfix_precedence.c │ ├── invalid_struct_declaration │ │ ├── duplicate_member_name.c │ │ ├── duplicate_struct_declaration.c │ │ ├── incomplete_member.c │ │ ├── invalid_array_member.c │ │ ├── invalid_self_reference.c │ │ └── void_member.c │ ├── scalar_required │ │ ├── and_struct.c │ │ ├── assign_null_ptr_to_struct.c │ │ ├── assign_scalar_to_struct.c │ │ ├── cast_struct_to_scalar.c │ │ ├── cast_to_struct.c │ │ ├── compare_structs.c │ │ ├── not_struct.c │ │ ├── pass_struct_as_scalar_param.c │ │ ├── struct_as_int.c │ │ ├── struct_controlling_expression.c │ │ └── subscript_struct.c │ └── tag_resolution │ │ ├── address_of_wrong_type.c │ │ ├── conflicting_fun_param_types.c │ │ ├── conflicting_fun_ret_types.c │ │ ├── distinct_struct_types.c │ │ ├── incomplete_shadows_complete.c │ │ ├── incomplete_shadows_complete_cast.c │ │ ├── invalid_shadow_self_reference.c │ │ ├── member_name_wrong_scope.c │ │ ├── member_name_wrong_scope_nested.c │ │ ├── mismatched_return_type.c │ │ ├── shadow_struct.c │ │ └── shadowed_tag_branch_mismatch.c └── valid │ ├── extra_credit │ ├── README.md │ ├── libraries │ │ ├── classify_unions.c │ │ ├── classify_unions_client.c │ │ ├── param_passing.c │ │ ├── param_passing_client.c │ │ ├── static_union_inits.c │ │ ├── static_union_inits.h │ │ ├── static_union_inits_client.c │ │ ├── union_inits.c │ │ ├── union_inits.h │ │ ├── union_inits_client.c │ │ ├── union_lib.h │ │ ├── union_retvals.c │ │ └── union_retvals_client.c │ ├── member_access │ │ ├── nested_union_access.c │ │ ├── static_union_access.c │ │ ├── union_init_and_member_access.c │ │ └── union_temp_lifetime.c │ ├── other_features │ │ ├── bitwise_ops_struct_members.c │ │ ├── compound_assign_struct_members.c │ │ ├── decr_arrow_lexing.c │ │ ├── incr_struct_members.c │ │ ├── label_tag_member_namespace.c │ │ └── struct_decl_in_switch_statement.c │ ├── semantic_analysis │ │ ├── cast_union_to_void.c │ │ ├── decl_shadows_decl.c │ │ ├── incomplete_union_types.c │ │ ├── redeclare_union.c │ │ ├── struct_shadows_union.c │ │ ├── union_members_same_type.c │ │ ├── union_namespace.c │ │ ├── union_self_pointer.c │ │ └── union_shadows_struct.c │ ├── size_and_offset │ │ ├── compare_union_pointers.c │ │ └── union_sizes.c │ ├── union_copy │ │ ├── assign_to_union.c │ │ ├── copy_non_scalar_members.c │ │ ├── copy_thru_pointer.c │ │ └── unions_in_conditionals.c │ └── union_types.h │ ├── no_structure_parameters │ ├── README.md │ ├── libraries │ │ ├── array_of_structs.c │ │ ├── array_of_structs.h │ │ ├── array_of_structs_client.c │ │ ├── global_struct.c │ │ ├── global_struct.h │ │ ├── global_struct_client.c │ │ ├── initializers │ │ │ ├── auto_struct_initializers.c │ │ │ ├── auto_struct_initializers.h │ │ │ ├── auto_struct_initializers_client.c │ │ │ ├── nested_auto_struct_initializers.c │ │ │ ├── nested_auto_struct_initializers.h │ │ │ ├── nested_auto_struct_initializers_client.c │ │ │ ├── nested_static_struct_initializers.c │ │ │ ├── nested_static_struct_initializers.h │ │ │ ├── nested_static_struct_initializers_client.c │ │ │ ├── static_struct_initializers.c │ │ │ ├── static_struct_initializers.h │ │ │ └── static_struct_initializers_client.c │ │ ├── opaque_struct.c │ │ ├── opaque_struct_client.c │ │ ├── param_struct_pointer.c │ │ ├── param_struct_pointer.h │ │ ├── param_struct_pointer_client.c │ │ ├── return_struct_pointer.c │ │ ├── return_struct_pointer.h │ │ └── return_struct_pointer_client.c │ ├── parse_and_lex │ │ ├── postfix_precedence.c │ │ ├── space_around_struct_member.c │ │ ├── struct_member_looks_like_const.c │ │ └── trailing_comma.c │ ├── scalar_member_access │ │ ├── arrow.c │ │ ├── dot.c │ │ ├── linked_list.c │ │ ├── nested_struct.c │ │ └── static_structs.c │ ├── semantic_analysis │ │ ├── cast_struct_to_void.c │ │ ├── incomplete_structs.c │ │ ├── namespaces.c │ │ └── resolve_tags.c │ ├── size_and_offset_calculations │ │ ├── member_comparisons.c │ │ ├── member_offsets.c │ │ ├── sizeof_exps.c │ │ ├── sizeof_type.c │ │ └── struct_sizes.h │ ├── smoke_tests │ │ ├── simple.c │ │ └── static_vs_auto.c │ └── struct_copy │ │ ├── copy_struct.c │ │ ├── copy_struct_through_pointer.c │ │ ├── copy_struct_with_arrow_operator.c │ │ ├── copy_struct_with_dot_operator.c │ │ ├── stack_clobber.c │ │ └── structs.h │ ├── parameters │ ├── data_on_page_boundary_linux.s │ ├── data_on_page_boundary_osx.s │ ├── incomplete_param_type.c │ ├── libraries │ │ ├── classify_params.c │ │ ├── classify_params.h │ │ ├── classify_params_client.c │ │ ├── modify_param.c │ │ ├── modify_param.h │ │ ├── modify_param_client.c │ │ ├── param_calling_conventions.c │ │ ├── param_calling_conventions.h │ │ ├── param_calling_conventions_client.c │ │ ├── pass_struct.c │ │ ├── pass_struct.h │ │ ├── pass_struct_client.c │ │ ├── struct_sizes.c │ │ ├── struct_sizes.h │ │ └── struct_sizes_client.c │ ├── pass_args_on_page_boundary.c │ ├── simple.c │ └── stack_clobber.c │ └── params_and_returns │ ├── big_data_on_page_boundary_linux.s │ ├── big_data_on_page_boundary_osx.s │ ├── data_on_page_boundary_linux.s │ ├── data_on_page_boundary_osx.s │ ├── ignore_retval.c │ ├── libraries │ ├── access_retval_members.c │ ├── access_retval_members.h │ ├── access_retval_members_client.c │ ├── missing_retval.c │ ├── missing_retval.h │ ├── missing_retval_client.c │ ├── return_calling_conventions.c │ ├── return_calling_conventions.h │ ├── return_calling_conventions_client.c │ ├── retval_struct_sizes.c │ ├── retval_struct_sizes.h │ └── retval_struct_sizes_client.c │ ├── return_big_struct_on_page_boundary.c │ ├── return_incomplete_type.c │ ├── return_pointer_in_rax.c │ ├── return_space_address_overlap_linux.s │ ├── return_space_address_overlap_osx.s │ ├── return_space_overlap.c │ ├── return_struct_on_page_boundary.c │ ├── simple.c │ ├── stack_clobber.c │ ├── temporary_lifetime.c │ ├── validate_return_pointer_linux.s │ └── validate_return_pointer_osx.s ├── chapter_19 ├── constant_folding │ ├── README.md │ ├── all_types │ │ ├── extra_credit │ │ │ ├── cast_nan_not_executed.c │ │ │ ├── fold_bitwise_long.c │ │ │ ├── fold_bitwise_unsigned.c │ │ │ ├── fold_nan.c │ │ │ └── return_nan.c │ │ ├── fold_cast_from_double.c │ │ ├── fold_cast_to_double.c │ │ ├── fold_conditional_jump.c │ │ ├── fold_double.c │ │ ├── fold_double_cast_exception.c │ │ ├── fold_extensions_and_copies.c │ │ ├── fold_long.c │ │ ├── fold_truncate.c │ │ ├── fold_uint.c │ │ ├── fold_ulong.c │ │ └── negative_zero.c │ └── int_only │ │ ├── extra_credit │ │ └── fold_bitwise.c │ │ ├── fold_binary.c │ │ ├── fold_conditional_jump.c │ │ ├── fold_control_flow.c │ │ ├── fold_exception.c │ │ └── fold_unary.c ├── copy_propagation │ ├── README.md │ ├── all_types │ │ ├── alias_analysis.c │ │ ├── char_type_conversion.c │ │ ├── copy_struct.c │ │ ├── dont_propagate │ │ │ ├── copy_to_offset.c │ │ │ ├── dont_propagate_addr_of.c │ │ │ ├── static_are_aliased.c │ │ │ ├── store_kills_aliased.c │ │ │ ├── type_conversion.c │ │ │ └── zero_neg_zero_different.c │ │ ├── extra_credit │ │ │ ├── copy_union.c │ │ │ ├── dont_propagate │ │ │ │ ├── update_union_member.c │ │ │ │ └── update_union_member_2.c │ │ │ ├── pointer_compound_assignment.c │ │ │ ├── pointer_incr.c │ │ │ ├── redundant_nan_copy.c │ │ │ └── redundant_union_copy.c │ │ ├── funcall_kills_aliased.c │ │ ├── pointer_arithmetic.c │ │ ├── propagate_all_types.c │ │ ├── propagate_into_type_conversions.c │ │ ├── propagate_null_pointer.c │ │ ├── redundant_double_copies.c │ │ ├── redundant_struct_copies.c │ │ └── store_doesnt_kill.c │ └── int_only │ │ ├── constant_propagation.c │ │ ├── different_paths_same_copy.c │ │ ├── different_source_values_same_copy.c │ │ ├── dont_propagate │ │ ├── add_all_blocks_to_worklist.c │ │ ├── dest_killed.c │ │ ├── listing_19_14.c │ │ ├── multi_values.c │ │ ├── no_copies_reach_entry.c │ │ ├── one_reaching_copy.c │ │ ├── source_killed.c │ │ ├── source_killed_on_one_path.c │ │ ├── static_dst_killed.c │ │ └── static_src_killed.c │ │ ├── extra_credit │ │ ├── dont_propagate │ │ │ ├── decr_kills_dest.c │ │ │ └── switch_fallthrough.c │ │ ├── goto_define.c │ │ ├── prefix_result.c │ │ ├── propagate_from_default.c │ │ └── propagate_into_case.c │ │ ├── fig_19_8.c │ │ ├── init_all_copies.c │ │ ├── kill_and_add_copies.c │ │ ├── killed_then_redefined.c │ │ ├── multi_path_no_kill.c │ │ ├── nested_loops.c │ │ ├── propagate_into_complex_expressions.c │ │ ├── propagate_params.c │ │ ├── propagate_static.c │ │ ├── propagate_static_var.c │ │ ├── propagate_var.c │ │ └── redundant_copies.c ├── dead_store_elimination │ ├── README.md │ ├── all_types │ │ ├── aliased_dead_at_exit.c │ │ ├── copy_to_dead_struct.c │ │ ├── delete_dead_pt_ii_instructions.c │ │ ├── dont_elim │ │ │ ├── copytooffset_doesnt_kill.c │ │ │ ├── funcall_generates_aliased.c │ │ │ ├── load_generates_aliased.c │ │ │ ├── never_kill_store.c │ │ │ ├── recognize_all_uses.c │ │ │ └── use_and_update.c │ │ ├── extra_credit │ │ │ ├── compound_assign_to_dead_struct_member.c │ │ │ ├── copy_to_dead_union.c │ │ │ ├── decr_struct_member.c │ │ │ └── dont_elim │ │ │ │ ├── copy_generates_union.c │ │ │ │ ├── incr_through_pointer.c │ │ │ │ └── type_punning.c │ │ └── getaddr_doesnt_gen.c │ └── int_only │ │ ├── dead_store_static_var.c │ │ ├── delete_arithmetic_ops.c │ │ ├── dont_elim │ │ ├── add_all_to_worklist.c │ │ ├── dont_remove_funcall.c │ │ ├── loop.c │ │ ├── nested_loops.c │ │ ├── recognize_all_uses.c │ │ ├── self_copy.c │ │ ├── static_vars_at_exit.c │ │ ├── static_vars_fun.c │ │ └── used_one_path.c │ │ ├── elim_second_copy.c │ │ ├── extra_credit │ │ ├── dead_compound_assignment.c │ │ ├── dead_incr_decr.c │ │ └── dont_elim │ │ │ └── incr_and_dead_store.c │ │ ├── fig_19_11.c │ │ ├── initialize_blocks_with_empty_set.c │ │ ├── loop_dead_store.c │ │ ├── simple.c │ │ └── static_not_always_live.c ├── helper_libs │ └── exit.c ├── unreachable_code_elimination │ ├── README.md │ ├── and_clause.c │ ├── constant_if_else.c │ ├── dead_after_if_else.c │ ├── dead_after_return.c │ ├── dead_blocks_with_predecessors.c │ ├── dead_branch_inside_loop.c │ ├── dead_for_loop.c │ ├── empty.c │ ├── empty_block.c │ ├── extra_credit │ │ ├── dead_before_first_switch_case.c │ │ ├── dead_in_switch_body.c │ │ ├── goto_skips_over_code.c │ │ ├── remove_unused_label.c │ │ └── unreachable_switch_body.c │ ├── infinite_loop.c │ ├── keep_final_jump.c │ ├── or_clause.c │ ├── remove_conditional_jumps.c │ ├── remove_jump_keep_label.c │ └── remove_useless_starting_label.c └── whole_pipeline │ ├── README.md │ ├── all_types │ ├── alias_analysis_change.c │ ├── extra_credit │ │ ├── eval_nan_condition.c │ │ ├── fold_compound_assign_all_types.c │ │ ├── fold_compound_bitwise_assign_all_types.c │ │ ├── fold_incr_decr_chars.c │ │ ├── fold_incr_decr_doubles.c │ │ ├── fold_incr_decr_unsigned.c │ │ ├── fold_negative_long_bitshift.c │ │ └── nan.c │ ├── fold_cast_from_double.c │ ├── fold_cast_to_double.c │ ├── fold_char_condition.c │ ├── fold_extension_and_truncation.c │ ├── fold_infinity.c │ ├── fold_negative_values.c │ ├── fold_negative_zero.c │ ├── integer_promotions.c │ ├── listing_19_5_more_types.c │ ├── propagate_into_copyfromoffset.c │ ├── propagate_into_copytooffset.c │ ├── propagate_into_load.c │ ├── propagate_into_store.c │ └── signed_unsigned_conversion.c │ └── int_only │ ├── dead_condition.c │ ├── elim_and_copy_prop.c │ ├── extra_credit │ ├── compound_assign_exceptions.c │ ├── evaluate_switch.c │ ├── fold_bitwise_compound_assignment.c │ ├── fold_compound_assignment.c │ ├── fold_incr_and_decr.c │ └── fold_negative_bitshift.c │ ├── int_min.c │ ├── listing_19_5.c │ └── remainder_test.c ├── chapter_2 ├── invalid_parse │ ├── extra_paren.c │ ├── missing_const.c │ ├── missing_semicolon.c │ ├── nested_missing_const.c │ ├── parenthesize_operand.c │ ├── unclosed_paren.c │ └── wrong_order.c └── valid │ ├── bitwise.c │ ├── bitwise_int_min.c │ ├── bitwise_zero.c │ ├── neg.c │ ├── neg_zero.c │ ├── negate_int_max.c │ ├── nested_ops.c │ ├── nested_ops_2.c │ ├── parens.c │ ├── parens_2.c │ ├── parens_3.c │ └── redundant_parens.c ├── chapter_20 ├── all_types │ ├── no_coalescing │ │ ├── aliasing_optimized_away.c │ │ ├── dbl_bin_uses_operands.c │ │ ├── dbl_fun_call.c │ │ ├── dbl_funcall_generates_args.c │ │ ├── dbl_trivially_colorable.c │ │ ├── div_interference.c │ │ ├── div_uses_ax.c │ │ ├── force_spill_doubles.c │ │ ├── force_spill_mixed_ints.c │ │ ├── fourteen_pseudos_interfere.c │ │ ├── gp_xmm_mixed.c │ │ ├── indexed_operand_reads_regs.c │ │ ├── mixed_type_arg_registers.c │ │ ├── mixed_type_funcall_generates_args.c │ │ ├── mixed_type_stack_alignment.c │ │ ├── one_aliased_var.c │ │ ├── ptr_rax_live_at_exit.c │ │ ├── return_all_int_struct.c │ │ ├── return_double.c │ │ ├── return_double_struct.c │ │ ├── store_pointer_in_register.c │ │ ├── track_dbl_arg_registers.c │ │ ├── type_conversion_interference.c │ │ └── xmm0_live_at_exit.c │ ├── util.h │ └── with_coalescing │ │ ├── briggs_coalesce_long.c │ │ ├── briggs_coalesce_xmm.c │ │ ├── briggs_xmm_k_value.c │ │ ├── coalesce_char.c │ │ ├── dont_coalesce_movzx.c │ │ ├── george_coalesce_xmm.c │ │ ├── george_off_by_one_xmm.c │ │ └── george_xmm_k_value.c ├── helper_libs │ ├── alignment_check_wrapper_linux.s │ ├── alignment_check_wrapper_osx.s │ ├── clobber_xmm_regs_linux.s │ ├── clobber_xmm_regs_osx.s │ ├── coalesce_prevents_spill_lib.c │ ├── funcall_generates_args_lib.c │ ├── mixed_type_arg_registers_lib.c │ ├── mixed_type_funcall_generates_args_lib.c │ ├── return_all_int_struct_lib.c │ ├── return_double_lib.c │ ├── return_double_struct_lib.c │ ├── target_shim.c │ ├── track_arg_registers_lib.c │ ├── track_dbl_arg_registers_lib.c │ ├── util.c │ ├── wrapper_linux.s │ └── wrapper_osx.s └── int_only │ ├── no_coalescing │ ├── bin_uses_operands.c │ ├── callee_saved_stack_alignment.c │ ├── cdq_interference.c │ ├── cmp_generates_operands.c │ ├── cmp_no_updates.c │ ├── copy_no_interference.c │ ├── division_uses_ax.c │ ├── eax_live_at_exit.c │ ├── force_spill.c │ ├── funcall_generates_args.c │ ├── idiv_interference.c │ ├── loop.c │ ├── many_pseudos_fewer_conflicts.c │ ├── optimistic_coloring.c │ ├── preserve_across_fun_call.c │ ├── rewrite_regression_test.c │ ├── same_instr_interference.c │ ├── same_instr_no_interference.c │ ├── test_spill_metric.c │ ├── test_spill_metric_2.c │ ├── track_arg_registers.c │ ├── trivially_colorable.c │ ├── unary_interference.c │ ├── unary_uses_operand.c │ └── use_all_hardregs.c │ ├── util.h │ └── with_coalescing │ ├── briggs_coalesce.c │ ├── briggs_coalesce_hardreg.c │ ├── briggs_dont_coalesce.c │ ├── coalesce_prevents_spill.c │ ├── george_coalesce.c │ ├── george_dont_coalesce.c │ ├── george_dont_coalesce_2.c │ ├── george_off_by_one.c │ └── no_george_test_for_pseudos.c ├── chapter_3 ├── invalid_parse │ ├── double_operation.c │ ├── extra_credit │ │ └── bitwise_double_operator.c │ ├── imbalanced_paren.c │ ├── malformed_paren.c │ ├── misplaced_semicolon.c │ ├── missing_first_op.c │ ├── missing_open_paren.c │ ├── missing_second_op.c │ └── no_semicolon.c └── valid │ ├── add.c │ ├── associativity.c │ ├── associativity_2.c │ ├── associativity_3.c │ ├── associativity_and_precedence.c │ ├── div.c │ ├── div_neg.c │ ├── extra_credit │ ├── bitwise_and.c │ ├── bitwise_or.c │ ├── bitwise_precedence.c │ ├── bitwise_shift_associativity.c │ ├── bitwise_shift_associativity_2.c │ ├── bitwise_shift_precedence.c │ ├── bitwise_shiftl.c │ ├── bitwise_shiftr.c │ ├── bitwise_shiftr_negative.c │ ├── bitwise_variable_shift_count.c │ └── bitwise_xor.c │ ├── mod.c │ ├── mult.c │ ├── parens.c │ ├── precedence.c │ ├── sub.c │ ├── sub_neg.c │ ├── unop_add.c │ └── unop_parens.c ├── chapter_4 ├── invalid_parse │ ├── missing_const.c │ ├── missing_first_op.c │ ├── missing_operand.c │ ├── missing_second_op.c │ ├── missing_semicolon.c │ └── unary_missing_semicolon.c └── valid │ ├── and_false.c │ ├── and_short_circuit.c │ ├── and_true.c │ ├── associativity.c │ ├── compare_arithmetic_results.c │ ├── eq_false.c │ ├── eq_precedence.c │ ├── eq_true.c │ ├── extra_credit │ ├── bitwise_and_precedence.c │ ├── bitwise_or_precedence.c │ ├── bitwise_shift_precedence.c │ └── bitwise_xor_precedence.c │ ├── ge_false.c │ ├── ge_true.c │ ├── gt_false.c │ ├── gt_true.c │ ├── le_false.c │ ├── le_true.c │ ├── lt_false.c │ ├── lt_true.c │ ├── multi_short_circuit.c │ ├── ne_false.c │ ├── ne_true.c │ ├── nested_ops.c │ ├── not.c │ ├── not_sum.c │ ├── not_sum_2.c │ ├── not_zero.c │ ├── operate_on_booleans.c │ ├── or_false.c │ ├── or_short_circuit.c │ ├── or_true.c │ ├── precedence.c │ ├── precedence_2.c │ ├── precedence_3.c │ ├── precedence_4.c │ └── precedence_5.c ├── chapter_5 ├── invalid_parse │ ├── compound_invalid_operator.c │ ├── declare_keyword_as_var.c │ ├── extra_credit │ │ ├── binary_decrement.c │ │ ├── binary_increment.c │ │ ├── compound_initializer.c │ │ └── increment_declaration.c │ ├── invalid_specifier.c │ ├── invalid_type.c │ ├── invalid_variable_name.c │ ├── malformed_compound_assignment.c │ ├── malformed_decrement.c │ ├── malformed_increment.c │ ├── malformed_less_equal.c │ ├── malformed_not_equal.c │ ├── missing_semicolon.c │ └── return_in_assignment.c ├── invalid_semantics │ ├── declared_after_use.c │ ├── extra_credit │ │ ├── compound_invalid_lvalue.c │ │ ├── compound_invalid_lvalue_2.c │ │ ├── postfix_decr_non_lvalue.c │ │ ├── postfix_incr_non_lvalue.c │ │ ├── prefix_decr_non_lvalue.c │ │ ├── prefix_incr_non_lvalue.c │ │ ├── undeclared_bitwise_op.c │ │ ├── undeclared_compound_assignment.c │ │ ├── undeclared_compound_assignment_use.c │ │ ├── undeclared_postfix_decr.c │ │ └── undeclared_prefix_incr.c │ ├── invalid_lvalue.c │ ├── invalid_lvalue_2.c │ ├── mixed_precedence_assignment.c │ ├── redefine.c │ ├── undeclared_var.c │ ├── undeclared_var_and.c │ ├── undeclared_var_compare.c │ ├── undeclared_var_unary.c │ └── use_then_redefine.c └── valid │ ├── add_variables.c │ ├── allocate_temps_and_vars.c │ ├── assign.c │ ├── assign_val_in_initializer.c │ ├── assignment_in_initializer.c │ ├── assignment_lowest_precedence.c │ ├── empty_function_body.c │ ├── exp_then_declaration.c │ ├── extra_credit │ ├── bitwise_in_initializer.c │ ├── bitwise_ops_vars.c │ ├── bitwise_shiftl_variable.c │ ├── bitwise_shiftr_assign.c │ ├── compound_assignment_chained.c │ ├── compound_assignment_lowest_precedence.c │ ├── compound_assignment_use_result.c │ ├── compound_bitwise_and.c │ ├── compound_bitwise_assignment_lowest_precedence.c │ ├── compound_bitwise_chained.c │ ├── compound_bitwise_or.c │ ├── compound_bitwise_shiftl.c │ ├── compound_bitwise_shiftr.c │ ├── compound_bitwise_xor.c │ ├── compound_divide.c │ ├── compound_minus.c │ ├── compound_mod.c │ ├── compound_multiply.c │ ├── compound_plus.c │ ├── incr_expression_statement.c │ ├── incr_in_binary_expr.c │ ├── incr_parenthesized.c │ ├── postfix_incr_and_decr.c │ ├── postfix_precedence.c │ └── prefix_incr_and_decr.c │ ├── kw_var_names.c │ ├── local_var_missing_return.c │ ├── mixed_precedence_assignment.c │ ├── non_short_circuit_or.c │ ├── null_statement.c │ ├── null_then_return.c │ ├── return_var.c │ ├── short_circuit_and_fail.c │ ├── short_circuit_or.c │ ├── unused_exp.c │ ├── use_assignment_result.c │ └── use_val_in_own_initializer.c ├── chapter_6 ├── invalid_lex │ └── extra_credit │ │ └── bad_label.c ├── invalid_parse │ ├── declaration_as_statement.c │ ├── empty_if_body.c │ ├── extra_credit │ │ ├── goto_without_label.c │ │ ├── kw_label.c │ │ ├── label_declaration.c │ │ ├── label_expression_clause.c │ │ ├── label_outside_function.c │ │ ├── label_without_statement.c │ │ └── parenthesized_label.c │ ├── if_assignment.c │ ├── if_no_parens.c │ ├── incomplete_ternary.c │ ├── malformed_ternary.c │ ├── malformed_ternary_2.c │ ├── mismatched_nesting.c │ └── wrong_ternary_delimiter.c ├── invalid_semantics │ ├── extra_credit │ │ ├── duplicate_labels.c │ │ ├── goto_missing_label.c │ │ ├── goto_variable.c │ │ ├── undeclared_var_in_labeled_statement.c │ │ └── use_label_as_variable.c │ ├── invalid_var_in_if.c │ ├── ternary_assign.c │ └── undeclared_var_in_ternary.c └── valid │ ├── assign_ternary.c │ ├── binary_condition.c │ ├── binary_false_condition.c │ ├── else.c │ ├── extra_credit │ ├── bitwise_ternary.c │ ├── compound_assign_ternary.c │ ├── compound_if_expression.c │ ├── goto_after_declaration.c │ ├── goto_backwards.c │ ├── goto_label.c │ ├── goto_label_and_var.c │ ├── goto_label_main.c │ ├── goto_label_main_2.c │ ├── goto_nested_label.c │ ├── label_all_statements.c │ ├── label_token.c │ ├── lh_compound_assignment.c │ ├── postfix_if.c │ ├── postfix_in_ternary.c │ ├── prefix_if.c │ ├── prefix_in_ternary.c │ ├── unused_label.c │ └── whitespace_after_label.c │ ├── if_nested.c │ ├── if_nested_2.c │ ├── if_nested_3.c │ ├── if_nested_4.c │ ├── if_nested_5.c │ ├── if_not_taken.c │ ├── if_null_body.c │ ├── if_taken.c │ ├── lh_assignment.c │ ├── multiple_if.c │ ├── nested_ternary.c │ ├── nested_ternary_2.c │ ├── rh_assignment.c │ ├── ternary.c │ ├── ternary_middle_assignment.c │ ├── ternary_middle_binop.c │ ├── ternary_precedence.c │ ├── ternary_rh_binop.c │ ├── ternary_short_circuit.c │ └── ternary_short_circuit_2.c ├── chapter_7 ├── invalid_parse │ ├── extra_brace.c │ ├── missing_brace.c │ ├── missing_semicolon.c │ └── ternary_blocks.c ├── invalid_semantics │ ├── double_define.c │ ├── double_define_after_scope.c │ ├── extra_credit │ │ ├── different_labels_same_scope.c │ │ ├── duplicate_labels_different_scopes.c │ │ └── goto_use_before_declare.c │ ├── out_of_scope.c │ └── use_before_declare.c └── valid │ ├── assign_to_self.c │ ├── assign_to_self_2.c │ ├── declaration_only.c │ ├── empty_blocks.c │ ├── extra_credit │ ├── compound_subtract_in_block.c │ ├── goto_before_declaration.c │ ├── goto_inner_scope.c │ ├── goto_outer_scope.c │ └── goto_sibling_scope.c │ ├── hidden_then_visible.c │ ├── hidden_variable.c │ ├── inner_uninitialized.c │ ├── multiple_vars_same_name.c │ ├── nested_if.c │ ├── similar_var_names.c │ └── use_in_inner_scope.c ├── chapter_8 ├── invalid_parse │ ├── decl_as_loop_body.c │ ├── do_extra_semicolon.c │ ├── do_missing_semicolon.c │ ├── do_while_empty_parens.c │ ├── extra_credit │ │ ├── compound_assignment_invalid_decl.c │ │ ├── label_in_loop_header.c │ │ ├── label_is_not_block.c │ │ ├── switch_case_declaration.c │ │ ├── switch_goto_case.c │ │ ├── switch_missing_case_value.c │ │ ├── switch_missing_paren.c │ │ └── switch_no_condition.c │ ├── extra_for_header_clause.c │ ├── invalid_for_declaration.c │ ├── missing_for_header_clause.c │ ├── paren_mismatch.c │ ├── statement_in_condition.c │ └── while_missing_paren.c ├── invalid_semantics │ ├── break_not_in_loop.c │ ├── continue_not_in_loop.c │ ├── extra_credit │ │ ├── case_continue.c │ │ ├── case_outside_switch.c │ │ ├── default_continue.c │ │ ├── default_outside_switch.c │ │ ├── different_cases_same_scope.c │ │ ├── duplicate_case.c │ │ ├── duplicate_case_in_labeled_switch.c │ │ ├── duplicate_case_in_nested_statement.c │ │ ├── duplicate_default.c │ │ ├── duplicate_default_in_nested_statement.c │ │ ├── duplicate_label_in_default.c │ │ ├── duplicate_label_in_loop.c │ │ ├── duplicate_variable_in_switch.c │ │ ├── labeled_break_outside_loop.c │ │ ├── non_constant_case.c │ │ ├── switch_continue.c │ │ ├── undeclared_var_switch_expression.c │ │ ├── undeclared_variable_in_case.c │ │ ├── undeclared_variable_in_default.c │ │ └── undefined_label_in_case.c │ ├── out_of_scope_do_loop.c │ └── out_of_scope_loop_variable.c └── valid │ ├── break.c │ ├── break_immediate.c │ ├── continue.c │ ├── continue_empty_post.c │ ├── do_while.c │ ├── do_while_break_immediate.c │ ├── empty_expression.c │ ├── empty_loop_body.c │ ├── extra_credit │ ├── case_block.c │ ├── compound_assignment_controlling_expression.c │ ├── compound_assignment_for_loop.c │ ├── duffs_device.c │ ├── goto_bypass_condition.c │ ├── goto_bypass_init_exp.c │ ├── goto_bypass_post_exp.c │ ├── label_loop_body.c │ ├── label_loops_breaks_and_continues.c │ ├── loop_header_postfix_and_prefix.c │ ├── loop_in_switch.c │ ├── post_exp_incr.c │ ├── switch.c │ ├── switch_assign_in_condition.c │ ├── switch_break.c │ ├── switch_decl.c │ ├── switch_default.c │ ├── switch_default_fallthrough.c │ ├── switch_default_not_last.c │ ├── switch_default_only.c │ ├── switch_empty.c │ ├── switch_fallthrough.c │ ├── switch_goto_mid_case.c │ ├── switch_in_loop.c │ ├── switch_nested_cases.c │ ├── switch_nested_not_taken.c │ ├── switch_nested_switch.c │ ├── switch_no_case.c │ ├── switch_not_taken.c │ ├── switch_single_case.c │ ├── switch_with_continue.c │ └── switch_with_continue_2.c │ ├── for.c │ ├── for_absent_condition.c │ ├── for_absent_post.c │ ├── for_decl.c │ ├── for_nested_shadow.c │ ├── for_shadow.c │ ├── multi_break.c │ ├── multi_continue_same_loop.c │ ├── nested_break.c │ ├── nested_continue.c │ ├── nested_loop.c │ ├── null_for_header.c │ └── while.c └── chapter_9 ├── invalid_declarations ├── assign_to_fun_call.c ├── decl_params_with_same_name.c ├── extra_credit │ ├── call_label_as_function.c │ ├── compound_assign_to_fun_call.c │ ├── decrement_fun_call.c │ └── increment_fun_call.c ├── nested_function_definition.c ├── params_with_same_name.c ├── redefine_fun_as_var.c ├── redefine_parameter.c ├── redefine_var_as_fun.c ├── undeclared_fun.c └── wrong_parameter_names.c ├── invalid_labels └── extra_credit │ ├── goto_cross_function.c │ └── goto_function.c ├── invalid_parse ├── call_non_identifier.c ├── decl_wrong_closing_delim.c ├── fun_decl_for_loop.c ├── funcall_wrong_closing_delim.c ├── function_call_declaration.c ├── function_returning_function.c ├── initialize_function_as_variable.c ├── trailing_comma.c ├── trailing_comma_decl.c ├── unclosed_paren_decl.c └── var_init_in_param_list.c ├── invalid_types ├── assign_fun_to_variable.c ├── assign_value_to_function.c ├── call_variable_as_function.c ├── conflicting_function_declarations.c ├── conflicting_local_function_declaration.c ├── divide_by_function.c ├── extra_credit │ ├── bitwise_op_function.c │ ├── compound_assign_function_lhs.c │ ├── compound_assign_function_rhs.c │ ├── postfix_incr_fun_name.c │ ├── prefix_decr_fun_name.c │ └── switch_on_function.c ├── multiple_function_definitions.c ├── multiple_function_definitions_2.c ├── too_few_args.c └── too_many_args.c └── valid ├── arguments_in_registers ├── dont_clobber_edx.c ├── expression_args.c ├── fibonacci.c ├── forward_decl_multi_arg.c ├── hello_world.c ├── param_shadows_local_var.c ├── parameter_shadows_function.c ├── parameter_shadows_own_function.c ├── parameters_are_preserved.c └── single_arg.c ├── extra_credit ├── compound_assign_function_result.c ├── dont_clobber_ecx.c ├── goto_label_multiple_functions.c ├── goto_shared_name.c └── label_naming_scheme.c ├── libraries ├── addition.c ├── addition_client.c ├── many_args.c ├── many_args_client.c ├── no_function_calls │ ├── division.c │ ├── division_client.c │ ├── local_stack_variables.c │ └── local_stack_variables_client.c ├── system_call.c └── system_call_client.c ├── no_arguments ├── forward_decl.c ├── function_shadows_variable.c ├── multiple_declarations.c ├── no_return_value.c ├── precedence.c ├── use_function_in_expression.c └── variable_shadows_function.c └── stack_arguments ├── call_putchar.c ├── lots_of_arguments.c ├── stack_alignment.c ├── stack_alignment_check_linux.s ├── stack_alignment_check_osx.s └── test_for_memory_leaks.c /.gitignore: -------------------------------------------------------------------------------- 1 | **/__pycache__/* 2 | mycc 3 | *.s -------------------------------------------------------------------------------- /test_framework/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nlsandler/writing-a-c-compiler-tests/ef1a0f0893331a42cd1579bf9ca37f653e33805f/test_framework/__init__.py -------------------------------------------------------------------------------- /test_framework/parser/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nlsandler/writing-a-c-compiler-tests/ef1a0f0893331a42cd1579bf9ca37f653e33805f/test_framework/parser/__init__.py -------------------------------------------------------------------------------- /test_framework/tacky/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nlsandler/writing-a-c-compiler-tests/ef1a0f0893331a42cd1579bf9ca37f653e33805f/test_framework/tacky/__init__.py -------------------------------------------------------------------------------- /test_framework/test_tests/__init__.py: -------------------------------------------------------------------------------- 1 | """Tests for the test suite itself (assembly parser, command-line interface, etc.)""" 2 | -------------------------------------------------------------------------------- /tests/chapter_1/invalid_lex/at_sign.c: -------------------------------------------------------------------------------- 1 | /* The @ symbol doesn't appear in any C tokens, 2 | except inside string or character literals. */ 3 | int main(void) { 4 | return 0@1; 5 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_lex/backslash.c: -------------------------------------------------------------------------------- 1 | /* A single backslash is not a valid token. */ 2 | \ -------------------------------------------------------------------------------- /tests/chapter_1/invalid_lex/backtick.c: -------------------------------------------------------------------------------- 1 | /* A backtick is not a valid token. */ 2 | ` -------------------------------------------------------------------------------- /tests/chapter_1/invalid_lex/invalid_identifier.c: -------------------------------------------------------------------------------- 1 | /* '1foo' is not a valid token, because identifier can't start with digits. */ 2 | int main(void) { 3 | return 1foo; 4 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_lex/invalid_identifier_2.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return @b; 4 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/end_before_expr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/extra_junk.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return 2; 4 | } 5 | // A single identifier outside of a declaration isn't a valid top-level construct 6 | foo -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/invalid_function_name.c: -------------------------------------------------------------------------------- 1 | /* A function name must be an identifier, not a constant */ 2 | int 3 (void) { 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/keyword_wrong_case.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | RETURN 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/missing_type.c: -------------------------------------------------------------------------------- 1 | // note: in older versions of C this would be valid 2 | // and return type would default to 'int' 3 | // GCC/Clang will compile it (with a warning) 4 | // for backwards compatibility 5 | main(void) { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/misspelled_keyword.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | returns 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/no_semicolon.c: -------------------------------------------------------------------------------- 1 | int main (void) { 2 | return 0 3 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/not_expression.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return int; 3 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/space_in_keyword.c: -------------------------------------------------------------------------------- 1 | int main(void){ 2 | retur n 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/switched_parens.c: -------------------------------------------------------------------------------- 1 | int main )( { 2 | return 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/unclosed_brace.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 0; 3 | -------------------------------------------------------------------------------- /tests/chapter_1/invalid_parse/unclosed_paren.c: -------------------------------------------------------------------------------- 1 | int main( { 2 | return 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_1/valid/multi_digit.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // test case w/ multi-digit constant 3 | return 100; 4 | } -------------------------------------------------------------------------------- /tests/chapter_1/valid/newlines.c: -------------------------------------------------------------------------------- 1 | int 2 | main 3 | ( 4 | void 5 | ) 6 | { 7 | return 8 | 0 9 | ; 10 | } -------------------------------------------------------------------------------- /tests/chapter_1/valid/no_newlines.c: -------------------------------------------------------------------------------- 1 | int main(void){return 0;} -------------------------------------------------------------------------------- /tests/chapter_1/valid/return_0.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_1/valid/return_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_1/valid/spaces.c: -------------------------------------------------------------------------------- 1 | int main ( void) { return 0 ; } -------------------------------------------------------------------------------- /tests/chapter_1/valid/tabs.c: -------------------------------------------------------------------------------- 1 | int main ( void) { return 0 ; } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_declarations/undeclared_global_variable.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return x; 3 | } 4 | 5 | /* you must declare a file-scope variable before using it */ 6 | int x = 0; 7 | -------------------------------------------------------------------------------- /tests/chapter_10/invalid_labels/extra_credit/goto_global_var.c: -------------------------------------------------------------------------------- 1 | int x = 10; 2 | 3 | int main(void) { 4 | /* goto statements can only target labels, not variables. */ 5 | goto x; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_parse/extern_param.c: -------------------------------------------------------------------------------- 1 | /* A function parameter cannot have a storage class */ 2 | int f(extern int i) { 3 | return i; 4 | } 5 | 6 | int main(void) { 7 | return f(1); 8 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_parse/extra_credit/extern_label.c: -------------------------------------------------------------------------------- 1 | // The extern specifier cannot be applied to labels 2 | 3 | int main(void) { 4 | extern a: 5 | return 1; 6 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_parse/extra_credit/file_scope_label.c: -------------------------------------------------------------------------------- 1 | /* Labels cannot appear at file scope. */ 2 | x: 3 | int foo = 0; 4 | 5 | int main(void) { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_parse/extra_credit/static_label.c: -------------------------------------------------------------------------------- 1 | // The static specifier cannot be applied to labels 2 | 3 | int main(void) { 4 | static a: 5 | return 1; 6 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_parse/missing_parameter_list.c: -------------------------------------------------------------------------------- 1 | /* Functions must have parameter lists */ 2 | int f { 3 | return 0 4 | }; 5 | 6 | int main(void) { 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_parse/missing_type_specifier.c: -------------------------------------------------------------------------------- 1 | /* A declaration must have at least one type specifier 2 | * (Clang/GCC warn instead of failing here) 3 | */ 4 | static var = 0; 5 | 6 | int main(void) { 7 | return var; 8 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_parse/multi_storage_class_fun.c: -------------------------------------------------------------------------------- 1 | /* A function declaration can't have multiple storage class keywords */ 2 | static int extern foo(void) { 3 | return 0; 4 | } 5 | 6 | int main(void) { 7 | return foo(); 8 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_parse/multi_storage_class_var.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* a variable can't have more than one storage class */ 3 | static extern int foo = 0; 4 | return foo; 5 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_parse/static_and_extern.c: -------------------------------------------------------------------------------- 1 | /* A declaration cannot include both static and extern specifiers */ 2 | static extern int a; 3 | 4 | int main(void) { 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_parse/static_param.c: -------------------------------------------------------------------------------- 1 | /* A function parameter cannot have a storage class */ 2 | int f(static int i) { 3 | return i; 4 | } 5 | 6 | int main(void) { 7 | return f(1); 8 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_types/extern_variable_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* An extern variable cannot have an initializer */ 3 | extern int i = 0; 4 | return i; 5 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_types/extra_credit/static_var_case.c: -------------------------------------------------------------------------------- 1 | // Can't use a static variable as a case in a switch statement 2 | 3 | int main(void) { 4 | static int i = 0; 5 | 6 | switch(0) { 7 | case i: return 0; 8 | } 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_types/non_constant_static_initializer.c: -------------------------------------------------------------------------------- 1 | int a = 10; 2 | /* b has static storage duration, 3 | * so its initializer must be constant. 4 | */ 5 | int b = 1 + a; 6 | 7 | int main(void) { 8 | return b; 9 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_types/non_constant_static_local_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | /* b has static storage duration, 4 | * so its initializer must be constant. 5 | */ 6 | static int b = a * 2; 7 | return b; 8 | } -------------------------------------------------------------------------------- /tests/chapter_10/invalid_types/redeclare_fun_as_file_scope_var.c: -------------------------------------------------------------------------------- 1 | int foo(void); 2 | 3 | /* this conflict with the previous declaration of foo as a function */ 4 | int foo; 5 | 6 | int main(void) { 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /tests/chapter_10/invalid_types/use_file_scope_variable_as_fun.c: -------------------------------------------------------------------------------- 1 | /* This declares a global variable */ 2 | extern int foo; 3 | 4 | int main(void) { 5 | /* Treating a variable as a function is a type error. */ 6 | return foo(); 7 | } -------------------------------------------------------------------------------- /tests/chapter_10/valid/data_on_page_boundary_linux.s: -------------------------------------------------------------------------------- 1 | .bss 2 | .align 4096 3 | .zero 4090 4 | .globl zed 5 | zed: 6 | .zero 4 7 | .section ".note.GNU-stack","",@progbits 8 | -------------------------------------------------------------------------------- /tests/chapter_10/valid/data_on_page_boundary_osx.s: -------------------------------------------------------------------------------- 1 | .bss 2 | .align 12 # 2^12 = 4096 3 | .zero 4090 4 | .globl _zed 5 | _zed: 6 | .zero 4 7 | -------------------------------------------------------------------------------- /tests/chapter_10/valid/extra_credit/libraries/same_label_same_fun.c: -------------------------------------------------------------------------------- 1 | static int f(void) { 2 | goto x; 3 | return 0; 4 | x: 5 | return 2; 6 | } 7 | 8 | int f_caller(void) { 9 | return f(); 10 | } -------------------------------------------------------------------------------- /tests/chapter_10/valid/libraries/external_linkage_function.c: -------------------------------------------------------------------------------- 1 | /* you can redeclare a function multiple times, 2 | * but only define it once 3 | */ 4 | extern int sum(int a, int b); 5 | 6 | int sum(int i, int j) { 7 | return i + j; 8 | } 9 | 10 | int sum(int x, int y); 11 | -------------------------------------------------------------------------------- /tests/chapter_10/valid/libraries/external_tentative_var.c: -------------------------------------------------------------------------------- 1 | /* Tentatively define a variable, and make sure it's initialized to 0. */ 2 | int x; 3 | 4 | int read_x(void) { 5 | return x; 6 | } -------------------------------------------------------------------------------- /tests/chapter_10/valid/libraries/internal_hides_external_linkage.c: -------------------------------------------------------------------------------- 1 | int x = 10; 2 | 3 | int read_x(void){ 4 | return x; 5 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_parse/bad_specifiers.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* Cannot declare a variable with two "int" specifiers */ 3 | int long int i = 0; 4 | return i; 5 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_parse/empty_cast.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* A cast expression must include at least one type specifier */ 3 | return () 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_parse/fun_name_long.c: -------------------------------------------------------------------------------- 1 | /* Because long is a keyword, you can't use it as a function name */ 2 | int long(void) { 3 | return 4; 4 | } 5 | 6 | int main(void){ 7 | return long(); 8 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_parse/invalid_cast.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* A cast expression can only contain type specifiers, 3 | * not storage class specifiers 4 | */ 5 | return (static int) 10; 6 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_parse/invalid_suffix.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* There shouldn't be a space before the 'l' suffix in a long constant */ 3 | return 0 l; 4 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_parse/long_constant_as_var.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* You can't use a long constant where an identifier is required */ 3 | int 10l; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_parse/missing_cast_parentheses.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* The type specifier in a cast expression must be in parentheses */ 3 | return long 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_parse/var_name_long.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* Because long is a keyword, you can't use it as a variable name */ 3 | int long = 5; 4 | return long; 5 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_types/call_long_as_function.c: -------------------------------------------------------------------------------- 1 | long x(void); 2 | 3 | int main(void) { 4 | long x = 0; 5 | /* x isn't a function, so you can't call it */ 6 | return x(); 7 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_types/cast_lvalue.c: -------------------------------------------------------------------------------- 1 | /* The result of a cast expression is not an lvalue */ 2 | 3 | int main(void) { 4 | int i = 0; 5 | i = (long) i = 10; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_types/conflicting_function_types.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to declare a function multiple times with different parameter types */ 2 | 3 | int foo(int a); 4 | 5 | int main(void) { 6 | return 0; 7 | } 8 | 9 | int foo(long a); -------------------------------------------------------------------------------- /tests/chapter_11/invalid_types/conflicting_global_types.c: -------------------------------------------------------------------------------- 1 | int foo = 3; 2 | 3 | /* It's illegal to declare the same variable 4 | * with different types 5 | */ 6 | long foo; 7 | 8 | int main(void) { 9 | return foo; 10 | } -------------------------------------------------------------------------------- /tests/chapter_11/invalid_types/conflicting_variable_types.c: -------------------------------------------------------------------------------- 1 | long a; 2 | 3 | int main(void) { 4 | /* This declaration refers to the global 'a' variable, 5 | * but has a conflicting type. 6 | */ 7 | extern int a; 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_11/valid/libraries/long_global_var.c: -------------------------------------------------------------------------------- 1 | long int l = 8589934592l; // 2^33 2 | 3 | long return_l(void) { 4 | return l; 5 | } 6 | 7 | int return_l_as_int(void) { 8 | return l; 9 | } -------------------------------------------------------------------------------- /tests/chapter_11/valid/libraries/maintain_stack_alignment.c: -------------------------------------------------------------------------------- 1 | long add_variables(long x, long y, int z){ 2 | return x + y + z; 3 | } -------------------------------------------------------------------------------- /tests/chapter_11/valid/libraries/return_long.c: -------------------------------------------------------------------------------- 1 | long add(int a, int b) { 2 | return (long) a + (long) b; 3 | } -------------------------------------------------------------------------------- /tests/chapter_11/valid/long_expressions/simple.c: -------------------------------------------------------------------------------- 1 | /* A simple arithmetic test case */ 2 | 3 | int main(void) { 4 | long l = 9223372036854775807l; 5 | return (l - 2l == 9223372036854775805l); 6 | } -------------------------------------------------------------------------------- /tests/chapter_12/invalid_lex/invalid_suffix.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* An unsigned constant suffix should only have one 'u' */ 3 | return 0uu; 4 | } -------------------------------------------------------------------------------- /tests/chapter_12/invalid_lex/invalid_suffix_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* lul is not a valid suffix for integer constants */ 3 | return 0lul; 4 | } -------------------------------------------------------------------------------- /tests/chapter_12/invalid_parse/bad_specifiers.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* Can't combine signed and unsigned specifiers */ 3 | int i = 0; 4 | return (signed unsigned) i; 5 | } -------------------------------------------------------------------------------- /tests/chapter_12/invalid_parse/bad_specifiers_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* Can't include the same specifier twice */ 3 | unsigned long unsigned i = 0; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_12/invalid_types/conflicting_signed_unsigned.c: -------------------------------------------------------------------------------- 1 | /* Cannot declare x as both signed int and unsigned int */ 2 | 3 | unsigned x; 4 | 5 | int x; 6 | 7 | int main(void) { 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_12/invalid_types/conflicting_uint_ulong.c: -------------------------------------------------------------------------------- 1 | /* Can't declare the same function with two return types: unsignd int and unsigned long */ 2 | unsigned int foo(void); 3 | 4 | unsigned long foo(void) { 5 | return 0; 6 | } 7 | 8 | int main(void) { 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_12/valid/unsigned_expressions/simple.c: -------------------------------------------------------------------------------- 1 | /* A simple arithmetic test case */ 2 | 3 | int main(void) { 4 | unsigned u = 2147483647u; 5 | return (u + 2u == 2147483649u); 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/helper_libs/nan.c: -------------------------------------------------------------------------------- 1 | // include isnan macro and export a non-macro version we can use 2 | #include 3 | 4 | int double_isnan(double d) { 5 | return isnan(d); 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_lex/bad_exponent_suffix.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | double foo = 1E2x; 4 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_lex/missing_exponent.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | /* "30." won't match our regex because it's followed by a letter. 4 | * It's a preprocessing number but not a valid constant token. 5 | */ 6 | double foo = 30.e; 7 | return 4; 8 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_lex/missing_negative_exponent.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* The exponent on a floating-point constant must be an integer, 3 | * not just a negative sign. 4 | */ 5 | double foo = 24e-; 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_lex/yet_another_bad_constant.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return 1.e-10x; 4 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_parse/invalid_type_specifier.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* "Unsigned double" is not a valid type specifier */ 3 | unsigned double d = 10.0; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_parse/invalid_type_specifier_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* "double double" is not a valid type specifier */ 3 | double double d = 10.0; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/complement_double.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* You can't take the bitwise complement of a double */ 3 | double d = ~10.0; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/bitwise_and.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* It's illegal to apply bitwise & to doubles */ 3 | double d = 10.0 & -1; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/bitwise_or.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* It's illegal to apply bitwise | to doubles */ 3 | double d = 0.0 | -0.0; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/bitwise_shift_double.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* It's illegal to apply the << or >> operator to doubles */ 3 | double d = 5.0 << 3; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/bitwise_shift_double_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* It's illegal to use a double as the right operand of << or >>. */ 3 | return 1 << 2.0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/bitwise_xor.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* It's illegal to XOR doubles */ 3 | return 1e10 ^ -1e10; 4 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/compound_bitwise_and.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // Can't perform compound bitwise operations with doubles 3 | double d = 1.0; 4 | d &= 0; 5 | return (int) d; 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/compound_bitwise_xor.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // Can't perform compound bitwise operations with doubles 3 | int i = 0; 4 | i |= 2.0; 5 | return (int) i; 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/compound_left_bitshift.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // Can't perform compound bitwise operations with doubles 3 | double d = 1.0; 4 | d <<= 1; 5 | return d; 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/compound_mod.c: -------------------------------------------------------------------------------- 1 | // Can't apply %= to a double 2 | int main(void) { 3 | double d = 5.0; 4 | d %= 2; 5 | return (int) d; 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/compound_mod_2.c: -------------------------------------------------------------------------------- 1 | // Can't apply %= to a double 2 | int main(void) { 3 | int i = 5; 4 | i %= 1.0; 5 | return i; 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/extra_credit/compound_right_bitshift.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // Can't perform compound bitwise operations with doubles 3 | int i = 1000; 4 | i >>= 2.0; 5 | return i; 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/mod_double.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* You can't apply the modulo operator to a double */ 3 | double d = 10.0; 4 | d = d % 3; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/invalid_types/mod_double_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* You can't apply the modulo operator to a double */ 3 | double e = 3.0 % 5; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_13/valid/floating_expressions/simple.c: -------------------------------------------------------------------------------- 1 | /* A simple arithmetic test case */ 2 | int main(void) { 3 | double x = 2.0; 4 | return (x * 2.0 == 4.0); 5 | } -------------------------------------------------------------------------------- /tests/chapter_13/valid/function_calls/return_double.c: -------------------------------------------------------------------------------- 1 | /* Test that we follow the calling convention for a double return type */ 2 | double d(void) { 3 | return 1234.e75; 4 | } 5 | 6 | int main(void) { 7 | double retval = d(); 8 | return retval == 1234.e75; 9 | } -------------------------------------------------------------------------------- /tests/chapter_13/valid/libraries/extern_double.c: -------------------------------------------------------------------------------- 1 | double d = 1e20; -------------------------------------------------------------------------------- /tests/chapter_13/valid/libraries/extern_double_client.c: -------------------------------------------------------------------------------- 1 | /* Test linking against a double defined in another file */ 2 | extern double d; 3 | 4 | int main(void) { 5 | return d == 1e20; 6 | } -------------------------------------------------------------------------------- /tests/chapter_13/valid/libraries/use_arg_after_fun_call.c: -------------------------------------------------------------------------------- 1 | double fun(double x) { 2 | if (x > 2) 3 | return x; 4 | else { 5 | double ret = fun(x + 2); // ret = 3.0 6 | return ret + x; // return 4.0 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/chapter_13/valid/libraries/use_arg_after_fun_call_client.c: -------------------------------------------------------------------------------- 1 | /* This test case is identical to chapter13/valid/function_calls/use_arg_after_fun_call.c 2 | * but split across two files */ 3 | double fun(double x); 4 | 5 | int main(void) { 6 | return fun(1.0); 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_declarations/extra_credit/deref_label.c: -------------------------------------------------------------------------------- 1 | // It's illegal to dereference a label 2 | int main(void) { 3 | lbl: 4 | *lbl; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_parse/cast_to_declarator.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | // can only cast to declarator types, not abstract declarators 4 | return (int **a)(10); 5 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_parse/malformed_abstract_declarator.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* This abstract declarator is malformed. 3 | * Pointer declarators like * cannot appear after 4 | * parenthesized expressions 5 | */ 6 | (int (*)*) 10; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_parse/malformed_declarator.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* This declarator is malformed. 3 | * Pointer declarators like * cannot appear after 4 | * parenthesized expressions 5 | */ 6 | int (*)* y; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_parse/malformed_function_declarator.c: -------------------------------------------------------------------------------- 1 | /* This is a variation on chapter 9's function_returning_function.c, 2 | * with a parenthesized declarator. */ 3 | int (foo(void))(void); 4 | 5 | int main(void) { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_parse/malformed_function_declarator_2.c: -------------------------------------------------------------------------------- 1 | 2 | // You can't wrap a parameter list in multiple sets of parentheses 3 | int foo((void)); 4 | -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/address_of_address.c: -------------------------------------------------------------------------------- 1 | /* The result of the & operator is not an lvalue, 2 | * so it's illegal to take its address 3 | */ 4 | int main(void) { 5 | int x = 0; 6 | int *y = &x; 7 | int **z = &(&x); 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/address_of_assignment.c: -------------------------------------------------------------------------------- 1 | /* The result of an assignment statement is not an lvalue, 2 | * so it's illegal to take its address. 3 | */ 4 | int main(void) { 5 | int x = 0; 6 | int y = 0; 7 | int *ptr = &(x = y); 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/address_of_constant.c: -------------------------------------------------------------------------------- 1 | /* A constant is not an lvalue, so it's illegal to take its address. */ 2 | int main(void) { 3 | int *ptr = &10; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/assign_int_to_pointer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to assign an integer to a pointer, 2 | * because an integer cannot be implicitly converted 3 | * to pointer type 4 | */ 5 | int main(void) { 6 | int *x; 7 | x = 10; 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/assign_to_address.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int x = 0; 4 | &x = 10; /* An address-of expression is not an lvalue, so you can't assign to it */ 5 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/assign_wrong_pointer_type.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | double *d = 0; 4 | long *l = 0; 5 | /* It's illegal to assign one pointer type to another */ 6 | l = d; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/bad_null_pointer_constant.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | // only integers can be null pointer constants 4 | int *x = 0.0; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/cast_double_to_pointer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to cast a double to a pointer */ 2 | 3 | int main(void) { 4 | double d = 0.0; 5 | int *x = (int *) d; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/cast_pointer_to_double.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to cast a pointer to a double */ 2 | 3 | int main(void) { 4 | int *x; 5 | double d = (double) x; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/compare_mixed_pointer_types.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to compare two different pointer types */ 2 | int main(void) { 3 | int *x = 0ul; 4 | unsigned *y = 0ul; 5 | return x == y; 6 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/complement_pointer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to take the bitwise complement of a pointer. */ 2 | int main(void) { 3 | int *x = 0; 4 | return (int) ~x; 5 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/dereference_non_pointer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to dereference an expression with a non-pointer type */ 2 | int main(void) { 3 | unsigned long l = 100ul; 4 | return *l; 5 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/divide_pointer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to multiply, divide, or take the modulo of pointers */ 2 | int main(void) 3 | { 4 | int x = 10; 5 | int *y = &x; 6 | (y / 8); 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/bitwise_and_pointer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to apply bitwise operations where either operand is a pointer */ 2 | int main(void) { 3 | long *ptr = 0; 4 | 10 & ptr; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/bitwise_compound_assign_to_pointer.c: -------------------------------------------------------------------------------- 1 | // No bitwise operations on pointers, including bitwise compound assignment 2 | int main(void) { 3 | int x = 0; 4 | int *ptr = &x; 5 | ptr &= 0; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/bitwise_lshift_pointer.c: -------------------------------------------------------------------------------- 1 | // It's illegal to use pointer as right operand in bitshift 2 | int main(void) { 3 | int *ptr = 0; 4 | int i = 1000; 5 | i >> ptr; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/bitwise_or_pointer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to apply bitwise operations to pointers */ 2 | int main(void) { 3 | int *x = 0; 4 | int *y = 0; 5 | x | y; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/bitwise_rshift_pointer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to apply left or right bitshift operations to pointers */ 2 | int main(void) { 3 | int *x = 0; 4 | return (int) (x >> 10); 5 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/bitwise_xor_pointer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to apply bitwise operations where either operand is a pointer */ 2 | int main(void) { 3 | unsigned long *ptr = 0; 4 | long l = 100; 5 | ptr ^ l; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/compound_assignment_not_lval.c: -------------------------------------------------------------------------------- 1 | // The result of a compound assignment expression isn't an lvalue, so you can't 2 | // take its address with & 3 | int main(void) { 4 | int i = 100; 5 | int *ptr = &(i += 200); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/compound_divide_pointer.c: -------------------------------------------------------------------------------- 1 | /* A pointer can't appear as the left or right operand 2 | * of the *=, /=, or %= operator 3 | */ 4 | int main(void) { 5 | int *x = 0; 6 | int *y = 0; 7 | x /= y; 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/compound_mod_pointer.c: -------------------------------------------------------------------------------- 1 | /* A pointer can't appear as the left or right operand 2 | * of the *=, /=, or %= operator 3 | */ 4 | int main(void) { 5 | int i = 10; 6 | int *ptr = &i; 7 | i %= ptr; 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/compound_multiply_pointer.c: -------------------------------------------------------------------------------- 1 | /* A pointer can't appear as the left or right operand 2 | * of the *=, /=, or %= operator 3 | */ 4 | int main(void) { 5 | int *x = 0; 6 | x *= 2; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/postfix_decr_not_lvalue.c: -------------------------------------------------------------------------------- 1 | // The result of a postfix ++ or -- operation is not an lvalue, 2 | // so you can't take its address. 3 | int main(void) { 4 | int i = 10; 5 | int *ptr = &i--; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/extra_credit/prefix_incr_not_lvalue.c: -------------------------------------------------------------------------------- 1 | // The result of a prefix ++ or -- operation is not an lvalue, 2 | // so you can't take its address 3 | int main(void) { 4 | int i = 10; 5 | int *ptr = &++i; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/invalid_static_initializer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to initialize a static pointer with a non-pointer value */ 2 | static int *x = 10; 3 | 4 | int main(void) { 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/multiply_pointers.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to multiply, divide, or take the modulo of pointers */ 2 | int main(void) { 3 | int *x = 0; 4 | int *y = x; 5 | (x * y); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/multiply_pointers_2.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to multiply, divide, or take the modulo of pointers */ 2 | int main(void) 3 | { 4 | int *x = 0; 5 | (0 * x); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/invalid_types/negate_pointer.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to negate a pointer */ 2 | int main(void) { 3 | int *x = 0; 4 | -x; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_14/valid/dereference/simple.c: -------------------------------------------------------------------------------- 1 | /* A basic dereferencing test case */ 2 | 3 | int main(void) { 4 | int x = 3; 5 | int *ptr = &x; 6 | return *ptr; 7 | } -------------------------------------------------------------------------------- /tests/chapter_14/valid/libraries/global_pointer.c: -------------------------------------------------------------------------------- 1 | double *d_ptr; 2 | 3 | int update_thru_ptr(double new_val) { 4 | *d_ptr = new_val; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_14/valid/libraries/global_pointer_client.c: -------------------------------------------------------------------------------- 1 | extern double *d_ptr; 2 | int update_thru_ptr(double new_val); 3 | 4 | int main(void) { 5 | double d = 0.0; 6 | d_ptr = &d; 7 | update_thru_ptr(10.0); 8 | return (d == 10.0); 9 | 10 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/array_of_functions.c: -------------------------------------------------------------------------------- 1 | // This is a parse error in our implementation 2 | // but could also be a type error 3 | int foo[3](int a); 4 | -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/array_of_functions_2.c: -------------------------------------------------------------------------------- 1 | // Identical to array_of_functions.c but parenthesized differently 2 | int (foo[3])(int a); -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/double_declarator.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // array size must be an integer 3 | int x[2.0]; 4 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/empty_initializer_list.c: -------------------------------------------------------------------------------- 1 | // An initializer list must have at least one element 2 | // NOTE: empty initializer lists are valid as of C23 3 | int main(void) { 4 | int arr[1] = {}; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/malformed_abstract_array_declarator.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // invalid abstract declarator syntax: pointer declarator can't follow 3 | // array size declarator 4 | return (int[3] *)0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/malformed_abstract_array_declarator_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // pointer declarator can't follow array size declarator 3 | return (int[3](*))0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/malformed_array_declarator.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int foo[[10]]; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/malformed_array_declarator_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // invalid declarator syntax: can't have parenthesized (*) in non-abstract declarator 3 | int (*)(ptr_to_array[3]) = 0; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/malformed_array_declarator_3.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // array size specifier must follow identifier 3 | int [3] arr = {1, 2, 3}; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/malformed_type_name.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 4; 3 | int *foo = &a; 4 | // invalid cast syntax; missing type specifier 5 | int *bar[3] = (*[3]) foo; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/malformed_type_name_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int *ptr; 3 | // this is malformed in two ways: the declarator itself is invalid, 4 | // and it's missing a type specifier 5 | int *array_pointer[3] = ([3](*)) ptr; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/mismatched_subscript.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int indices[3] = {1, 2, 3}; 3 | int vals[3] = {4, 5, 6}; 4 | return vals[indices[1]; 5 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/parenthesized_array_of_functions.c: -------------------------------------------------------------------------------- 1 | // Basically the same test case as array_of_functions.c 2 | // In other implementations this might be a type error, not a parse error 3 | int(foo[3])(int a); -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/return_array.c: -------------------------------------------------------------------------------- 1 | /* In our implementation this is a parse error; in others it could be a type error. */ 2 | int foo(void)[3]; -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/unclosed_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int arr = {1, 2; 3 | return arr[0]; 4 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/unclosed_nested_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int arr[2][2] = {{ 1, 2}, {3, 4}; 3 | return arr[0][0]; 4 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_parse/unclosed_subscript.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int arr[] = {1, 2, 3}; 3 | return arr[1; 4 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/add_two_pointers.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int *x = 0; 4 | int *y = 0; 5 | // it's illegal to add two values of pointer type 6 | return (x + y == 0); 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/assign_to_array.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int arr[3] = {1, 2, 3}; 4 | int arr2[3] = {4, 5, 6}; 5 | // arr has array type, so it can't be assigned to 6 | arr = arr2; 7 | return arr[0]; 8 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/assign_to_array_2.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int dim2[1][2] = {{1, 2}}; 4 | int dim[2] = {3, 4}; 5 | // dim2 has array type, so it can't be assigned to 6 | dim2[0] = dim; 7 | return dim[0]; 8 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/assign_to_array_3.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int arr[3] = { 1, 2, 3}; 3 | int (*ptr_to_array)[3]; 4 | // *ptr_to_array has array type, so we can't assign to it 5 | *ptr_to_array = arr; 6 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/bad_arg_type.c: -------------------------------------------------------------------------------- 1 | int foo(int **x) { 2 | return x[0][0]; 3 | } 4 | 5 | int main(void) { 6 | int arr[1] = {10}; 7 | return foo(&arr); // a pointer to an array is not the same as a pointer to a pointer 8 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/cast_to_array_type.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int arr[10]; 4 | // casts to array type are illegal 5 | return (int[10])arr; 6 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/cast_to_array_type_2.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | long arr[10]; 4 | // casts to array type are illegal 5 | return (int *[10])arr; 6 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/cast_to_array_type_3.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | long arr[6]; 4 | // casts to array type are illegal 5 | return ((long(([2])[3]))arr); 6 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/compare_pointer_to_int.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | long *l = 0; 4 | // It's illegal to compare a pointer to any integer type 5 | // without explicitly casting to the same type 6 | return l <= 100ul; 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/compound_initializer_too_long_static.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | static int arr[3] = {1, 2, 3, 4}; 3 | return arr[2]; 4 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/compound_inititializer_too_long.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int arr[3] = {1, 2, 3, 4}; 3 | return arr[2]; 4 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/conflicting_array_declarations.c: -------------------------------------------------------------------------------- 1 | int arr[6]; 2 | 3 | int main(void) { 4 | return arr[0]; 5 | } 6 | 7 | // it's illegal to redeclare arr as a different type 8 | int arr[5]; -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/extra_credit/compound_add_double_to_pointer.c: -------------------------------------------------------------------------------- 1 | // If LHS of += or -= is a pointer, RHS must be an integer (not a double or pointer) 2 | int main(void) { 3 | int arr[3] = {1, 2, 3}; 4 | int *elem = arr; 5 | elem += 1.0; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/extra_credit/compound_assign_to_array.c: -------------------------------------------------------------------------------- 1 | // An array that decays to a pointer is not an lvalue, so you can't 2 | // assign to it with += or -= 3 | int main(void) { 4 | int arr[3] = {1, 2, 3}; 5 | arr -= 1; 6 | 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/extra_credit/compound_sub_pointer_from_int.c: -------------------------------------------------------------------------------- 1 | // += and -= operators: RHS must not be a pointer regardless of LHS type 2 | int main(void) { 3 | int arr[3] = {1, 2, 3}; 4 | int *elem = arr + 1; 5 | int i = 0; 6 | i -= elem; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/extra_credit/postfix_incr_array.c: -------------------------------------------------------------------------------- 1 | // An array that decays to a pointer is not an lvalue, so you can't 2 | // apply ++ or -- to it 3 | int main(void) { 4 | int arr[3] = {1, 2, 3}; 5 | arr++; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/extra_credit/prefix_decr_array.c: -------------------------------------------------------------------------------- 1 | // An array that decays to a pointer is not an lvalue, so you can't 2 | // apply ++ or -- to it 3 | int main(void) { 4 | int arr[3] = {1, 2, 3}; 5 | --arr; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/extra_credit/switch_on_array.c: -------------------------------------------------------------------------------- 1 | // Can't switch on expression of array type 2 | int main(void) { 3 | int arr[3] = {1, 2, 3}; 4 | switch (arr) { 5 | default: 6 | return 0; 7 | } 8 | return 1; 9 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/function_returns_array.c: -------------------------------------------------------------------------------- 1 | /* This is a type error, but note that because of the grammar rule for 2 | * declarators in our implementation, it would be a parse error without the parentheses: 3 | * int foo(void)[3][4] 4 | */ 5 | int(foo(void))[3][4]; -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/incompatible_elem_type_compound_init.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | // invalid implicit conversion of double 1.0 to type int * 4 | int *arr[3] = {0, 0, 1.0}; 5 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/incompatible_elem_type_static_compound_init.c: -------------------------------------------------------------------------------- 1 | // invalid implicit conversion of double 1.0 to type int * 2 | int *arr[3] = {0, 0, 1.0}; 3 | 4 | int main(void) 5 | { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/null_ptr_array_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | // You can't initialize an array with a scalar, not even a null pointer constant 4 | int arr[1] = 0; 5 | return arr[0]; 6 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/null_ptr_static_array_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | // you can't initialize a static array with a scalar, not even a null pointer constant 4 | static int arr[1] = 0; 5 | return arr[0]; 6 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/scalar_initializer_for_array.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | // You can't initialize an array with a scalar expression. 4 | int arr[1] = 4; 5 | return arr[0]; 6 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/scalar_initializer_for_static_array.c: -------------------------------------------------------------------------------- 1 | // You can't initialize a static array with a scalar expression. 2 | double arr[3] = 1.0; 3 | 4 | int main(void) 5 | { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/sub_different_pointer_types.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | long x[10]; 4 | long *ptr = x; 5 | unsigned long *ptr2 = (unsigned long *)ptr; 6 | // You can't subtract pointers to different types 7 | return ptr - ptr2; 8 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/sub_double_from_ptr.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int *y = 0; 4 | // you can't subtract a double from a pointer 5 | return (y - 0.0 == 0.0); 6 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/sub_ptr_from_int.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int *x = 0; 4 | // you can't subtract a pointer from an integer 5 | // Note that 0 is NOT implicitly converted to a null pointer here 6 | return 0 - x == 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/subscript_both_pointers.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int x = 10; 4 | int *ptr = &x; 5 | int *subscript = 0; 6 | // you can't perform subscript operation when both operands are pointers 7 | return ptr[subscript]; 8 | } -------------------------------------------------------------------------------- /tests/chapter_15/invalid_types/subscript_non_ptr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 3; 3 | // one operand in a subscript operation must be a pointer 4 | return a[4]; 5 | } -------------------------------------------------------------------------------- /tests/chapter_15/valid/libraries/global_array.c: -------------------------------------------------------------------------------- 1 | long arr[4] = {1, 2, 3, 4}; 2 | 3 | int double_each_element(void) { 4 | for (int i = 0; i < 4; i = i + 1) { 5 | arr[i] = arr[i] * 2; 6 | } 7 | 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_15/valid/libraries/return_pointer_to_array.c: -------------------------------------------------------------------------------- 1 | // given a nested array of longs, return a pointer to one row in the array 2 | long (*return_row(long (*arr)[3][4], int idx))[4] { 3 | return arr[idx]; 4 | } -------------------------------------------------------------------------------- /tests/chapter_15/valid/subscripting/simple.c: -------------------------------------------------------------------------------- 1 | /* A very simple subscripting test case */ 2 | 3 | int main(void) { 4 | int arr[3] = {1, 2, 3}; 5 | return arr[2]; 6 | } -------------------------------------------------------------------------------- /tests/chapter_15/valid/subscripting/subscript_precedence.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int arr[3] = {1, 2, 3}; 3 | return (-arr[2] == -3); 4 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_lex/char_bad_escape_sequence.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return '\y'; 4 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_lex/newline.c: -------------------------------------------------------------------------------- 1 | char *s = "hello 2 | world "; 3 | 4 | int 5 | main(void) 6 | { 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_lex/string_bad_escape_sequence.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char *str = "foo\ybar"; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_lex/unescaped_backslash.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return '\'; 4 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_lex/unescaped_double_quote.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | char *ptr = "foo"bar"; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_lex/unescaped_single_quote.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return '''; 4 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_lex/unterminated_char_constant.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return 'x 4 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_lex/unterminated_string.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | char *ptr = "foo\"; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_parse/extra_credit/character_const_goto.c: -------------------------------------------------------------------------------- 1 | // You can't use a character constant as a label in a goto statement 2 | int main(void) { 3 | goto 'x'; 4 | 'x'; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_parse/extra_credit/character_const_label.c: -------------------------------------------------------------------------------- 1 | // You can't use a character constant as a label 2 | int main(void) { 3 | 'x': return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_parse/extra_credit/string_literal_goto.c: -------------------------------------------------------------------------------- 1 | // You can't use a string literal as a label in a goto statement 2 | int main(void) { 3 | goto "foo"; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_parse/extra_credit/string_literal_label.c: -------------------------------------------------------------------------------- 1 | // You can't use a string literal as a label 2 | int main(void) { 3 | "foo": return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_parse/invalid_type_specifier.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | // cannot combine char with any other type specifier 4 | // except signed and unsigned 5 | int char x = 10; 6 | return x; 7 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_parse/invalid_type_specifier_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // cannot combine char with any other type specifier 3 | // except signed and unsigned 4 | char static long x = 0; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_parse/misplaced_char_literal.c: -------------------------------------------------------------------------------- 1 | // A char literal is a constant, it's only permitted where constants are 2 | // and not, for example, where you'd normally expect to find a postfix operator 3 | 4 | int main(void) { 5 | int a = 3; 6 | return a'1'; 7 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_parse/string_literal_varname.c: -------------------------------------------------------------------------------- 1 | /* You can't use a string literal as a variable name */ 2 | 3 | int main(void) { 4 | int "x" = 0; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/assign_to_string_literal.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // you can't assign to a string literal; 3 | // it decays to a pointer to string's first element, which isn't an lvalue 4 | "foo" = "bar"; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/compound_initializer_for_pointer.c: -------------------------------------------------------------------------------- 1 | /* You can't initialize a pointer with a compound initializer */ 2 | int main(void) { 3 | char *ptr = {'a', 'b', 'c'}; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/extra_credit/bit_shift_string.c: -------------------------------------------------------------------------------- 1 | // can't apply << or >> to strings 2 | int main(void) { 3 | "foo" << 3; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/extra_credit/bitwise_operation_on_string.c: -------------------------------------------------------------------------------- 1 | // Can't apply bitwise operations to strings 2 | int main(void) { 3 | "My string" & 100; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/extra_credit/case_statement_string.c: -------------------------------------------------------------------------------- 1 | // Can't use strings as labels for case statements 2 | int main(void) { 3 | switch (0) { 4 | case "foo": 5 | return 1; 6 | default: 7 | return 0; 8 | } 9 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/extra_credit/compound_assign_from_string.c: -------------------------------------------------------------------------------- 1 | // Can't use a string on the right side of a compound assignment expression 2 | int main(void) { 3 | char * s = "some string "; 4 | s += "another str"; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/extra_credit/compound_assign_to_string.c: -------------------------------------------------------------------------------- 1 | // Can't compound assign to string literal 2 | int main(void) { 3 | "My string" += 1; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/extra_credit/postfix_incr_string.c: -------------------------------------------------------------------------------- 1 | // can't apply postfix ++/-- to string literals 2 | int main(void) { 3 | "foo"++; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/extra_credit/prefix_incr_string.c: -------------------------------------------------------------------------------- 1 | // Can't apply prefix ++/-- to string literal 2 | int main(void) { 3 | ++"foo"; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/extra_credit/switch_on_string.c: -------------------------------------------------------------------------------- 1 | // can't use string literal as controlling expression in switch statement 2 | int main(void) { 3 | switch ("foo") { 4 | default: 5 | return 0; 6 | } 7 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/implicit_conversion_between_char_pointers.c: -------------------------------------------------------------------------------- 1 | /* You can't implicitly convert a char * to a signed char * because they're different types. */ 2 | int main(void) { 3 | char *c = 0; 4 | signed char *s = c; 5 | return (int) s; 6 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/negate_char_pointer.c: -------------------------------------------------------------------------------- 1 | /* You can't negate pointers, including pointers to char */ 2 | int main(void) { 3 | char *x = "foo"; 4 | return -x; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/string_initializer_too_long.c: -------------------------------------------------------------------------------- 1 | /* You can't initialize a char array from a string literal 2 | * that's too long to fit in it */ 3 | int main(void) { 4 | char too_long[3] = "abcd"; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/string_initializer_too_long_static.c: -------------------------------------------------------------------------------- 1 | /* You can't initialize a char array (including a static one) 2 | * from a string literal that's too long to fit in it */ 3 | int main(void) { 4 | static char too_long[3] = "abcd"; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_16/invalid_types/string_initializer_wrong_type.c: -------------------------------------------------------------------------------- 1 | /* String literals can only initialize char arrays, 2 | * not arrays of other types */ 3 | int main(void) { 4 | long ints[4] = "abc"; 5 | return ints[1]; 6 | } -------------------------------------------------------------------------------- /tests/chapter_16/valid/char_constants/return_char_constant.c: -------------------------------------------------------------------------------- 1 | /* Simplest possible test case for using a character constant */ 2 | int main(void) { 3 | return 'c'; // ASCII value 99 4 | } -------------------------------------------------------------------------------- /tests/chapter_16/valid/chars/data_on_page_boundary_linux.s: -------------------------------------------------------------------------------- 1 | .bss 2 | .align 4096 3 | .zero 4090 4 | .globl zed 5 | zed: 6 | .zero 1 7 | .section ".note.GNU-stack","",@progbits 8 | -------------------------------------------------------------------------------- /tests/chapter_16/valid/chars/data_on_page_boundary_osx.s: -------------------------------------------------------------------------------- 1 | .bss 2 | .align 12 3 | .zero 4090 4 | .globl _zed 5 | _zed: 6 | .zero 1 7 | -------------------------------------------------------------------------------- /tests/chapter_16/valid/libraries/global_char.c: -------------------------------------------------------------------------------- 1 | char c = 100; 2 | unsigned char uc = 250; 3 | signed char sc = 0; 4 | 5 | int update_global_chars(void) { 6 | c = c + 10; 7 | uc = uc + 10; // wraps around 8 | sc = sc - 10; 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_16/valid/strings_as_initializers/simple.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // simple test of initializing and subscripting char array 3 | unsigned char chars[4] = "abc"; 4 | return chars[2]; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/valid/strings_as_lvalues/empty_string.c: -------------------------------------------------------------------------------- 1 | /* Test that we add a terminating null byte to the empty string */ 2 | int main(void) { 3 | char *empty = ""; 4 | return empty[0]; 5 | } -------------------------------------------------------------------------------- /tests/chapter_16/valid/strings_as_lvalues/simple.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | char *x = "Hello, World!"; 3 | return x[2]; 4 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_parse/bad_specifier.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | unsigned void *v; // you can't combine void with other type specifiers 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_parse/bad_specifier_2.c: -------------------------------------------------------------------------------- 1 | void char *x; // you can't combine void with other type specifiers 2 | 3 | int main(void) { return 0; } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_parse/sizeof_cast.c: -------------------------------------------------------------------------------- 1 | // can't apply sizeof directly to a cast expression 2 | // unless the whole cast expression is parenthesized, e.g. sizeof ((char) 1) 3 | int main(void) { 4 | return sizeof(char) 1; 5 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_parse/sizeof_type_no_parens.c: -------------------------------------------------------------------------------- 1 | // you can't get the size of a type name without parenthesizing it 2 | int main(void) { 3 | return sizeof int; 4 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/bitshift_void.c: -------------------------------------------------------------------------------- 1 | // Can't perform bitshift operations with void operands 2 | void f(void){ 3 | return; 4 | } 5 | 6 | int main(void) { 7 | int x = 10; 8 | x << f(); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/bitwise_void.c: -------------------------------------------------------------------------------- 1 | // Can't perform bitwise operations with void operands 2 | int main(void) { 3 | int x = 10; 4 | int y = 11; 5 | x & (void) y; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/compound_void_rval.c: -------------------------------------------------------------------------------- 1 | // rval in compound expression cannot be void 2 | void f(void) { 3 | return; 4 | } 5 | 6 | int main(void) { 7 | int x = 10; 8 | x *= f(); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/compound_void_rval_add.c: -------------------------------------------------------------------------------- 1 | // rval in compound expression cannot be void 2 | void f(void) { 3 | return; 4 | } 5 | 6 | int main(void) { 7 | int *x = 0; 8 | x += f(); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/compound_void_rval_bitshift.c: -------------------------------------------------------------------------------- 1 | // rval in compound expression cannot be void 2 | void f(void) { 3 | return; 4 | } 5 | 6 | int main(void) { 7 | int x = 10; 8 | x >>= f(); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/postfix_decr_void.c: -------------------------------------------------------------------------------- 1 | // Can't apply postfix ++/-- to void lvalue 2 | extern void *x; 3 | 4 | int main(void) { 5 | ++(*x)--; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/postfix_decr_void_pointer.c: -------------------------------------------------------------------------------- 1 | // Can't apply prefix or postfix ++/-- to pointers to void 2 | void *malloc(unsigned long size); 3 | 4 | int main(void) { 5 | void *buff = malloc(100); 6 | buff--; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/postfix_incr_void_pointer.c: -------------------------------------------------------------------------------- 1 | // Can't apply prefix or postfix ++/-- to pointers to void 2 | void *malloc(unsigned long size); 3 | 4 | int main(void) { 5 | void *buff = malloc(100); 6 | buff++; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/prefix_decr_void_pointer.c: -------------------------------------------------------------------------------- 1 | // Can't apply prefix or postfix ++/-- to pointers to void 2 | void *malloc(unsigned long size); 3 | 4 | int main(void) { 5 | void *buff = malloc(100); 6 | --buff; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/prefix_incr_void.c: -------------------------------------------------------------------------------- 1 | // Can't apply prefix ++/-- to void lvalue 2 | extern void *x; 3 | 4 | int main(void) { 5 | ++(*x); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/prefix_incr_void_pointer.c: -------------------------------------------------------------------------------- 1 | // Can't apply prefix or postfix ++/-- to pointers to void 2 | void *malloc(unsigned long size); 3 | 4 | int main(void) { 5 | void *buff = malloc(100); 6 | ++buff; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/extra_credit/switch_void.c: -------------------------------------------------------------------------------- 1 | // Can't use void controlling expression in switch statement 2 | void f(void) { 3 | return; 4 | } 5 | 6 | int main(void) { 7 | switch(f()) { 8 | default: return 0; 9 | } 10 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/sizeof_function.c: -------------------------------------------------------------------------------- 1 | int x(void) { return 0; } 2 | 3 | // can't apply sizeof to a function 4 | int main(void) { return sizeof x; } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/sizeof_void.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return sizeof (void); // can only apply sizeof to complete types 3 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/sizeof_void_array.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // the element type in an array declarator must be complete 3 | return sizeof(void[3]); 4 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/sizeof_void_expression.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x; 3 | // can't apply sizeof to an expression with incomplete type 4 | return sizeof((void)x); 5 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/sub_void_pointer.c: -------------------------------------------------------------------------------- 1 | // no pointer arithmetic with pointers to incomplete type 2 | // (GCC/Clang allow this as an extension) 3 | 4 | int main(void) { 5 | int y; 6 | void *x = &y; 7 | void *null = 0; 8 | return x - null; 9 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/subscript_void.c: -------------------------------------------------------------------------------- 1 | // you can't subscript pointers to incomplete types 2 | // although Clang/GCC let you subscript void * as a language extension 3 | int main(void) { 4 | int x = 10; 5 | void *v = &x; 6 | v[0]; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/void_array.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | void arr[3]; // array of incomplete element type is illegal 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/void_array_in_cast.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | (void(*)[3]) 4; // the element type in an array declarator must be complete 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/void_array_nested_in_declaration.c: -------------------------------------------------------------------------------- 1 | extern void (*ptr)[3][4]; // array of incomplete element type is illegal (including nested array) 2 | 3 | void *foo(void) { 4 | return ptr; 5 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/void_array_pointer_in_declaration.c: -------------------------------------------------------------------------------- 1 | void *malloc(unsigned long size); 2 | 3 | int main(void) { 4 | void (*ptr)[3] = malloc(3); // array of incomplete element type is illegal 5 | return ptr == 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/incomplete_types/void_array_pointer_in_param_type.c: -------------------------------------------------------------------------------- 1 | // array of incomplete element type is illegal 2 | int foo(void (*bad_array)[3]) { 3 | return bad_array == 0; 4 | } 5 | 6 | int main(void) { 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/pointer_conversions/compare_void_ptr_to_int.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return (void *)0 == 20ul; // you can't compare pointers to ints 3 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/pointer_conversions/compare_void_to_other_pointer.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int arr[3] = {1, 2, 3}; 3 | void *ptr = (void *)arr; 4 | // you can't compare pointers to different types, e..g. void * to int * 5 | return ptr < arr + 1; 6 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/pointer_conversions/convert_ulong_to_void_ptr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | unsigned long x = 0; 3 | void *v = x; // can't implicitly convert a non-pointer type to a pointer 4 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/pointer_conversions/convert_void_ptr_to_int.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | void *x = 0; 3 | return x; // can't implicitly convert void * to integer as if by assignment 4 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/pointer_conversions/usual_arithmetic_conversions_ptr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // can't convert void * to int with usual arithmetic conversions 3 | int i = 10 * (void *)0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/scalar_expressions/and_void.c: -------------------------------------------------------------------------------- 1 | // void expressions are non-scalar, so they can't be used in logical expressions 2 | 3 | int main(void) { 4 | return (void)1 && 2; 5 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/scalar_expressions/cast_void.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // can only cast scalar values to int (or to any scalar type) 3 | int y = (int) (void) 3; 4 | return y; 5 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/scalar_expressions/not_void.c: -------------------------------------------------------------------------------- 1 | // void expressions are non-scalar, so they can't be used in logical expressions 2 | 3 | void f(void); 4 | void g(void); 5 | int main(void) { return !(1 ? f() : g()); } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/scalar_expressions/or_void.c: -------------------------------------------------------------------------------- 1 | // void expressions are non-scalar, so they can't be used in logical expressions 2 | 3 | int main(void) { return 1 || (void)2; } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/scalar_expressions/void_if_condition.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 10; 3 | 4 | // void expressions are non-scalar, so they can't be used as controlling conditions 5 | if ((void)x) 6 | return 0; 7 | return 1; 8 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/scalar_expressions/void_ternary_condition.c: -------------------------------------------------------------------------------- 1 | void f(void); 2 | 3 | int main(void) { 4 | // the condition in a ternary expression must have scalar type 5 | return f() ? 1 : 2; 6 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/void/assign_void_rval.c: -------------------------------------------------------------------------------- 1 | /* can't convert void to another type by assignment */ 2 | int main(void) { 3 | int a = 10; 4 | a = (void)20; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/void/negate_void.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | -(void)10; // you can't negate void expressions, only arithmetic expressions 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/void/no_return_value.c: -------------------------------------------------------------------------------- 1 | int foo(void) { 2 | // function with non-void return type 3 | // must return a value 4 | return; 5 | } 6 | 7 | int main(void) { 8 | foo(); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/void/non_void_return.c: -------------------------------------------------------------------------------- 1 | void x(void) { 2 | // a function with a void return type can't return an expression 3 | return 1; 4 | } 5 | 6 | int main(void) { 7 | x(); 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/void/return_void_as_pointer.c: -------------------------------------------------------------------------------- 1 | void *x(void) { 2 | // you can't implicitly convert a void expression to another type 3 | return (void)0; 4 | } 5 | -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/void/subscript_void.c: -------------------------------------------------------------------------------- 1 | // subscript expression requires an integer index, not void 2 | 3 | int main(void) { 4 | char arr[3]; 5 | return arr[(void)1]; 6 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/void/void_compare.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // you can't compare void expressions 3 | if ((void)1 < (void)2) 4 | return 1; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/void/void_equality.c: -------------------------------------------------------------------------------- 1 | void x(void); 2 | int main(void) { 3 | // you can't compare void expressions 4 | return x() == (void)10; 5 | } -------------------------------------------------------------------------------- /tests/chapter_17/invalid_types/void/void_fun_params.c: -------------------------------------------------------------------------------- 1 | // The standard doesn't technically prohibit void parameters 2 | // but there is no conceivable reason to allow them 3 | void foo(void x); 4 | 5 | int main(void) { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_17/valid/libraries/sizeof_extern.c: -------------------------------------------------------------------------------- 1 | /* Test that we correctly calculate the size of objects declared in other translation units */ 2 | 3 | double large_array[1000][2000]; -------------------------------------------------------------------------------- /tests/chapter_17/valid/libraries/sizeof_extern_client.c: -------------------------------------------------------------------------------- 1 | 2 | extern double large_array[1000][2000]; 3 | 4 | int main(void) { 5 | return sizeof large_array == 16000000; 6 | } -------------------------------------------------------------------------------- /tests/chapter_17/valid/sizeof/sizeof_not_evaluated.c: -------------------------------------------------------------------------------- 1 | void exit(int status); 2 | int foo(void) { exit(10); } 3 | 4 | int main(void) { 5 | // make sure foo isn't actually called 6 | return sizeof(foo()); 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_lex/dot_bad_token_2.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | int main(void) { 6 | struct s x; 7 | // Recognize .0foo as an invalid token instead of a struct member operator 8 | return x.0foo; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/arrow_missing_member.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int y; 3 | }; 4 | 5 | int main(void) { 6 | struct s *ptr = 0; 7 | return ptr->; // arrow must be followed by a member name 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/dot_invalid_member.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int y; 3 | }; 4 | 5 | struct s x; 6 | // dot operator must be immediately followed by member name 7 | // (can't parenthesize it) 8 | int main(void) { 9 | return x.(y); 10 | } 11 | -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/dot_no_left_expr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return .a; // a dot operator can only appear after an expression 3 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/empty_initializer_list.c: -------------------------------------------------------------------------------- 1 | // An initializer list must have at least one element 2 | // NOTE: empty initializer lists are valid as of C23 3 | 4 | struct s {int a;}; 5 | 6 | int main(void) { 7 | struct s foo = {}; 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/default_kw_member_name.c: -------------------------------------------------------------------------------- 1 | // because 'default' is a keyword, we can't use it as a member name 2 | struct s { 3 | int default; 4 | }; 5 | 6 | int main(void) { 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/goto_kw_struct_tag.c: -------------------------------------------------------------------------------- 1 | // Because 'goto' is a keyword, we can't use it as a struct tag 2 | struct goto { int a; }; 3 | int main(void) { 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/struct_union.c: -------------------------------------------------------------------------------- 1 | // Can't use struct and union keywords in same declaration 2 | union struct s { 3 | int a; 4 | }; 5 | 6 | int main(void) { 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/two_union_kws.c: -------------------------------------------------------------------------------- 1 | union u { 2 | int a; 3 | }; 4 | 5 | union union u x; // can't use union keyword twice in a type specifier 6 | 7 | int main(void) { 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_bad_type_spec.c: -------------------------------------------------------------------------------- 1 | // Can't combine union type specifier with other type specifier 2 | union x long a; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_decl_bad_type_specifier.c: -------------------------------------------------------------------------------- 1 | // Can't combine union specifier with other type specifier 2 | 3 | union a { int a; }; 4 | 5 | int main(void) { 6 | union a int x; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_decl_empty_member_list.c: -------------------------------------------------------------------------------- 1 | // union member list cannot be empty 2 | // (note that GCC/Clang allow this as an extenision) 3 | union s {}; 4 | 5 | int main(void) { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_decl_extra_semicolon.c: -------------------------------------------------------------------------------- 1 | // Stray semicolon in union declaration 2 | union u { 3 | int a; 4 | ; 5 | }; 6 | 7 | int main(void) { 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_empty_initializer.c: -------------------------------------------------------------------------------- 1 | // An initializer list must have at least one element 2 | // NOTE: empty initializer lists are valid as of C23 3 | union u { int a; }; 4 | 5 | int main(void) { 6 | union u x = {}; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_member_initializer.c: -------------------------------------------------------------------------------- 1 | union a { 2 | // union members cannot have initializers 3 | int member = 1; 4 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_member_is_function.c: -------------------------------------------------------------------------------- 1 | union s { 2 | // a union member can't be a function 3 | // we treat this as a parse error, but it would also be reasonable 4 | // to handle it during type checking 5 | int foo(void); 6 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_member_name_kw.c: -------------------------------------------------------------------------------- 1 | // Can't use a keyword as a union member name 2 | 3 | union u { 4 | int struct; 5 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_member_no_type.c: -------------------------------------------------------------------------------- 1 | union u { 2 | a; // each union member declaration must specify a type 3 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_member_storage_class.c: -------------------------------------------------------------------------------- 1 | union y { 2 | // union member cannot have storage class 3 | static int a; 4 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_struct_tag.c: -------------------------------------------------------------------------------- 1 | // can't use 'struct' as the keyword for a union declaration 2 | union struct { 3 | int a; 4 | }; 5 | 6 | int main(void) { 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_two_tags.c: -------------------------------------------------------------------------------- 1 | /* Union tag must be a single identifier */ 2 | 3 | union x y { 4 | int a; 5 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_var_bad_tag.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | union 4 foo; // a union tag must be an identifier (not a constant) 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/extra_credit/union_var_tag_paren.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int y; 3 | }; 4 | 5 | int main(void) { 6 | // can't parenthesize union tag 7 | union(s) var; 8 | 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/misplaced_storage_class.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | // storage class specifier can't come between struct keyword and tag 6 | struct static s foo; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_decl_double_semicolon.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | ; // extra semicolon that doesn't follow declaration is a syntax error 4 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_decl_empty_member_list.c: -------------------------------------------------------------------------------- 1 | // struct member list cannot be empty 2 | // (note that GCC/Clang allow this as an extenision) 3 | struct s {}; 4 | 5 | int main(void) { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_decl_extra_semicolon.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | ; // extra semicolon that doesn't follow declaration is a syntax error 3 | int a; 4 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_decl_kw_wrong_order.c: -------------------------------------------------------------------------------- 1 | // struct keyword must come before tag 2 | s struct x { int a; }; 3 | 4 | int main(void) { 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_decl_missing_end_semicolon.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | } // a structure declaration must end with a semicolon 4 | 5 | int main(void) { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_decl_tag_kw.c: -------------------------------------------------------------------------------- 1 | // cannot use keyword (like 'for') as struct tag 2 | struct for { 3 | int a; 4 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_decl_two_kws.c: -------------------------------------------------------------------------------- 1 | struct struct s; // struct keyword can only appear once in a type declaration 2 | 3 | int main(void) { 4 | return 1; 5 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_member_initializer.c: -------------------------------------------------------------------------------- 1 | struct a { 2 | // structure members cannot have initializers 3 | int member = 1; 4 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_member_is_function.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | // a structure member can't be a function 3 | // we treat this as a parse error, but it would also be reasonable 4 | // to handle it during type checking 5 | int foo(void); 6 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_member_name_kw.c: -------------------------------------------------------------------------------- 1 | // cannot use a keyword (like 'return') as a field name 2 | 3 | struct s { 4 | int return; 5 | } 6 | 7 | int main(void) { 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_member_no_semicolon.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a // structure member declaration must end with a semicolon 3 | }; 4 | 5 | int main(void) { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_member_no_type.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | a; // each structure member declaration must specify a type 3 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/struct_member_storage_class.c: -------------------------------------------------------------------------------- 1 | struct y { 2 | // structure member cannot have storage class 3 | static int a; 4 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/var_decl_bad_tag_1.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | struct 4 foo; // a struct tag must be an identifier (not a constant) 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/var_decl_bad_tag_2.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int y; 3 | }; 4 | 5 | int main(void) { 6 | // can't parenthesize struct tag 7 | struct(s) var; 8 | 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/var_decl_bad_type_specifier.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | // cannot combine struct keyword with other type specifier 4 | struct s long a; 5 | 6 | int main(void) { 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/var_decl_missing_struct_kw.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | struct x; 3 | x y; // you can't specify a structure type with just the tag; you need the 4 | // 'struct' specifier 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/var_decl_two_struct_kws.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | struct struct s x; // can't use struct keyword twice in a type specifier 6 | 7 | int main(void) { 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_parse/var_decl_two_tags.c: -------------------------------------------------------------------------------- 1 | /* Structure tag must be a single identifier */ 2 | 3 | struct x y { 4 | int a; 5 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/incomplete_unions/define_incomplete_union.c: -------------------------------------------------------------------------------- 1 | union u; // declare incomplete union type 2 | 3 | union u my_union; // INVALID: defining variable with incomplete union type -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/incomplete_unions/sizeof_incomplete_union_type.c: -------------------------------------------------------------------------------- 1 | // Can't apply sizeof to an incomplete union type 2 | 3 | int main(void) { 4 | union u; 5 | return sizeof(union u); // invalid - union u type is incomplete 6 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/other_features/bitwise_op_structure.c: -------------------------------------------------------------------------------- 1 | // Can't use operands of structure type in bitwise expressions 2 | struct s {int i;}; 3 | int main(void) { 4 | struct s x = {100}; 5 | int i = 1000; 6 | x & i; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/other_features/compound_assign_to_struct.c: -------------------------------------------------------------------------------- 1 | // Can't use operands of structure type in compound assignment operations 2 | struct s { int i; }; 3 | int main(void) { 4 | struct s x = {10}; 5 | x += 10; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/other_features/postfix_incr_struct.c: -------------------------------------------------------------------------------- 1 | // Can't apply prefix or postfix ++/-- to structures 2 | struct s { 3 | int i; 4 | }; 5 | 6 | int main(void) { 7 | struct s my_struct = {1}; 8 | my_struct++; 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/other_features/prefix_decr_struct.c: -------------------------------------------------------------------------------- 1 | // Can't apply prefix or postfix ++/-- to structures 2 | struct s { 3 | int i; 4 | }; 5 | 6 | int main(void) { 7 | struct s my_struct = {1}; 8 | --my_struct; 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/scalar_required/cast_union_to_int.c: -------------------------------------------------------------------------------- 1 | // Can't cast union to scalar type even if it has the right size 2 | union u { 3 | int i; 4 | }; 5 | 6 | int main(void) { 7 | union u x = {10}; 8 | return (int)x; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/scalar_required/compare_unions.c: -------------------------------------------------------------------------------- 1 | // Can't compare objects of union type 2 | 3 | union u { long l; }; 4 | 5 | int main(void){ 6 | union u x = {1}; 7 | x == x; // illegal 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/union_initializers/scalar_union_initializer.c: -------------------------------------------------------------------------------- 1 | /* You can't initialize a union with a scalar value */ 2 | union u {int a;}; 3 | 4 | int main(void){ 5 | union u my_union = 1; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/union_initializers/static_scalar_union_initializer.c: -------------------------------------------------------------------------------- 1 | /* You can't initialize a union with a scalar value */ 2 | union u {int a;}; 3 | 4 | int main(void){ 5 | static union u my_union = 1; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/union_struct_conflicts/conflicting_tag_declarations.c: -------------------------------------------------------------------------------- 1 | /* It's illegal to specify struct and union types with the same tag in the same scope */ 2 | struct x; 3 | union x; 4 | 5 | int main(void) { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/union_type_declarations/duplicate_union_def.c: -------------------------------------------------------------------------------- 1 | /* YOu can't declare the same union type twice. */ 2 | 3 | int main(void) { 4 | union u {int a;}; 5 | union u {int a;}; // illegal - duplicate declaration 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/union_type_declarations/incomplete_union_member.c: -------------------------------------------------------------------------------- 1 | /* You can't declare a union with an incomplete member type */ 2 | struct s; 3 | union u { 4 | struct s bad_struct; 5 | }; 6 | 7 | int main(void){ 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/union_type_declarations/member_name_conflicts.c: -------------------------------------------------------------------------------- 1 | /* You can't declare two members of the same union with the same name */ 2 | union u { 3 | int a; 4 | int a; 5 | }; 6 | 7 | int main(void) { 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/extra_credit/union_type_declarations/union_self_reference.c: -------------------------------------------------------------------------------- 1 | union u { 2 | int i; 3 | union u self; //illegal; incomplete member type 4 | }; 5 | 6 | int main(void) { 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/incompatible_types/assign_different_pointer_type.c: -------------------------------------------------------------------------------- 1 | struct s1; 2 | struct s2; 3 | 4 | int main(void) { 5 | struct s1 *p1 = 0; 6 | struct s2 *p2 = 0; 7 | p2 = p1; // can't assign to struct s2 * from struct s1 * 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/incompatible_types/branch_mismatch_2.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | int main(void) { 6 | struct s x = {1}; 7 | // can't have conditional branches where only one branch is a struct 8 | 1 ? x : (void) 2; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/initializers/initialize_nested_static_struct_member_wrong_type.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | double d; 3 | void *arr[3]; 4 | }; 5 | 6 | // can't initialize a nested element of type void * with a constant of type double 7 | struct s x = {0.0, {1.0}}; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/initializers/initialize_static_struct_with_zero.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | // you can't initialize a static struct (or any struct) with a scalar constant 6 | struct s x = 0; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/initializers/initialize_struct_with_scalar.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | struct pair { 3 | int x; 4 | int y; 5 | }; 6 | 7 | // you can't initialize a struct with a scalar expression 8 | struct pair p = 1; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/initializers/non_constant_static_init.c: -------------------------------------------------------------------------------- 1 | struct pair { 2 | int a; 3 | int b; 4 | }; 5 | struct pair x = {1, 2}; 6 | // you can't initialize a static variable with a non-constant expression 7 | struct pair y = x; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/initializers/static_initializer_too_long.c: -------------------------------------------------------------------------------- 1 | struct pair { 2 | int a; 3 | int b; 4 | }; 5 | // a static compound structure initializer can't initialize more values than the 6 | // struct has 7 | struct pair p = {1, 2, 3}; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/assign_to_incomplete_var.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | extern struct s x; 4 | extern struct s y; 5 | 6 | int main(void) { 7 | x = y; // can't assign to or from variable with incomplete type 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/cast_incomplete_struct.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | extern struct s v; 4 | 5 | int main(void) { 6 | // you can't perform a cast on a struct with incomplete type 7 | (void)v; 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/deref_incomplete_struct_pointer.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | struct s *ptr = 0; 4 | 5 | int main(void) { 6 | // can't dereference pointer to incomplete type 7 | // except in expression &*ptr 8 | *ptr; 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/incomplete_arg_funcall.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | void f(struct s param); 4 | 5 | extern struct s extern_var; 6 | 7 | int main(void) { 8 | // can't pass a variable with incomplete type as an argument 9 | f(extern_var); 10 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/incomplete_local_var.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | int main(void) { 4 | // can't define a local variable (or any variable) with incomplete type 5 | struct s v; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/incomplete_param.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | // it's illegal to define a function with a parameter of incomplete type, 4 | // even if the parameter isn't used 5 | int foo(struct s x) { return 0; } 6 | -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/incomplete_ptr_addition.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | extern struct s *ptr; 4 | 5 | int main(void) { 6 | // can't perform pointer addition w/ pointers to incomplete types 7 | return ptr + 0 == ptr; 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/incomplete_ptr_subtraction.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | extern struct s *ptr; 4 | 5 | int main(void) { 6 | // can't perform pointer substraction w/ pointers to incomplete types 7 | return (ptr - ptr) == 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/incomplete_return_type_funcall.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | struct s f(void); 4 | 5 | int main(void) { 6 | f(); // can't call a function with an incomplete return type (besides void) 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/incomplete_struct_full_expr.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | extern struct s x; 4 | 5 | int main(void) { 6 | // can't use expression w/ incomplete struct type as expression statement 7 | for (x;;) 8 | ; 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/incomplete_struct_member.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | extern struct s foo; 4 | 5 | int main(void) { 6 | return foo.a; // can't get member of incomplete structure type 7 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/incomplete_subscript.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | extern struct s *ptr; 3 | 4 | // can't subscript a pointer to an incomplete type 5 | // this is equivalent to dereferencing a pointer to an incomplete type 6 | int main(void) { ptr[0]; } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_incomplete_structs/sizeof_incomplete.c: -------------------------------------------------------------------------------- 1 | struct s; 2 | 3 | int main(void) { 4 | return sizeof(struct s); // can't take size of incomplete type 5 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_member_operators/arrow_pointer_to_non_struct.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | long l; 3 | }; 4 | 5 | int main(void) { 6 | double d = 0.0; 7 | double* ptr = &d; 8 | return ptr->l; // can't apply -> operator to pointer to non-struct 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_member_operators/member_pointer_non_struct_pointer.c: -------------------------------------------------------------------------------- 1 | struct a { 2 | int x; 3 | int y; 4 | }; 5 | 6 | int main(void) { 7 | struct a my_struct = {1, 2}; 8 | // can't apply -> to non-pointer 9 | return my_struct->x; 10 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_struct_declaration/duplicate_member_name.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | // can't declare two members with same name 3 | int x; 4 | double x; 5 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_struct_declaration/incomplete_member.c: -------------------------------------------------------------------------------- 1 | struct s; // declare incomplete structure type 2 | 3 | struct a { 4 | // can't declare a struct member with incomplete type 5 | struct s g; 6 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/invalid_struct_declaration/void_member.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | // can't declare structure members with incomplete type, including void 3 | void x; 4 | }; -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/scalar_required/and_struct.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | int main(void) { 6 | struct s x = {1}; 7 | return 0 && x; // can't apply boolean operators to structs 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/scalar_required/assign_scalar_to_struct.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | struct s x = {1}; 6 | 7 | int main(void) { 8 | struct s *ptr = &x; 9 | *ptr = 2; // can't assign scalar value to lvalue of struct type 10 | return 0; 11 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/scalar_required/cast_struct_to_scalar.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | int main(void) { 6 | struct s x = {1}; 7 | // can't cast struct to a scalar value 8 | int y = (int)x; 9 | return y; 10 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/scalar_required/compare_structs.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | int main(void) { 6 | struct s x = {1}; 7 | struct s y = {2}; 8 | return x == y; // can only apply == operator to scalars, not structures 9 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/scalar_required/not_struct.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | int main(void) { 6 | struct s x = {1}; 7 | return !x; // can only apply boolean operators to scalars, not structs 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/scalar_required/struct_as_int.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | int main(void) { 6 | struct s x = {1}; 7 | // can only apply ~ operator to ints, not structs 8 | (void)~x; 9 | return 0; 10 | } -------------------------------------------------------------------------------- /tests/chapter_18/invalid_types/scalar_required/subscript_struct.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int a; 3 | }; 4 | 5 | int main(void) { 6 | struct s x = {1}; 7 | return x[0]; // can only subscript pointers, not structures 8 | } -------------------------------------------------------------------------------- /tests/chapter_18/valid/no_structure_parameters/parse_and_lex/struct_member_looks_like_const.c: -------------------------------------------------------------------------------- 1 | struct s { 2 | int E10; 3 | }; 4 | 5 | int main(void) { 6 | struct s x1 = {3}; 7 | return x1.E10; // lex correctly, recognizing that 1.E10 is not a constant 8 | } 9 | -------------------------------------------------------------------------------- /tests/chapter_19/unreachable_code_elimination/and_clause.c: -------------------------------------------------------------------------------- 1 | /* Test that we eliminate the second clause in 0 && y */ 2 | int putchar(int c); 3 | 4 | int target(void) { 5 | return 0 && putchar(97); 6 | } 7 | 8 | int main(void) { 9 | return target(); 10 | } -------------------------------------------------------------------------------- /tests/chapter_19/unreachable_code_elimination/empty.c: -------------------------------------------------------------------------------- 1 | /* Test that an empty function doesn't crash this optimization pass. 2 | * We don't inspect the assembly for this program, so there's no 'target' 3 | * function 4 | * */ 5 | 6 | int main(void) { 7 | } -------------------------------------------------------------------------------- /tests/chapter_19/unreachable_code_elimination/or_clause.c: -------------------------------------------------------------------------------- 1 | /* Test that we eliminate the second clause in 1 || x */ 2 | int putchar(int c); 3 | 4 | int target(void) { 5 | return 1 || putchar(97); 6 | } 7 | 8 | int main(void) { 9 | return target(); 10 | } -------------------------------------------------------------------------------- /tests/chapter_2/invalid_parse/extra_paren.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return (3)); 4 | } -------------------------------------------------------------------------------- /tests/chapter_2/invalid_parse/missing_const.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return ~; 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/invalid_parse/missing_semicolon.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return -5 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/invalid_parse/nested_missing_const.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return -~; 4 | } -------------------------------------------------------------------------------- /tests/chapter_2/invalid_parse/parenthesize_operand.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return (-)3; 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/invalid_parse/unclosed_paren.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return (1; 4 | } -------------------------------------------------------------------------------- /tests/chapter_2/invalid_parse/wrong_order.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 4-; 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/bitwise.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return ~12; 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/bitwise_zero.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return ~0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/neg.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return -5; 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/neg_zero.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return -0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/negate_int_max.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // 2147483647 is the largest possible value of type int 3 | return -2147483647; 4 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/nested_ops.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return ~-3; 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/nested_ops_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return -~0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/parens.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return (-2); 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/parens_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return ~(2); 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/parens_3.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return -(-4); 3 | } -------------------------------------------------------------------------------- /tests/chapter_2/valid/redundant_parens.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return -((((10)))); 4 | } -------------------------------------------------------------------------------- /tests/chapter_20/all_types/no_coalescing/dbl_trivially_colorable.c: -------------------------------------------------------------------------------- 1 | /* A simple test that we can allocate all the floating-point 2 | * pseudos in a program without register pressure. 3 | */ 4 | int target(double x, double y) { 5 | return 10 - (3.0 * y + x); 6 | } -------------------------------------------------------------------------------- /tests/chapter_3/invalid_parse/double_operation.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 * / 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/invalid_parse/extra_credit/bitwise_double_operator.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // we should lex this as two | operators, not a single || operator, 3 | // even after we add || in the next chapter 4 | return 1 | | 2; 5 | } -------------------------------------------------------------------------------- /tests/chapter_3/invalid_parse/imbalanced_paren.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 + (2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/invalid_parse/malformed_paren.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 2 (- 3); 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/invalid_parse/misplaced_semicolon.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 + (2;) 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/invalid_parse/missing_first_op.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return /3; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/invalid_parse/missing_open_paren.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 + 2); 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/invalid_parse/missing_second_op.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 + ; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/invalid_parse/no_semicolon.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 2*2 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/add.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 + 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/associativity.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 - 2 - 3; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/associativity_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 6 / 3 / 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/associativity_3.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return (3 / 2 * 4) + (5 - 4 + 3); 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/associativity_and_precedence.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 5 * 4 / 2 - 3 | 3 % (2 + 1); 4 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/div.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 4 / 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/div_neg.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return (-12) / 5; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/extra_credit/bitwise_and.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 3 & 5; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/extra_credit/bitwise_or.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 | 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/extra_credit/bitwise_shift_associativity.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 33 << 4 >> 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/extra_credit/bitwise_shift_associativity_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 33 >> 2 << 1; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/extra_credit/bitwise_shiftl.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 35 << 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/extra_credit/bitwise_shiftr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1000 >> 4; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/extra_credit/bitwise_xor.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 7 ^ 1; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/mod.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 4 % 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/mult.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 2 * 3; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/parens.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 2 * (3 + 4); 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/precedence.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 2 + 3 * 4; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/sub.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 - 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/sub_neg.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 2- -1; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/unop_add.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return ~2 + 3; 3 | } -------------------------------------------------------------------------------- /tests/chapter_3/valid/unop_parens.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return ~(1 + 1); 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/invalid_parse/missing_const.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | 10 <= !; 4 | } -------------------------------------------------------------------------------- /tests/chapter_4/invalid_parse/missing_first_op.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return <= 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/invalid_parse/missing_operand.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 < > 3; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/invalid_parse/missing_second_op.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 2 && ~; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/invalid_parse/missing_semicolon.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 || 2 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/invalid_parse/unary_missing_semicolon.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | return !10 4 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/and_false.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifdef __clang__ 3 | #pragma clang diagnostic ignored "-Wconstant-logical-operand" 4 | #endif 5 | #endif 6 | 7 | int main(void) { 8 | return (10 && 0) + (0 && 4) + (0 && 0); 9 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/and_short_circuit.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 0 && (1 / 0); 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/and_true.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifdef __clang__ 3 | #pragma clang diagnostic ignored "-Wconstant-logical-operand" 4 | #endif 5 | #endif 6 | 7 | int main(void) { 8 | return 1 && -1; 9 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/associativity.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifndef __clang__ 3 | #pragma GCC diagnostic ignored "-Wparentheses" 4 | #endif 5 | #endif 6 | 7 | int main(void) { 8 | return 5 >= 0 > 1 <= 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/compare_arithmetic_results.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return ~2 * -2 == 1 + 5; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/eq_false.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 == 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/eq_precedence.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifndef __clang__ 3 | #pragma GCC diagnostic ignored "-Wparentheses" 4 | #endif 5 | #endif 6 | 7 | int main(void) { 8 | return 3 == 1 != 2; 9 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/eq_true.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 == 1; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/extra_credit/bitwise_and_precedence.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wparentheses" 3 | #endif 4 | 5 | int main(void) { 6 | // & has lower precedence than == 7 | return 5 & 7 == 5; 8 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/extra_credit/bitwise_or_precedence.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wparentheses" 3 | #endif 4 | 5 | int main(void) { 6 | // | has lower precedence than != 7 | return 5 | 7 != 5; 8 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/extra_credit/bitwise_shift_precedence.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wparentheses" 3 | #endif 4 | 5 | int main(void) { 6 | return 20 >> 4 <= 3 << 1; 7 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/extra_credit/bitwise_xor_precedence.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wparentheses" 3 | #endif 4 | 5 | int main(void) { 6 | // ^ has lower precedence than < 7 | return 5 ^ 7 < 5; 8 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/ge_false.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 >= 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/ge_true.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return (1 >= 1) + (1 >= -4); 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/gt_false.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return (1 > 2) + (1 > 1); 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/gt_true.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 15 > 10; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/le_false.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 <= -1; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/le_true.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return (0 <= 2) + (0 <= 0); 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/lt_false.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 2 < 1; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/lt_true.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 < 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/ne_false.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 0 != 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/ne_true.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return -1 != -2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/nested_ops.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return !-3; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/not.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return !5; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/not_sum.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return !(4-4); 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/not_sum_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return !(3 - 44); 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/not_zero.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return !0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/or_false.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 0 || 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/or_short_circuit.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 || (1 / 0); 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/or_true.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifdef __clang__ 3 | #pragma clang diagnostic ignored "-Wconstant-logical-operand" 4 | #endif 5 | #endif 6 | 7 | int main(void) { 8 | return (4 || 0) + (0 || 3) + (5 || 5); 9 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/precedence_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return (1 || 0) && 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/precedence_3.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifndef __clang__ 3 | #pragma GCC diagnostic ignored "-Wparentheses" 4 | #endif 5 | #endif 6 | int main(void) { 7 | return 2 == 2 >= 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/precedence_4.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 2 == 2 || 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_4/valid/precedence_5.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifndef __clang__ 3 | #pragma GCC diagnostic ignored "-Wparentheses" 4 | #endif 5 | #endif 6 | int main(void) { 7 | return (0 == 0 && 3 == 2 + 1 > 1) + 1; 8 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/declare_keyword_as_var.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int return = 4; 3 | return return + 1; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/extra_credit/binary_decrement.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | return a -- 1; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/extra_credit/binary_increment.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | return a ++ 1; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/extra_credit/compound_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a += 0; 3 | return a; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/extra_credit/increment_declaration.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a++; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/invalid_specifier.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int foo bar = 3; 3 | return bar; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/invalid_type.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | ints a = 1; 3 | return a; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/invalid_variable_name.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int 10 = 0; 4 | return 10; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/malformed_less_equal.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | // make sure we lex < and = as two separate tokens 4 | // this really tests the lexing logic from previous chapter, 5 | // but the lexer didn't recognize = yet 6 | return 1 < = 2; 7 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/malformed_not_equal.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | // make sure we lex ! and = as two separate tokens 4 | // this really tests the lexing logic from previous chapter, 5 | // but the lexer didn't recognize = yet 6 | return 1 ! = 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/missing_semicolon.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 2 3 | a = a + 4; 4 | return a; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_parse/return_in_assignment.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int 10 = return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/declared_after_use.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | a = 1 + 2; 3 | int a; 4 | return a; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/extra_credit/compound_invalid_lvalue.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | -a += 1; 4 | return a; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/extra_credit/compound_invalid_lvalue_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 10; 3 | (a += 1) -= 2; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/extra_credit/postfix_incr_non_lvalue.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | (a = 4)++; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/extra_credit/prefix_decr_non_lvalue.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return --3; 3 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/extra_credit/prefix_incr_non_lvalue.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | ++(a+1); 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/extra_credit/undeclared_bitwise_op.c: -------------------------------------------------------------------------------- 1 | int main(void){ 2 | return a >> 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/extra_credit/undeclared_compound_assignment.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | a += 1; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/extra_credit/undeclared_compound_assignment_use.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int b = 10; 3 | b *= a; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/extra_credit/undeclared_postfix_decr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | a--; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/extra_credit/undeclared_prefix_incr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | a++; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/invalid_lvalue.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 2; 3 | a + 3 = 4; 4 | return a; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/invalid_lvalue_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 2; 3 | !a = 3; 4 | return a; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/mixed_precedence_assignment.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | int b = 2; 4 | a = 3 * b = a; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/redefine.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | int a = 2; 4 | return a; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/undeclared_var.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return a; 3 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/undeclared_var_and.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 0 && a; 3 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/undeclared_var_compare.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return a < 5; 3 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/undeclared_var_unary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return -a; 3 | } -------------------------------------------------------------------------------- /tests/chapter_5/invalid_semantics/use_then_redefine.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | return a; 4 | int a = 1; 5 | return a; 6 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/add_variables.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int first_variable = 1; 3 | int second_variable = 2; 4 | return first_variable + second_variable; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/allocate_temps_and_vars.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 2147483646; 3 | int b = 0; 4 | int c = a / 6 + !b; 5 | return c * 2 == a - 1431655762; 6 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/assign.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int var0; 3 | var0 = 2; 4 | return var0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/assign_val_in_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = a = 5; 3 | return a; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/assignment_in_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a; 3 | int b = a = 0; 4 | return b; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/assignment_lowest_precedence.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifdef __clang__ 3 | #pragma clang diagnostic ignored "-Wconstant-logical-operand" 4 | #endif 5 | #endif 6 | 7 | int main(void) { 8 | int a; 9 | a = 0 || 5; 10 | return a; 11 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/empty_function_body.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | 3 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/exp_then_declaration.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = -2593; 3 | a = a % 3; 4 | int b = -a; 5 | return b; 6 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/bitwise_in_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 15; 3 | int b = a ^ 5; // 10 4 | return 1 | b; // 11 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/bitwise_ops_vars.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wparentheses" 3 | #endif 4 | 5 | int main(void) { 6 | int a = 3; 7 | int b = 5; 8 | int c = 8; 9 | return a & b | c; 10 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/bitwise_shiftl_variable.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 3; 3 | return x << 3; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/bitwise_shiftr_assign.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int var_to_shift = 1234; 3 | int x = 0; 4 | x = var_to_shift >> 4; 5 | return x; 6 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_assignment_use_result.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 1; 3 | int y = x += 3; 4 | return (x == 4 && y == 4); 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_bitwise_and.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int to_and = 3; 3 | to_and &= 6; 4 | return to_and; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_bitwise_or.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int to_or = 1; 3 | to_or |= 30; 4 | return to_or; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_bitwise_shiftl.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int to_shiftl = 3; 3 | to_shiftl <<= 4; 4 | return to_shiftl; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_bitwise_shiftr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int to_shiftr = 382574; 3 | to_shiftr >>= 4; 4 | return to_shiftr; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_bitwise_xor.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int to_xor = 7; 3 | to_xor ^= 5; 4 | return to_xor; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_divide.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int to_divide = 8; 3 | to_divide /= 4; 4 | return to_divide; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_minus.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int to_subtract = 10; 3 | to_subtract -= 8; 4 | return to_subtract; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_mod.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int to_mod = 5; 3 | to_mod %= 3; 4 | return to_mod; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_multiply.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int to_multiply = 4; 3 | to_multiply *= 3; 4 | return to_multiply; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/compound_plus.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int to_add = 0; 3 | to_add += 4; 4 | return to_add; 5 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/incr_expression_statement.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | int b = 0; 4 | a++; 5 | ++a; 6 | ++a; 7 | b--; 8 | --b; 9 | return (a == 3 && b == -2); 10 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/incr_in_binary_expr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 2; 3 | int b = 3 + a++; 4 | int c = 4 + ++b; 5 | return (a == 3 && b == 6 && c == 10); 6 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/incr_parenthesized.c: -------------------------------------------------------------------------------- 1 | // Test that we can apply ++ and -- to parenthesized expressions 2 | int main(void) { 3 | int a = 1; 4 | int b = 2; 5 | int c = -++(a); 6 | int d = !(b)--; 7 | return (a == 2 && b == 1 && c == -2 && d == 0); 8 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/postfix_incr_and_decr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | int b = 2; 4 | int c = a++; 5 | int d = b--; 6 | return (a == 2 && b == 1 && c == 1 && d == 2); 7 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/postfix_precedence.c: -------------------------------------------------------------------------------- 1 | /* Postfix operators have higher precedence than prefix */ 2 | 3 | int main(void) { 4 | int a = 1; 5 | int b = !a++; 6 | return (a == 2 && b == 0); 7 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/extra_credit/prefix_incr_and_decr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | int b = 2; 4 | int c = ++a; 5 | int d = --b; 6 | return (a == 2 && b == 1 && c == 2 && d == 1); 7 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/kw_var_names.c: -------------------------------------------------------------------------------- 1 | // Test that we can properly lex identifiers that start with keywords 2 | 3 | int main(void) { 4 | int return_val = 3; 5 | int void2 = 2; 6 | return return_val + void2; 7 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/local_var_missing_return.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 3; 3 | a = a + 5; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/mixed_precedence_assignment.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | int b = 0; 4 | a = 3 * (b = a); 5 | return a + b; 6 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/non_short_circuit_or.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifndef __clang__ 3 | #pragma GCC diagnostic ignored "-Wunused-value" 4 | #endif 5 | #endif 6 | int main(void) { 7 | int a = 0; 8 | 0 || (a = 1); 9 | return a; 10 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/null_statement.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | ; 3 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/null_then_return.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | ; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/return_var.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 2; 3 | return a; 4 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/short_circuit_and_fail.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifndef __clang__ 3 | #pragma GCC diagnostic ignored "-Wunused-value" 4 | #endif 5 | #endif 6 | 7 | int main(void) { 8 | int a = 0; 9 | 0 && (a = 5); 10 | return a; 11 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/short_circuit_or.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifndef __clang__ 3 | #pragma GCC diagnostic ignored "-Wunused-value" 4 | #endif 5 | #endif 6 | int main(void) { 7 | int a = 0; 8 | 1 || (a = 1); 9 | return a; 10 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/unused_exp.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wunused-value" 3 | #endif 4 | int main(void) { 5 | 2 + 2; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_5/valid/use_assignment_result.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | 3 | int a = 1; 4 | int b = 2; 5 | return a = b = 4; 6 | } 7 | -------------------------------------------------------------------------------- /tests/chapter_5/valid/use_val_in_own_initializer.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0 && a; 3 | return a; 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_lex/extra_credit/bad_label.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | 0invalid_label: 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/declaration_as_statement.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | if (5) 3 | int i = 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/empty_if_body.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | if (0) else return 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/extra_credit/goto_without_label.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | goto; 3 | lbl: 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/extra_credit/kw_label.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return: return 0; 3 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/extra_credit/label_declaration.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // NOTE: this is a syntax error in C17 but valid in C23 3 | label: 4 | int a = 0; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/extra_credit/label_expression_clause.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | 1 && label: 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/extra_credit/label_outside_function.c: -------------------------------------------------------------------------------- 1 | label: 2 | int main(void) { 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/extra_credit/label_without_statement.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // NOTE: this is invalid in C17, but valid in C23 3 | foo: 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/extra_credit/parenthesized_label.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | goto(a); 3 | a: 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/if_assignment.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int flag = 0; 3 | int a = if (flag) 4 | 2; 5 | else 6 | 3; 7 | return a; 8 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/if_no_parens.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | if 0 return 1; 3 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/incomplete_ternary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 ? 2; 3 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/malformed_ternary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 ? 2 : 3 : 4; 3 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/malformed_ternary_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 1 ? 2 ? 3 : 4; 3 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/mismatched_nesting.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | if (1) 4 | return 1; 5 | else 6 | return 2; 7 | else 8 | return 3; 9 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_parse/wrong_ternary_delimiter.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | 3 | int x = 10; 4 | // make sure second delimiter in ternary expression is : 5 | return x ? 1 = 2; 6 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_semantics/extra_credit/duplicate_labels.c: -------------------------------------------------------------------------------- 1 | /* Label names must be unique within a function */ 2 | int main(void) { 3 | int x = 0; 4 | label: 5 | x = 1; 6 | label: 7 | return 2; 8 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_semantics/extra_credit/goto_missing_label.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | goto label; 3 | return 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_semantics/extra_credit/goto_variable.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a; 3 | goto a; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_semantics/extra_credit/undeclared_var_in_labeled_statement.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wunused-label" 3 | #endif 4 | 5 | int main(void) { 6 | lbl: 7 | return a; 8 | return 0; 9 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_semantics/extra_credit/use_label_as_variable.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 0; 3 | a: 4 | x = a; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_semantics/invalid_var_in_if.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | if (1) 3 | return c; 4 | int c = 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_semantics/ternary_assign.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 2; 3 | int b = 1; 4 | a > b ? a = 1 : a = 0; 5 | return a; 6 | } -------------------------------------------------------------------------------- /tests/chapter_6/invalid_semantics/undeclared_var_in_ternary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return a > 0 ? 1 : 2; 3 | int a = 5; 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/assign_ternary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | a = 1 ? 2 : 3; 4 | return a; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/binary_condition.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | if (1 + 2 == 3) 3 | return 5; 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/binary_false_condition.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | if (1 + 2 == 4) 3 | return 5; 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/else.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | if (a) 4 | return 1; 5 | else 6 | return 2; 7 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/bitwise_ternary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int result; 3 | 1 ^ 1 ? result = 4 : (result = 5); 4 | return result; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/compound_assign_ternary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 4; 3 | a *= 1 ? 2 : 3; 4 | return a; 5 | } 6 | -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/compound_if_expression.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | if (a += 1) 4 | return a; 5 | return 10; 6 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/goto_backwards.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | if (0) 3 | label: 4 | return 5; 5 | goto label; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/goto_label.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | goto label; 3 | return 0; 4 | label: 5 | return 1; 6 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/goto_label_and_var.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // it's valid to use the same identifier as a variable and label 3 | int ident = 5; 4 | goto ident; 5 | return 0; 6 | ident: 7 | return ident; 8 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/goto_label_main_2.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wunused-label" 3 | #endif 4 | int main(void) { 5 | goto _main; 6 | return 0; 7 | _main: 8 | return 1; 9 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/goto_nested_label.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wunused-label" 3 | #endif 4 | int main(void) { 5 | goto labelB; 6 | 7 | labelA: 8 | labelB: 9 | return 5; 10 | return 0; 11 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/label_token.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | goto _foo_1_; // a label may include numbers and underscores 3 | return 0; 4 | _foo_1_: 5 | return 1; 6 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/lh_compound_assignment.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 10; 3 | (x -= 1) ? (x /= 2) : 0; 4 | return x == 4; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/postfix_in_ternary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 10; 3 | x - 10 ? 0 : x--; 4 | return x; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/prefix_in_ternary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | return (++a ? ++a : 0); 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/extra_credit/unused_label.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wunused-label" 3 | #endif 4 | 5 | int main(void) { 6 | unused: 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/if_nested.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | int b = 0; 4 | if (a) 5 | b = 1; 6 | else if (b) 7 | b = 2; 8 | return b; 9 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/if_nested_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | int b = 1; 4 | if (a) 5 | b = 1; 6 | else if (~b) 7 | b = 2; 8 | return b; 9 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/if_nested_5.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | if (0) 4 | if (0) 5 | a = 3; 6 | else 7 | a = 4; 8 | else 9 | a = 1; 10 | 11 | return a; 12 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/if_not_taken.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | int b = 0; 4 | if (a) 5 | b = 1; 6 | return b; 7 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/if_null_body.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 0; 3 | if (0) 4 | ; 5 | else 6 | x = 1; 7 | return x; 8 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/if_taken.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | int b = 0; 4 | if (a) 5 | b = 1; 6 | return b; 7 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/lh_assignment.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 10; 3 | int y = 0; 4 | y = (x = 5) ? x : 2; 5 | return (x == 5 && y == 5); 6 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/multiple_if.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | int b = 0; 4 | 5 | if (a) 6 | a = 2; 7 | else 8 | a = 3; 9 | 10 | if (b) 11 | b = 4; 12 | else 13 | b = 5; 14 | 15 | return a + b; 16 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/nested_ternary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | int b = 2; 4 | int flag = 0; 5 | 6 | return a > b ? 5 : flag ? 6 : 7; 7 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/nested_ternary_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1 ? 2 ? 3 : 4 : 5; 3 | int b = 0 ? 2 ? 3 : 4 : 5; 4 | return a * b; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/rh_assignment.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int flag = 1; 3 | int a = 0; 4 | flag ? a = 1 : (a = 0); 5 | return a; 6 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/ternary.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | return a > -1 ? 4 : 5; 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/ternary_middle_assignment.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | a != 2 ? a = 2 : 0; 4 | return a; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/ternary_middle_binop.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1 ? 3 % 2 : 4; 3 | return a; 4 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/ternary_precedence.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 10; 3 | // test that || is higher precedence than ? 4 | return a || 0 ? 20 : 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/ternary_rh_binop.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #ifdef __clang__ 3 | #pragma clang diagnostic ignored "-Wconstant-logical-operand" 4 | #endif 5 | #endif 6 | int main(void) { 7 | return 0 ? 1 : 0 || 2; 8 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/ternary_short_circuit.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | int b = 0; 4 | a ? (b = 1) : (b = 2); 5 | return b; 6 | } -------------------------------------------------------------------------------- /tests/chapter_6/valid/ternary_short_circuit_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | int b = 0; 4 | a ? (b = 1) : (b = 2); 5 | return b; 6 | } -------------------------------------------------------------------------------- /tests/chapter_7/invalid_parse/extra_brace.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | if(0){ 3 | return 1; 4 | }} 5 | return 2; 6 | } -------------------------------------------------------------------------------- /tests/chapter_7/invalid_parse/missing_brace.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | if(0){ 3 | return 1; 4 | return 2; 5 | } -------------------------------------------------------------------------------- /tests/chapter_7/invalid_parse/missing_semicolon.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 4; 3 | { 4 | a = 5; 5 | return a 6 | } 7 | } -------------------------------------------------------------------------------- /tests/chapter_7/invalid_parse/ternary_blocks.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a; 3 | return 1 ? { a = 2 } : a = 4; 4 | } -------------------------------------------------------------------------------- /tests/chapter_7/invalid_semantics/double_define.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | { 3 | int a; 4 | int a; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tests/chapter_7/invalid_semantics/double_define_after_scope.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 3; 3 | { 4 | a = 5; 5 | } 6 | int a = 2; 7 | return a; 8 | } -------------------------------------------------------------------------------- /tests/chapter_7/invalid_semantics/extra_credit/different_labels_same_scope.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // different labels do not define different scopes 3 | label1:; 4 | int a = 10; 5 | label2:; 6 | int a = 11; 7 | return 1; 8 | } -------------------------------------------------------------------------------- /tests/chapter_7/invalid_semantics/extra_credit/goto_use_before_declare.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 0; 3 | if (x != 0) { 4 | return_y: 5 | return y; // not declared 6 | } 7 | int y = 4; 8 | goto return_y; 9 | } -------------------------------------------------------------------------------- /tests/chapter_7/invalid_semantics/out_of_scope.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | { 3 | int a = 2; 4 | } 5 | return a; 6 | } 7 | -------------------------------------------------------------------------------- /tests/chapter_7/invalid_semantics/use_before_declare.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a; 3 | { 4 | b = 10; 5 | } 6 | int b; 7 | return b; 8 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/assign_to_self.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wunused-variable" 3 | #endif 4 | int main(void) { 5 | int a = 3; 6 | { 7 | int a = a = 4; 8 | return a; 9 | } 10 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/assign_to_self_2.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 3; 3 | { 4 | int a = a = 4; 5 | } 6 | return a; 7 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/declaration_only.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wunused-variable" 3 | #endif 4 | int main(void) { 5 | int a; 6 | { 7 | int b = a = 1; 8 | } 9 | return a; 10 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/empty_blocks.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int ten = 10; 3 | {} 4 | int twenty = 10 * 2; 5 | {{}} 6 | return ten + twenty; 7 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/extra_credit/compound_subtract_in_block.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 5; 3 | if (a > 4) { 4 | a -= 4; 5 | int a = 5; 6 | if (a > 4) { 7 | a -= 4; 8 | } 9 | } 10 | return a; 11 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/extra_credit/goto_outer_scope.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 10; 3 | int b = 0; 4 | if (a) { 5 | int a = 1; 6 | b = a; 7 | goto end; 8 | } 9 | a = 9; 10 | end: 11 | return (a == 10 && b == 1); 12 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/hidden_then_visible.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 2; 3 | int b; 4 | { 5 | a = -4; 6 | int a = 7; 7 | b = a + 1; 8 | } 9 | return b == 8 && a == -4; 10 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/hidden_variable.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wunused-variable" 3 | #endif 4 | int main(void) { 5 | int a = 2; 6 | { 7 | int a = 1; 8 | return a; 9 | } 10 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/inner_uninitialized.c: -------------------------------------------------------------------------------- 1 | #ifdef SUPPRESS_WARNINGS 2 | #pragma GCC diagnostic ignored "-Wunused-variable" 3 | #endif 4 | int main(void) { 5 | int x = 4; 6 | { 7 | int x; 8 | } 9 | return x; 10 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/multiple_vars_same_name.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | { 4 | int b = 4; 5 | a = b; 6 | } 7 | { 8 | int b = 2; 9 | a = a - b; 10 | } 11 | return a; 12 | } -------------------------------------------------------------------------------- /tests/chapter_7/valid/use_in_inner_scope.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | int x; 4 | { 5 | x = 3; 6 | } 7 | { 8 | return x; 9 | } 10 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/decl_as_loop_body.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | while (1) 3 | int i = 0; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/do_extra_semicolon.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | do { 3 | int a; 4 | }; while(1); 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/do_missing_semicolon.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | do { 3 | 4; 4 | } while(1) 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/do_while_empty_parens.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | do 3 | 1; 4 | while (); 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/extra_credit/compound_assignment_invalid_decl.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | for (int i += 1; i < 10; i += 1) { 3 | return 0; 4 | } 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/extra_credit/label_in_loop_header.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | for (int i = 0; label: i < 10; i = i + 1) { 3 | ; 4 | } 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/extra_credit/switch_goto_case.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | goto 3; 3 | switch (3) { 4 | case 3: return 0; 5 | } 6 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/extra_credit/switch_missing_case_value.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | switch(0) { 3 | case: return 0; 4 | } 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/extra_credit/switch_missing_paren.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | switch 3 { 3 | case 3: return 0; 4 | } 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/extra_credit/switch_no_condition.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | switch { 3 | return 0; 4 | } 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/extra_for_header_clause.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | for (int i = 0; i < 10; i = i + 1; ) 3 | ; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/invalid_for_declaration.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | for (; int i = 0; i = i + 1) 3 | ; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/missing_for_header_clause.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | for (int i = 0;) 3 | ; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/paren_mismatch.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | for (int i = 2; )) 3 | int a = 0; 4 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/statement_in_condition.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | while(int a) { 3 | 2; 4 | } 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_parse/while_missing_paren.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | while 1 { 3 | return 0; 4 | } 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_semantics/break_not_in_loop.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | if (1) 3 | break; 4 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_semantics/continue_not_in_loop.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | { 3 | int a; 4 | continue; 5 | } 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_semantics/extra_credit/case_outside_switch.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | for (int i = 0; i < 10; i = i + 1) { 3 | // case statements can only appear inside switch statements 4 | case 0: return 1; 5 | } 6 | return 9; 7 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_semantics/extra_credit/default_outside_switch.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | { 3 | // case statements can only appear inside switch statements 4 | default: return 0; 5 | } 6 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_semantics/extra_credit/duplicate_case.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | switch(4) { 3 | case 5: return 0; 4 | case 4: return 1; 5 | case 5: return 0; // duplicate of previous case 5 6 | default: return 2; 7 | } 8 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_semantics/extra_credit/labeled_break_outside_loop.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | // make sure our usual analysis of break/continue labels also traverses labeled statements 3 | label: break; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_semantics/extra_credit/non_constant_case.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 3; 3 | switch(a + 1) { 4 | case 0: return 0; 5 | case a: return 1; // case statement values must be constant 6 | case 1: return 2; 7 | } 8 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_semantics/out_of_scope_do_loop.c: -------------------------------------------------------------------------------- 1 | /* Test case from Listing 8-3: 2 | * A variable declared in a loop body is out of scope in the controlling expression 3 | */ 4 | 5 | int main(void) { 6 | do { 7 | int a = a + 1; 8 | } while (a < 100); 9 | } -------------------------------------------------------------------------------- /tests/chapter_8/invalid_semantics/out_of_scope_loop_variable.c: -------------------------------------------------------------------------------- 1 | int main(void) 2 | { 3 | for (i = 0; i < 1; i = i + 1) 4 | { 5 | return 0; 6 | } 7 | } -------------------------------------------------------------------------------- /tests/chapter_8/valid/break.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 10; 3 | int b = 20; 4 | for (b = -20; b < 0; b = b + 1) { 5 | a = a - 1; 6 | if (a <= 0) 7 | break; 8 | } 9 | 10 | return a == 0 && b == -11; 11 | } 12 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/break_immediate.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 10; 3 | while ((a = 1)) 4 | break; 5 | return a; 6 | } 7 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/continue_empty_post.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int sum = 0; 3 | for (int i = 0; i < 10;) { 4 | i = i + 1; 5 | if (i % 2) 6 | continue; 7 | sum = sum + i; 8 | } 9 | return sum; 10 | } 11 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/do_while.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | do { 4 | a = a * 2; 5 | } while(a < 11); 6 | 7 | return a; 8 | } 9 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/do_while_break_immediate.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 10; 3 | do 4 | break; 5 | while ((a = 1)); 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/empty_expression.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | return 0;;; 3 | } 4 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/extra_credit/compound_assignment_controlling_expression.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int i = 100; 3 | int sum = 0; 4 | do sum += 2; 5 | while (i -= 1); 6 | return (i == 0 && sum == 200); 7 | } -------------------------------------------------------------------------------- /tests/chapter_8/valid/extra_credit/compound_assignment_for_loop.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int i = 1; 3 | for (i *= -1; i >= -100; i -=3) 4 | ; 5 | return (i == -103); 6 | } -------------------------------------------------------------------------------- /tests/chapter_8/valid/extra_credit/label_loop_body.c: -------------------------------------------------------------------------------- 1 | // a loop body may be a labeled statement 2 | int main(void) { 3 | int result = 0; 4 | goto label; 5 | while (0) 6 | label: { result = 1; } 7 | 8 | return result; 9 | } -------------------------------------------------------------------------------- /tests/chapter_8/valid/extra_credit/post_exp_incr.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int product = 1; 3 | for (int i = 0; i < 10; i++) { 4 | product = product + 2; 5 | } 6 | return product; 7 | } -------------------------------------------------------------------------------- /tests/chapter_8/valid/extra_credit/switch.c: -------------------------------------------------------------------------------- 1 | // very simple test of switch statements 2 | int main(void) { 3 | switch(3) { 4 | case 0: return 0; 5 | case 1: return 1; 6 | case 3: return 3; 7 | case 5: return 5; 8 | } 9 | } -------------------------------------------------------------------------------- /tests/chapter_8/valid/extra_credit/switch_default_not_last.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a; 3 | int b = a = 7; 4 | switch (a + b) { 5 | default: return 0; 6 | case 2: return 1; 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /tests/chapter_8/valid/extra_credit/switch_default_only.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | switch(a) default: return 1; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_8/valid/extra_credit/switch_single_case.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 1; 3 | // a switch statement body may be a single case 4 | switch(a) case 1: return 1; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_8/valid/for.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 12345; 3 | int i; 4 | 5 | for (i = 5; i >= 0; i = i - 1) 6 | a = a / 3; 7 | 8 | return a; 9 | } 10 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/for_absent_condition.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | for (int i = 400; ; i = i - 100) 3 | if (i == 100) 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/for_absent_post.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = -2147483647; 3 | for (; a % 5 != 0;) { 4 | a = a + 1; 5 | } 6 | return a % 5 || a > 0; 7 | } 8 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/for_decl.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | 4 | for (int i = -100; i <= 0; i = i + 1) 5 | a = a + 1; 6 | return a; 7 | } 8 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/for_shadow.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int shadow = 1; 3 | int acc = 0; 4 | for (int shadow = 0; shadow < 10; shadow = shadow + 1) { 5 | acc = acc + shadow; 6 | } 7 | return acc == 45 && shadow == 1; 8 | } 9 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/null_for_header.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | for (; ; ) { 4 | a = a + 1; 5 | if (a > 3) 6 | break; 7 | } 8 | 9 | return a; 10 | } 11 | -------------------------------------------------------------------------------- /tests/chapter_8/valid/while.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int a = 0; 3 | 4 | while (a < 5) 5 | a = a + 2; 6 | 7 | return a; 8 | } 9 | -------------------------------------------------------------------------------- /tests/chapter_9/invalid_declarations/extra_credit/call_label_as_function.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x = 1; 3 | a: 4 | x = x + 1; 5 | a(); // can't call a label like a function 6 | return x; 7 | 8 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_declarations/extra_credit/decrement_fun_call.c: -------------------------------------------------------------------------------- 1 | int x(void); 2 | 3 | int main(void) { 4 | // a function call is not an lvalue, so we can't decrement it 5 | x()--; 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_declarations/extra_credit/increment_fun_call.c: -------------------------------------------------------------------------------- 1 | int x(void); 2 | 3 | int main(void) { 4 | // a function call is not an lvalue, so we can't increment it 5 | ++x(); 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_declarations/nested_function_definition.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* Nested function definitions are not permitted */ 3 | int foo(void) { 4 | return 1; 5 | } 6 | return foo(); 7 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_declarations/params_with_same_name.c: -------------------------------------------------------------------------------- 1 | /* It's illegal for multiple parameters to a function to have the same name */ 2 | int foo(int a, int a) { 3 | return a; 4 | } 5 | 6 | int main(void) { 7 | return foo(1, 2); 8 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_declarations/undeclared_fun.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* You must declare a function before using it */ 3 | return foo(3); 4 | } 5 | 6 | int foo(int a) { 7 | return 1; 8 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_labels/extra_credit/goto_cross_function.c: -------------------------------------------------------------------------------- 1 | int foo(void) { 2 | label: 3 | return 0; 4 | } 5 | 6 | int main(void) { 7 | /* You can't goto a label in another function */ 8 | goto label; 9 | return 1; 10 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_labels/extra_credit/goto_function.c: -------------------------------------------------------------------------------- 1 | int foo(void) { 2 | return 3; 3 | } 4 | 5 | int main(void) { 6 | /* You can't use a function name as a goto label */ 7 | goto foo; 8 | return 3; 9 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_parse/fun_decl_for_loop.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | /* Function declarations aren't permitted in for loop headers. */ 3 | for (int f(void); ; ) { 4 | return 0; 5 | } 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_parse/function_call_declaration.c: -------------------------------------------------------------------------------- 1 | int foo(int a) { 2 | return 0; 3 | } 4 | 5 | int main(void) { 6 | /* A function argument must be an expression, not a declaration */ 7 | return foo(int a); 8 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_parse/trailing_comma.c: -------------------------------------------------------------------------------- 1 | int foo(int a, int b, int c) { 2 | return a + b + c; 3 | } 4 | 5 | int main(void) { 6 | /* Trailing commas aren't permitted in argument lists */ 7 | return foo(1, 2, 3,); 8 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_parse/trailing_comma_decl.c: -------------------------------------------------------------------------------- 1 | /* Trailing commas aren't permitted in parameter lists */ 2 | int foo(int a,) { 3 | return a + 1; 4 | } 5 | 6 | int main(void) { 7 | return foo(4); 8 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_parse/unclosed_paren_decl.c: -------------------------------------------------------------------------------- 1 | int foo(int a, int b { 2 | return 0; 3 | } 4 | 5 | int main(void) { 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_parse/var_init_in_param_list.c: -------------------------------------------------------------------------------- 1 | /* Variable initializers aren't permitted in parameter lists */ 2 | int bad_params(int a = 3) { 3 | return 1; 4 | } 5 | 6 | int main(void) { 7 | return 0; 8 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/assign_fun_to_variable.c: -------------------------------------------------------------------------------- 1 | int x(void); 2 | int main(void) { 3 | int a = 10; 4 | a = x; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/assign_value_to_function.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int x(void); 3 | x = 3; 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/call_variable_as_function.c: -------------------------------------------------------------------------------- 1 | int x(void); 2 | 3 | int main(void) { 4 | int x = 0; 5 | /* x isn't a function, so you can't call it */ 6 | return x(); 7 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/divide_by_function.c: -------------------------------------------------------------------------------- 1 | int x(void); 2 | 3 | int main(void) { 4 | int a = 10 / x; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/extra_credit/bitwise_op_function.c: -------------------------------------------------------------------------------- 1 | int x(void); 2 | 3 | int main(void) { 4 | x >> 2; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/extra_credit/compound_assign_function_lhs.c: -------------------------------------------------------------------------------- 1 | int x(void); 2 | 3 | int main(void) { 4 | x += 3; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/extra_credit/compound_assign_function_rhs.c: -------------------------------------------------------------------------------- 1 | int x(void); 2 | 3 | int main(void) { 4 | int a = 3; 5 | a += x; 6 | return 0; 7 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/extra_credit/postfix_incr_fun_name.c: -------------------------------------------------------------------------------- 1 | int x(void); 2 | 3 | int main(void) { 4 | x++; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/extra_credit/prefix_decr_fun_name.c: -------------------------------------------------------------------------------- 1 | int x(void); 2 | 3 | int main(void){ 4 | --x; 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/extra_credit/switch_on_function.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int f(void); 3 | switch (f) 4 | return 0; 5 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/multiple_function_definitions.c: -------------------------------------------------------------------------------- 1 | /* Function 'foo' is defined twice */ 2 | int foo(void){ 3 | return 3; 4 | } 5 | 6 | int main(void) { 7 | return foo(); 8 | } 9 | 10 | int foo(void){ 11 | return 4; 12 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/too_few_args.c: -------------------------------------------------------------------------------- 1 | int foo(int a, int b) { 2 | return a + 1; 3 | } 4 | 5 | int main(void) { 6 | /* foo is called with too many arguments */ 7 | return foo(1); 8 | } -------------------------------------------------------------------------------- /tests/chapter_9/invalid_types/too_many_args.c: -------------------------------------------------------------------------------- 1 | int foo(int a) { 2 | return a + 1; 3 | } 4 | 5 | int main(void) { 6 | /* foo is called with too many arguments */ 7 | return foo(1, 2); 8 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/arguments_in_registers/parameter_shadows_function.c: -------------------------------------------------------------------------------- 1 | int a(void) { 2 | return 1; 3 | } 4 | 5 | int b(int a) { 6 | return a; 7 | } 8 | 9 | int main(void) { 10 | return a() + b(2); 11 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/arguments_in_registers/parameter_shadows_own_function.c: -------------------------------------------------------------------------------- 1 | int a(int a) { 2 | return a * 2; 3 | } 4 | 5 | int main(void) { 6 | return a(1); 7 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/arguments_in_registers/single_arg.c: -------------------------------------------------------------------------------- 1 | int twice(int x){ 2 | return 2 * x; 3 | } 4 | 5 | int main(void) { 6 | return twice(3); 7 | } 8 | -------------------------------------------------------------------------------- /tests/chapter_9/valid/extra_credit/compound_assign_function_result.c: -------------------------------------------------------------------------------- 1 | int foo(void) { 2 | return 2; 3 | } 4 | 5 | int main(void) { 6 | int x = 3; 7 | x -= foo(); 8 | return x; 9 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/libraries/addition.c: -------------------------------------------------------------------------------- 1 | int add(int x, int y) { 2 | return x + y; 3 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/libraries/addition_client.c: -------------------------------------------------------------------------------- 1 | int add(int x, int y); 2 | 3 | int main(void) { 4 | return add(1, 2); 5 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/libraries/no_function_calls/division_client.c: -------------------------------------------------------------------------------- 1 | int f(int a, int b, int c, int d); 2 | 3 | int main(void) { 4 | return f(10, 2, 100, 4); 5 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/libraries/no_function_calls/local_stack_variables_client.c: -------------------------------------------------------------------------------- 1 | int f(int reg1, int reg2, int reg3, int reg4, int reg5, int reg6, 2 | int stack1, int stack2, int stack3); 3 | 4 | int main(void) { 5 | return f(1, 2, 3, 4, 5, 6, -1, -2, -3); 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/libraries/system_call.c: -------------------------------------------------------------------------------- 1 | int putchar(int c); 2 | 3 | int incr_and_print(int b) { 4 | return putchar(b + 2); 5 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/libraries/system_call_client.c: -------------------------------------------------------------------------------- 1 | int incr_and_print(int c); 2 | 3 | int main(void) { 4 | incr_and_print(70); 5 | return 0; 6 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/no_arguments/forward_decl.c: -------------------------------------------------------------------------------- 1 | int foo(void); 2 | 3 | int main(void) { 4 | return foo(); 5 | } 6 | 7 | int foo(void) { 8 | return 3; 9 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/no_arguments/multiple_declarations.c: -------------------------------------------------------------------------------- 1 | int main(void) { 2 | int f(void); 3 | int f(void); 4 | return f(); 5 | } 6 | 7 | int f(void) { 8 | return 3; 9 | } -------------------------------------------------------------------------------- /tests/chapter_9/valid/no_arguments/precedence.c: -------------------------------------------------------------------------------- 1 | int three(void) { 2 | return 3; 3 | } 4 | 5 | int main(void) { 6 | /* The function call operator () is higher precedence 7 | * than unary prefix operators 8 | */ 9 | return !three(); 10 | } --------------------------------------------------------------------------------