diff --git a/expected_results.json b/expected_results.json index f81229fa..f78f8986 100644 --- a/expected_results.json +++ b/expected_results.json @@ -1 +1 @@ -{"chapter_6/valid/rh_assignment.c": {"return_code": 1}, "chapter_6/valid/if_nested_2.c": {"return_code": 2}, "chapter_6/valid/if_nested_3.c": {"return_code": 3}, "chapter_6/valid/nested_ternary.c": {"return_code": 7}, "chapter_6/valid/binary_false_condition.c": {"return_code": 0}, "chapter_6/valid/else.c": {"return_code": 2}, "chapter_6/valid/nested_ternary_2.c": {"return_code": 15}, "chapter_6/valid/ternary_short_circuit.c": {"return_code": 1}, "chapter_6/valid/multiple_if.c": {"return_code": 8}, "chapter_6/valid/if_null_body.c": {"return_code": 1}, "chapter_6/valid/ternary_rh_binop.c": {"return_code": 1}, "chapter_6/valid/ternary_middle_assignment.c": {"return_code": 2}, "chapter_6/valid/if_nested_4.c": {"return_code": 4}, "chapter_6/valid/ternary_middle_binop.c": {"return_code": 1}, "chapter_6/valid/if_taken.c": {"return_code": 1}, "chapter_6/valid/if_not_taken.c": {"return_code": 0}, "chapter_6/valid/if_nested_5.c": {"return_code": 1}, "chapter_6/valid/assign_ternary.c": {"return_code": 2}, "chapter_6/valid/ternary.c": {"return_code": 4}, "chapter_6/valid/if_nested.c": {"return_code": 1}, "chapter_6/valid/ternary_short_circuit_2.c": {"return_code": 2}, "chapter_6/valid/binary_condition.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_and_var.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_main_2.c": {"return_code": 0}, "chapter_6/valid/extra_credit/bitwise_ternary.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_main.c": {"return_code": 0}, "chapter_6/valid/extra_credit/goto_nested_label.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_backwards.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label.c": {"return_code": 1}, "chapter_6/valid/extra_credit/compound_if_expression.c": {"return_code": 1}, "chapter_6/valid/extra_credit/goto_after_declaration.c": {"return_code": 1}, "chapter_8/valid/for.c": {"return_code": 16}, "chapter_8/valid/continue.c": {"return_code": 1}, "chapter_8/valid/multi_continue_same_loop.c": {"return_code": 1}, "chapter_8/valid/for_absent_post.c": {"return_code": 0}, "chapter_8/valid/null_for_header.c": {"return_code": 4}, "chapter_8/valid/nested_loop.c": {"return_code": 1}, "chapter_8/valid/nested_break.c": {"return_code": 250}, "chapter_8/valid/do_while.c": {"return_code": 16}, "chapter_8/valid/for_absent_condition.c": {"return_code": 0}, "chapter_8/valid/do_while_break_immediate.c": {"return_code": 10}, "chapter_8/valid/continue_empty_post.c": {"return_code": 30}, "chapter_8/valid/nested_continue.c": {"return_code": 24}, "chapter_8/valid/break.c": {"return_code": 1}, "chapter_8/valid/for_nested_shadow.c": {"return_code": 1}, "chapter_8/valid/empty_expression.c": {"return_code": 0}, "chapter_8/valid/multi_break.c": {"return_code": 1}, "chapter_8/valid/for_decl.c": {"return_code": 101}, "chapter_8/valid/for_shadow.c": {"return_code": 1}, "chapter_8/valid/break_immediate.c": {"return_code": 1}, "chapter_8/valid/while.c": {"return_code": 6}, "chapter_8/valid/empty_loop_body.c": {"return_code": 252}, "chapter_8/valid/extra_credit/switch_fallthrough.c": {"return_code": 4}, "chapter_8/valid/extra_credit/compound_assignment_for_loop.c": {"return_code": 10}, "chapter_8/valid/extra_credit/switch_break.c": {"return_code": 5}, "chapter_8/valid/extra_credit/switch_default.c": {"return_code": 22}, "chapter_8/valid/extra_credit/switch_default_fallthrough.c": {"return_code": 0}, "chapter_8/valid/extra_credit/switch_with_loop.c": {"return_code": 123}, "chapter_8/valid/extra_credit/switch_assign_in_body.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_in_loop.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_no_case.c": {"return_code": 4}, "chapter_8/valid/extra_credit/switch_nested_case.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_nested_not_taken.c": {"return_code": 2}, "chapter_8/valid/extra_credit/switch_decl.c": {"return_code": 7}, "chapter_8/valid/extra_credit/switch_with_continue.c": {"return_code": 5}, "chapter_8/valid/extra_credit/switch_empty.c": {"return_code": 10}, "chapter_8/valid/extra_credit/goto_loop_body.c": {"return_code": 1}, "chapter_8/valid/extra_credit/goto_bypass_condition.c": {"return_code": 10}, "chapter_8/valid/extra_credit/switch_nested_switch.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_block.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_default_not_last.c": {"return_code": 0}, "chapter_8/valid/extra_credit/switch_assign_in_condition.c": {"return_code": 2}, "chapter_8/valid/extra_credit/switch.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_goto_mid_case.c": {"return_code": 1}, "chapter_14/valid/libraries/static_pointer.c": {"return_code": 0}, "chapter_14/valid/libraries/global_pointer.c": {"return_code": 1}, "chapter_14/valid/function_calls/address_of_argument.c": {"return_code": 0}, "chapter_14/valid/function_calls/update_value_through_pointer_parameter.c": {"return_code": 0}, "chapter_14/valid/function_calls/return_pointer.c": {"return_code": 0}, "chapter_14/valid/extra_credit/incr_through_pointer.c": {"return_code": 11}, "chapter_14/valid/extra_credit/compound_assign_through_pointer.c": {"return_code": 1}, "chapter_14/valid/declarators/declare_pointer_in_for_loop.c": {"return_code": 5}, "chapter_14/valid/declarators/abstract_declarators.c": {"return_code": 0}, "chapter_14/valid/declarators/declarators.c": {"return_code": 0}, "chapter_14/valid/dereference/static_var_indirection.c": {"return_code": 0}, "chapter_14/valid/dereference/multilevel_indirection.c": {"return_code": 0}, "chapter_14/valid/dereference/read_through_pointers.c": {"return_code": 0}, "chapter_14/valid/dereference/update_through_pointers.c": {"return_code": 0}, "chapter_14/valid/dereference/address_of_dereference.c": {"return_code": 0}, "chapter_14/valid/dereference/simple.c": {"return_code": 3}, "chapter_14/valid/dereference/dereference_expression_result.c": {"return_code": 0}, "chapter_14/valid/casts/cast_between_pointer_types.c": {"return_code": 0}, "chapter_14/valid/casts/pointer_int_casts.c": {"return_code": 0}, "chapter_14/valid/casts/null_pointer_conversion.c": {"return_code": 0}, "chapter_14/valid/comparisons/compare_pointers.c": {"return_code": 0}, "chapter_14/valid/comparisons/pointers_as_conditions.c": {"return_code": 0}, "chapter_14/valid/comparisons/compare_to_null.c": {"return_code": 0}, "chapter_10/valid/static_then_extern.c": {"return_code": 3}, "chapter_10/valid/push_arg_on_page_boundary.c": {"return_code": 1}, "chapter_10/valid/static_local_multiple_scopes.c": {"return_code": 0, "stdout": "Aa\nBb\nCc\nDd\nEe\nFf\nGg\nHh\nIi\nJj\nKk\nLl\nMm\nNn\nOo\nPp\nQq\nRr\nSs\nTt\nUu\nVv\nWw\nXx\nYy\nZz\n"}, "chapter_10/valid/tentative_definition.c": {"return_code": 5}, "chapter_10/valid/static_variables_in_expressions.c": {"return_code": 0}, "chapter_10/valid/static_recursive_call.c": {"return_code": 0, "stdout": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, "chapter_10/valid/shadow_static_local_var.c": {"return_code": 0}, "chapter_10/valid/multiple_static_local.c": {"return_code": 29}, "chapter_10/valid/multiple_static_file_scope_vars.c": {"return_code": 4}, "chapter_10/valid/static_local_uninitialized.c": {"return_code": 4}, "chapter_10/valid/type_before_storage_class.c": {"return_code": 7}, "chapter_10/valid/extern_block_scope_variable.c": {"return_code": 3}, "chapter_10/valid/distinct_local_and_extern.c": {"return_code": 7}, "chapter_10/valid/libraries/internal_hides_external_linkage.c": {"return_code": 0}, "chapter_10/valid/libraries/external_tentative_var.c": {"return_code": 0}, "chapter_10/valid/libraries/external_linkage_function.c": {"return_code": 0}, "chapter_10/valid/libraries/external_variable.c": {"return_code": 0}, "chapter_10/valid/libraries/internal_linkage_var.c": {"return_code": 0}, "chapter_10/valid/libraries/external_var_scoping.c": {"return_code": 0}, "chapter_10/valid/libraries/internal_linkage_function.c": {"return_code": 0}, "chapter_10/valid/extra_credit/goto_skip_static_initializer.c": {"return_code": 10}, "chapter_2/valid/neg.c": {"return_code": 251}, "chapter_2/valid/negate_int_max.c": {"return_code": 1}, "chapter_2/valid/redundant_parens.c": {"return_code": 246}, "chapter_2/valid/neg_zero.c": {"return_code": 0}, "chapter_2/valid/bitwise_int_min.c": {"return_code": 254}, "chapter_2/valid/bitwise_zero.c": {"return_code": 255}, "chapter_2/valid/parens_3.c": {"return_code": 4}, "chapter_2/valid/parens_2.c": {"return_code": 253}, "chapter_2/valid/bitwise.c": {"return_code": 243}, "chapter_2/valid/nested_ops_2.c": {"return_code": 1}, "chapter_2/valid/nested_ops.c": {"return_code": 2}, "chapter_2/valid/parens.c": {"return_code": 254}, "chapter_1/valid/return_0.c": {"return_code": 0}, "chapter_1/valid/newlines.c": {"return_code": 0}, "chapter_1/valid/return_2.c": {"return_code": 2}, "chapter_1/valid/multi_digit.c": {"return_code": 100}, "chapter_1/valid/tabs.c": {"return_code": 0}, "chapter_1/valid/spaces.c": {"return_code": 0}, "chapter_1/valid/no_newlines.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/logical.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/static_initialized_double.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/comparisons.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/simple.c": {"return_code": 1}, "chapter_13/valid/floating_expressions/loop_controlling_expression.c": {"return_code": 100}, "chapter_13/valid/libraries/double_parameters.c": {"return_code": 0}, "chapter_13/valid/libraries/use_arg_after_fun_call.c": {"return_code": 4}, "chapter_13/valid/libraries/double_and_int_params_recursive.c": {"return_code": 0}, "chapter_13/valid/libraries/extern_double.c": {"return_code": 1}, "chapter_13/valid/libraries/double_params_and_result.c": {"return_code": 1}, "chapter_13/valid/explicit_casts/cvttsd2i_rewrite.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/double_to_signed.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/unsigned_to_double.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/signed_to_double.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/double_to_unsigned.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/convert_for_assignment.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/static_initializers.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/complex_arithmetic_common_type.c": {"return_code": 1}, "chapter_13/valid/constants/round_constants.c": {"return_code": 0}, "chapter_13/valid/constants/constant_doubles.c": {"return_code": 0}, "chapter_13/valid/special_values/subnormal_not_zero.c": {"return_code": 0}, "chapter_13/valid/special_values/negative_zero.c": {"return_code": 0}, "chapter_13/valid/special_values/infinity.c": {"return_code": 0}, "chapter_13/valid/function_calls/double_parameters.c": {"return_code": 0}, "chapter_13/valid/function_calls/double_and_int_parameters.c": {"return_code": 0}, "chapter_13/valid/function_calls/standard_library_call.c": {"return_code": 0}, "chapter_13/valid/function_calls/use_arg_after_fun_call.c": {"return_code": 4}, "chapter_13/valid/function_calls/return_double.c": {"return_code": 1}, "chapter_13/valid/function_calls/double_and_int_params_recursive.c": {"return_code": 0}, "chapter_13/valid/extra_credit/compound_assign.c": {"return_code": 1}, "chapter_13/valid/extra_credit/nan.c": {"return_code": 0}, "chapter_13/valid/extra_credit/compound_assign_implicit_cast.c": {"return_code": 1}, "chapter_18/valid/params_and_returns/pass_and_return_struct.c": {"return_code": 11}, "chapter_18/valid/params_and_returns/temporary_lifetime.c": {"return_code": 1}, "chapter_18/valid/params_and_returns/return_struct_on_page_boundary.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_incomplete_type.c": {"return_code": 1}, "chapter_18/valid/params_and_returns/cast_struct_to_void.c": {"return_code": 2}, "chapter_18/valid/params_and_returns/return_struct.c": {"return_code": 11}, "chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/pass_wonky_struct.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/missing_retval.c": {"return_code": 1}, "chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/pass_pointer_to_struct.c": {"return_code": 112}, "chapter_18/valid/no_structure_parameters/typecheck/deref_incomplete_var.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/typecheck/conditional_struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/typecheck/block_scope_forward_decl.c": {"return_code": 3}, "chapter_18/valid/no_structure_parameters/typecheck/define_then_declare.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/typecheck/incomplete_var_completed.c": {"return_code": 100}, "chapter_18/valid/no_structure_parameters/typecheck/file_scope_forward_decl.c": {"return_code": 2}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/copy_struct_with_array_2.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/load_test.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/copy_struct_into_member.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/copy_struct.c": {"return_code": 7}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/array_of_structs_padding.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/array_of_structs.c": {"return_code": 19}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/copy_from_offset_test.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/copy_struct_with_array.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/global_struct.c": {"return_code": 7}, "chapter_18/valid/no_structure_parameters/member_access_tests/deref_arrow.c": {"return_code": 3}, "chapter_18/valid/no_structure_parameters/member_access_tests/linked_list.c": {"return_code": 30}, "chapter_18/valid/no_structure_parameters/member_access_tests/assign_to_struct.c": {"return_code": 10}, "chapter_18/valid/no_structure_parameters/member_access_tests/pointer_to_struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/get_array_through_pointer.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/nested_struct.c": {"return_code": 16}, "chapter_18/valid/no_structure_parameters/member_access_tests/addr_of_arrow.c": {"return_code": 10}, "chapter_18/valid/no_structure_parameters/member_access_tests/copy_from_pointer.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/static_struct.c": {"return_code": 19}, "chapter_18/valid/no_structure_parameters/member_access_tests/global_nested_struct.c": {"return_code": 8}, "chapter_18/valid/no_structure_parameters/member_access_tests/non_static_struct.c": {"return_code": 9}, "chapter_18/valid/no_structure_parameters/member_access_tests/get_member_addresses.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/member_access_tests/nested_address_calculations.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/member_access_tests/aggregate_through_arrow.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/member_access_tests/copy_to_pointer.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/assign_to_struct_pointer.c": {"return_code": 10}, "chapter_18/valid/no_structure_parameters/libraries/global_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/incomplete_var.c": {"return_code": 5}, "chapter_18/valid/no_structure_parameters/libraries/nested_pointer_access.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/sizeof/sizeof_wonky.c": {"return_code": 19}, "chapter_18/valid/no_structure_parameters/sizeof/sizeof_struct.c": {"return_code": 8}, "chapter_18/valid/no_structure_parameters/sizeof/sizeof_padded.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/parse_and_lex/postfix_precedence.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/parse_and_lex/space_around_struct_member.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/parse_and_lex/struct_member_looks_like_const.c": {"return_code": 3}, "chapter_18/valid/no_structure_parameters/initializers/nested_struct_init.c": {"return_code": 157}, "chapter_18/valid/no_structure_parameters/initializers/mixed_initialization.c": {"return_code": 7}, "chapter_18/valid/no_structure_parameters/initializers/load_addr_in_init.c": {"return_code": 6}, "chapter_18/valid/no_structure_parameters/initializers/partial_struct_init.c": {"return_code": 26}, "chapter_18/valid/no_structure_parameters/initializers/string_in_global_struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/initializers/string_in_struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/scoping_tests/scoped_struct.c": {"return_code": 2}, "chapter_18/valid/no_structure_parameters/scoping_tests/resolve_tag_for_loop_decl.c": {"return_code": 10}, "chapter_18/valid/no_structure_parameters/scoping_tests/same_tag_name.c": {"return_code": 8}, "chapter_18/valid/no_structure_parameters/scoping_tests/resolve_tags_derived_types.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/scoping_tests/different_namespaces_same_ids.c": {"return_code": 10}, "chapter_18/valid/no_structure_parameters/scoping_tests/resolve_tag_sizeof.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/scoping_tests/same_tag_name_simple.c": {"return_code": 4}, "chapter_18/valid/no_structure_parameters/scoping_tests/declare_struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/scoping_tests/shared_struct_and_var_names.c": {"return_code": 1}, "chapter_18/valid/parameters/pass_struct_as_arg.c": {"return_code": 1}, "chapter_18/valid/parameters/pass_args_on_page_boundary.c": {"return_code": 15}, "chapter_18/valid/parameters/incomplete_param_type.c": {"return_code": 3}, "chapter_18/valid/parameters/pass_struct_and_other_args.c": {"return_code": 1}, "chapter_18/valid/parameters/libraries/param_calling_conventions.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/preserve_stack.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/struct_sizes.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/pass_struct.c": {"return_code": 2}, "chapter_18/valid/parameters/libraries/array_of_structs.c": {"return_code": 0}, "chapter_15/valid/initialization/automatic.c": {"return_code": 0}, "chapter_15/valid/initialization/static.c": {"return_code": 0}, "chapter_15/valid/initialization/trailing_comma_initializer.c": {"return_code": 3}, "chapter_15/valid/initialization/automatic_nested.c": {"return_code": 0}, "chapter_15/valid/initialization/static_nested.c": {"return_code": 0}, "chapter_15/valid/libraries/set_array_val.c": {"return_code": 0}, "chapter_15/valid/libraries/return_pointer_to_array.c": {"return_code": 0}, "chapter_15/valid/libraries/global_array.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_nested.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_pointer.c": {"return_code": 0}, "chapter_15/valid/subscripting/array_of_pointers_to_arrays.c": {"return_code": 0}, "chapter_15/valid/subscripting/simple_subscripts.c": {"return_code": 0}, "chapter_15/valid/subscripting/simple.c": {"return_code": 3}, "chapter_15/valid/subscripting/complex_operands.c": {"return_code": 0}, "chapter_15/valid/subscripting/addition_subscript_equivalence.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_precedence.c": {"return_code": 1}, "chapter_15/valid/allocation/test_alignment.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/pointer_add.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/add_dereference_and_assign.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/pointer_diff.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/compare.c": {"return_code": 0}, "chapter_15/valid/extra_credit/incr_ptr.c": {"return_code": 1}, "chapter_15/valid/declarators/big_array.c": {"return_code": 0}, "chapter_15/valid/declarators/equivalent_declarators.c": {"return_code": 0}, "chapter_15/valid/declarators/return_nested_array.c": {"return_code": 0}, "chapter_15/valid/declarators/array_as_argument.c": {"return_code": 0}, "chapter_15/valid/declarators/for_loop_array.c": {"return_code": 0}, "chapter_15/valid/casts/multi_dim_casts.c": {"return_code": 0}, "chapter_15/valid/casts/implicit_and_explicit_conversions.c": {"return_code": 0}, "chapter_15/valid/casts/cast_array_of_pointers.c": {"return_code": 1}, "chapter_17/valid/void/cast_to_void.c": {"return_code": 12}, "chapter_17/valid/void/void_function.c": {"return_code": 0}, "chapter_17/valid/void/void_for_loop.c": {"return_code": 0, "stdout": "ZYXWVUTSRQPONMLKJIHGFEDCBAABCDEFGHIJKLMNOPQRSTUVWXYZZYXWVUTSRQPONMLKJIHGFEDCBA"}, "chapter_17/valid/void/ternary.c": {"return_code": 0}, "chapter_17/valid/libraries/pass_alloced_memory.c": {"return_code": 0}, "chapter_17/valid/libraries/test_for_memory_leaks.c": {"return_code": 0}, "chapter_17/valid/libraries/sizeof_extern.c": {"return_code": 1}, "chapter_17/valid/sizeof/sizeof_basic_types.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_consts.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_expressions.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_array.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_derived_types.c": {"return_code": 0}, "chapter_17/valid/sizeof/simple.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_result_is_ulong.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_not_evaluated.c": {"return_code": 4}, "chapter_17/valid/void_pointer/array_of_pointers_to_void.c": {"return_code": 0}, "chapter_17/valid/void_pointer/conversion_by_assignment.c": {"return_code": 0}, "chapter_17/valid/void_pointer/explicit_cast.c": {"return_code": 0}, "chapter_17/valid/void_pointer/simple.c": {"return_code": 100}, "chapter_17/valid/void_pointer/memory_management_functions.c": {"return_code": 0}, "chapter_17/valid/void_pointer/common_pointer_type.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/addr_of_string.c": {"return_code": 0, "stdout": "Sample\tstring!\n\n"}, "chapter_16/valid/strings_as_lvalues/standard_library_calls.c": {"return_code": 0, "stdout": "Hello, World!\n"}, "chapter_16/valid/strings_as_lvalues/array_of_strings.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/cast_string_pointer.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/empty_string.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/pointer_operations.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/simple.c": {"return_code": 108}, "chapter_16/valid/strings_as_lvalues/adjacent_strings.c": {"return_code": 0, "stdout": "Hello, World\n"}, "chapter_16/valid/strings_as_lvalues/string_special_characters.c": {"return_code": 0, "stdout": "Hello\"world\nHello\\World\nLine\nbreak!\nTesting, 123.\n^@1 _\\]\n"}, "chapter_16/valid/strings_as_lvalues/strings_in_function_calls.c": {"return_code": 0}, "chapter_16/valid/libraries/return_char.c": {"return_code": 0}, "chapter_16/valid/libraries/char_arguments.c": {"return_code": 0}, "chapter_16/valid/libraries/global_char.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/array_init_special_chars.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/terminating_null_bytes.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/simple.c": {"return_code": 99}, "chapter_16/valid/strings_as_initializers/partial_initialize_via_string.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/adjacent_strings_in_initializer.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/transfer_by_eightbyte.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/literals_and_compound_initializers.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/write_to_array.c": {"return_code": 0, "stdout": "abc\nabx\nHello\nWorld\nJello\n"}, "chapter_16/valid/strings_as_initializers/test_alignment.c": {"return_code": 0}, "chapter_16/valid/char_constants/return_char_constant.c": {"return_code": 99}, "chapter_16/valid/char_constants/escape_sequences.c": {"return_code": 0}, "chapter_16/valid/char_constants/control_characters.c": {"return_code": 0}, "chapter_16/valid/char_constants/char_constant_operations.c": {"return_code": 0}, "chapter_16/valid/chars/partial_initialization.c": {"return_code": 0}, "chapter_16/valid/chars/convert_by_assignment.c": {"return_code": 0}, "chapter_16/valid/chars/type_specifiers.c": {"return_code": 0}, "chapter_16/valid/chars/push_arg_on_page_boundary.c": {"return_code": 1}, "chapter_16/valid/chars/integer_promotion.c": {"return_code": 0}, "chapter_16/valid/chars/chained_casts.c": {"return_code": 0}, "chapter_16/valid/chars/return_char.c": {"return_code": 0}, "chapter_16/valid/chars/char_arguments.c": {"return_code": 0}, "chapter_16/valid/chars/char_expressions.c": {"return_code": 0}, "chapter_16/valid/chars/access_through_char_pointer.c": {"return_code": 0}, "chapter_16/valid/chars/common_type.c": {"return_code": 0}, "chapter_16/valid/chars/static_initializers.c": {"return_code": 0}, "chapter_16/valid/chars/explicit_casts.c": {"return_code": 0}, "chapter_9/valid/arguments_in_registers/parameter_shadows_own_function.c": {"return_code": 2}, "chapter_9/valid/arguments_in_registers/expression_args.c": {"return_code": 2}, "chapter_9/valid/arguments_in_registers/single_arg.c": {"return_code": 6}, "chapter_9/valid/arguments_in_registers/hello_world.c": {"return_code": 0, "stdout": "Hello, World!\n"}, "chapter_9/valid/arguments_in_registers/parameter_shadows_function.c": {"return_code": 3}, "chapter_9/valid/arguments_in_registers/parameters_are_preserved.c": {"return_code": 1}, "chapter_9/valid/arguments_in_registers/forward_decl_multi_arg.c": {"return_code": 1}, "chapter_9/valid/arguments_in_registers/fibonacci.c": {"return_code": 8}, "chapter_9/valid/arguments_in_registers/param_shadows_local_var.c": {"return_code": 20}, "chapter_9/valid/no_arguments/function_shadows_variable.c": {"return_code": 11}, "chapter_9/valid/no_arguments/use_function_in_expression.c": {"return_code": 21}, "chapter_9/valid/no_arguments/no_return_value.c": {"return_code": 3}, "chapter_9/valid/no_arguments/multiple_declarations.c": {"return_code": 3}, "chapter_9/valid/no_arguments/precedence.c": {"return_code": 0}, "chapter_9/valid/no_arguments/forward_decl.c": {"return_code": 3}, "chapter_9/valid/no_arguments/variable_shadows_function.c": {"return_code": 7}, "chapter_9/valid/libraries/system_call.c": {"return_code": 0, "stdout": "H"}, "chapter_9/valid/libraries/many_args.c": {"return_code": 115}, "chapter_9/valid/libraries/addition.c": {"return_code": 3}, "chapter_9/valid/libraries/no_function_calls/division.c": {"return_code": 1}, "chapter_9/valid/libraries/no_function_calls/local_stack_variables.c": {"return_code": 100}, "chapter_9/valid/extra_credit/compound_assign_function_result.c": {"return_code": 1}, "chapter_9/valid/extra_credit/goto_label_multiple_functions.c": {"return_code": 5}, "chapter_9/valid/extra_credit/goto_shared_name.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/call_putchar.c": {"return_code": 8, "stdout": "A"}, "chapter_9/valid/stack_arguments/lots_of_arguments.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/stack_alignment.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/test_for_memory_leaks.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/logical.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/arithmetic_wraparound.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/comparisons.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/simple.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/static_variables.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/locals.c": {"return_code": 0}, "chapter_12/valid/libraries/unsigned_args.c": {"return_code": 0}, "chapter_12/valid/libraries/unsigned_global_var.c": {"return_code": 1}, "chapter_12/valid/explicit_casts/same_size_conversion.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/extension.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/round_trip_casts.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/chained_casts.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/truncate.c": {"return_code": 0}, "chapter_12/valid/type_specifiers/signed_type_specifiers.c": {"return_code": 0}, "chapter_12/valid/type_specifiers/unsigned_type_specifiers.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/convert_by_assignment.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/promote_constants.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/static_initializers.c": {"return_code": 0}, "chapter_12/valid/extra_credit/switch_uint.c": {"return_code": 0}, "chapter_12/valid/extra_credit/compound_assign_uint.c": {"return_code": 1}, "chapter_12/valid/extra_credit/bitwise_unsigned_shift.c": {"return_code": 1}, "chapter_12/valid/extra_credit/bitwise_unsigned_ops.c": {"return_code": 1}, "chapter_5/valid/null_then_return.c": {"return_code": 0}, "chapter_5/valid/empty_function_body.c": {"return_code": 0}, "chapter_5/valid/short_circuit_or.c": {"return_code": 0}, "chapter_5/valid/assignment_in_initializer.c": {"return_code": 0}, "chapter_5/valid/non_short_circuit_or.c": {"return_code": 1}, "chapter_5/valid/null_statement.c": {"return_code": 0}, "chapter_5/valid/short_circuit_and_fail.c": {"return_code": 0}, "chapter_5/valid/local_var_missing_return.c": {"return_code": 0}, "chapter_5/valid/exp_then_declaration.c": {"return_code": 1}, "chapter_5/valid/add_variables.c": {"return_code": 3}, "chapter_5/valid/assign_val_in_initializer.c": {"return_code": 5}, "chapter_5/valid/assignment_lowest_precedence.c": {"return_code": 1}, "chapter_5/valid/allocate_temps_and_vars.c": {"return_code": 1}, "chapter_5/valid/use_assignment_result.c": {"return_code": 4}, "chapter_5/valid/use_val_in_own_initializer.c": {"return_code": 0}, "chapter_5/valid/unused_exp.c": {"return_code": 0}, "chapter_5/valid/return_var.c": {"return_code": 2}, "chapter_5/valid/mixed_precedence_assignment.c": {"return_code": 4}, "chapter_5/valid/assign.c": {"return_code": 2}, "chapter_5/valid/extra_credit/bitwise_shiftr_assign.c": {"return_code": 77}, "chapter_5/valid/extra_credit/bitwise_shiftl_variable.c": {"return_code": 24}, "chapter_5/valid/extra_credit/compound_bitwise_and.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_minus.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_multiply.c": {"return_code": 12}, "chapter_5/valid/extra_credit/compound_bitwise_xor.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_bitwise_or.c": {"return_code": 31}, "chapter_5/valid/extra_credit/compound_assignment_chained.c": {"return_code": 4}, "chapter_5/valid/extra_credit/compound_divide.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_bitwise_shiftr.c": {"return_code": 102}, "chapter_5/valid/extra_credit/compound_assignment_use_result.c": {"return_code": 8}, "chapter_5/valid/extra_credit/compound_bitwise_shiftl.c": {"return_code": 48}, "chapter_5/valid/extra_credit/compound_plus.c": {"return_code": 4}, "chapter_5/valid/extra_credit/compound_mod.c": {"return_code": 2}, "chapter_5/valid/extra_credit/bitwise_and_vars.c": {"return_code": 1}, "chapter_7/valid/declaration_only.c": {"return_code": 1}, "chapter_7/valid/assign_to_self_2.c": {"return_code": 3}, "chapter_7/valid/hidden_then_visible.c": {"return_code": 1}, "chapter_7/valid/hidden_variable.c": {"return_code": 1}, "chapter_7/valid/assign_to_self.c": {"return_code": 4}, "chapter_7/valid/inner_uninitialized.c": {"return_code": 4}, "chapter_7/valid/multiple_vars_same_name.c": {"return_code": 2}, "chapter_7/valid/use_in_inner_scope.c": {"return_code": 3}, "chapter_7/valid/empty_blocks.c": {"return_code": 30}, "chapter_7/valid/nested_if.c": {"return_code": 1}, "chapter_7/valid/similar_var_names.c": {"return_code": 28}, "chapter_7/valid/extra_credit/goto_before_declaration.c": {"return_code": 0}, "chapter_7/valid/extra_credit/compound_subtract_in_block.c": {"return_code": 1}, "chapter_7/valid/extra_credit/goto_inner_scope.c": {"return_code": 1}, "chapter_4/valid/le_true.c": {"return_code": 2}, "chapter_4/valid/ne_true.c": {"return_code": 1}, "chapter_4/valid/ge_false.c": {"return_code": 0}, "chapter_4/valid/not_zero.c": {"return_code": 1}, "chapter_4/valid/precedence_2.c": {"return_code": 0}, "chapter_4/valid/ge_true.c": {"return_code": 2}, "chapter_4/valid/eq_precedence.c": {"return_code": 1}, "chapter_4/valid/eq_false.c": {"return_code": 0}, "chapter_4/valid/or_short_circuit.c": {"return_code": 1}, "chapter_4/valid/not_sum.c": {"return_code": 1}, "chapter_4/valid/precedence_4.c": {"return_code": 1}, "chapter_4/valid/and_short_circuit.c": {"return_code": 0}, "chapter_4/valid/precedence_3.c": {"return_code": 0}, "chapter_4/valid/compare_arithmetic_results.c": {"return_code": 1}, "chapter_4/valid/and_false.c": {"return_code": 0}, "chapter_4/valid/precedence_5.c": {"return_code": 1}, "chapter_4/valid/associativity.c": {"return_code": 1}, "chapter_4/valid/gt_true.c": {"return_code": 1}, "chapter_4/valid/lt_false.c": {"return_code": 0}, "chapter_4/valid/or_true.c": {"return_code": 3}, "chapter_4/valid/or_false.c": {"return_code": 0}, "chapter_4/valid/eq_true.c": {"return_code": 1}, "chapter_4/valid/ne_false.c": {"return_code": 0}, "chapter_4/valid/multi_short_circuit.c": {"return_code": 0}, "chapter_4/valid/gt_false.c": {"return_code": 0}, "chapter_4/valid/operate_on_booleans.c": {"return_code": 0}, "chapter_4/valid/not.c": {"return_code": 0}, "chapter_4/valid/le_false.c": {"return_code": 0}, "chapter_4/valid/nested_ops.c": {"return_code": 0}, "chapter_4/valid/precedence.c": {"return_code": 1}, "chapter_4/valid/not_sum_2.c": {"return_code": 0}, "chapter_4/valid/and_true.c": {"return_code": 1}, "chapter_4/valid/lt_true.c": {"return_code": 1}, "chapter_4/valid/extra_credit/bitwise_precedence.c": {"return_code": 1}, "chapter_3/valid/mod.c": {"return_code": 0}, "chapter_3/valid/unop_add.c": {"return_code": 0}, "chapter_3/valid/associativity_3.c": {"return_code": 8}, "chapter_3/valid/mult.c": {"return_code": 6}, "chapter_3/valid/sub.c": {"return_code": 255}, "chapter_3/valid/div_neg.c": {"return_code": 254}, "chapter_3/valid/unop_parens.c": {"return_code": 253}, "chapter_3/valid/add.c": {"return_code": 3}, "chapter_3/valid/associativity.c": {"return_code": 252}, "chapter_3/valid/associativity_2.c": {"return_code": 1}, "chapter_3/valid/div.c": {"return_code": 2}, "chapter_3/valid/sub_neg.c": {"return_code": 3}, "chapter_3/valid/associativity_and_precedence.c": {"return_code": 10}, "chapter_3/valid/parens.c": {"return_code": 14}, "chapter_3/valid/precedence.c": {"return_code": 14}, "chapter_3/valid/extra_credit/bitwise_shiftr.c": {"return_code": 62}, "chapter_3/valid/extra_credit/bitwise_and.c": {"return_code": 1}, "chapter_3/valid/extra_credit/bitwise_shiftl.c": {"return_code": 140}, "chapter_3/valid/extra_credit/bitwise_or.c": {"return_code": 3}, "chapter_3/valid/extra_credit/bitwise_shift_precedence.c": {"return_code": 0}, "chapter_3/valid/extra_credit/bitwise_xor.c": {"return_code": 6}, "chapter_3/valid/extra_credit/bitwise_shift_associativity_2.c": {"return_code": 16}, "chapter_3/valid/extra_credit/bitwise_shift_associativity.c": {"return_code": 66}, "chapter_3/valid/extra_credit/bitwise_precedence.c": {"return_code": 21}, "chapter_11/valid/long_expressions/long_args.c": {"return_code": 0}, "chapter_11/valid/long_expressions/logical.c": {"return_code": 0}, "chapter_11/valid/long_expressions/type_specifiers.c": {"return_code": 0}, "chapter_11/valid/long_expressions/multi_op.c": {"return_code": 1}, "chapter_11/valid/long_expressions/large_constants.c": {"return_code": 0}, "chapter_11/valid/long_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_11/valid/long_expressions/return_long.c": {"return_code": 1}, "chapter_11/valid/long_expressions/comparisons.c": {"return_code": 0}, "chapter_11/valid/long_expressions/simple.c": {"return_code": 1}, "chapter_11/valid/long_expressions/static_long.c": {"return_code": 1}, "chapter_11/valid/long_expressions/long_and_int_locals.c": {"return_code": 0}, "chapter_11/valid/long_expressions/assign.c": {"return_code": 1}, "chapter_11/valid/libraries/long_args.c": {"return_code": 0}, "chapter_11/valid/libraries/maintain_stack_alignment.c": {"return_code": 12}, "chapter_11/valid/libraries/return_long.c": {"return_code": 1}, "chapter_11/valid/libraries/long_global_var.c": {"return_code": 0}, "chapter_11/valid/explicit_casts/truncate.c": {"return_code": 0}, "chapter_11/valid/explicit_casts/sign_extend.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_by_assignment.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/long_constants.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_function_arguments.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_static_initializer.c": {"return_code": 0}, "chapter_11/valid/extra_credit/bitwise_long_op.c": {"return_code": 1}, "chapter_11/valid/extra_credit/compound_assign_to_int.c": {"return_code": 1}, "chapter_11/valid/extra_credit/compound_assign_to_long.c": {"return_code": 1}, "chapter_11/valid/extra_credit/switch_int.c": {"return_code": 1}, "chapter_11/valid/extra_credit/switch_long.c": {"return_code": 1}, "chapter_19/whole_pipeline/all_types/alias_analysis_change.c": {"return_code": 0}, "chapter_19/whole_pipeline/int_only/dead_condition.c": {"return_code": 10}, "chapter_19/whole_pipeline/int_only/elim_and_copy_prop.c": {"return_code": 10}, "chapter_19/whole_pipeline/int_only/remainder_test.c": {"return_code": 1}, "chapter_19/dead_store_elimination/all_types/aliased_dead_at_exit.c": {"return_code": 1}, "chapter_19/dead_store_elimination/all_types/getaddr_doesnt_gen.c": {"return_code": 0}, "chapter_19/dead_store_elimination/all_types/copy_to_dead_struct.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/dont_elim/copytooffset_doesnt_kill.c": {"return_code": 101}, "chapter_19/dead_store_elimination/all_types/dont_elim/store_generates_dst.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/dont_elim/load_generates_pointer.c": {"return_code": 10}, "chapter_19/dead_store_elimination/all_types/dont_elim/load_through_pointer.c": {"return_code": 10}, "chapter_19/dead_store_elimination/all_types/dont_elim/pass_pointer_to_fun.c": {"return_code": 5}, "chapter_19/dead_store_elimination/all_types/dont_elim/never_kill_store.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/dont_elim/copyfromoffset_gen.c": {"return_code": 3}, "chapter_19/dead_store_elimination/int_only/fig_19_12.c": {"return_code": 9}, "chapter_19/dead_store_elimination/int_only/use_and_kill.c": {"return_code": 5}, "chapter_19/dead_store_elimination/int_only/dead_store_static_var.c": {"return_code": 1}, "chapter_19/dead_store_elimination/int_only/loop_dead_store.c": {"return_code": 51}, "chapter_19/dead_store_elimination/int_only/simple.c": {"return_code": 3}, "chapter_19/dead_store_elimination/int_only/elim_second_copy.c": {"return_code": 10}, "chapter_19/dead_store_elimination/int_only/dont_elim/static_vars_at_exit.c": {"return_code": 1}, "chapter_19/dead_store_elimination/int_only/dont_elim/used_one_path.c": {"return_code": 40}, "chapter_19/dead_store_elimination/int_only/dont_elim/dont_remove_funcall.c": {"return_code": 0, "stdout": "C"}, "chapter_19/dead_store_elimination/int_only/dont_elim/add_all_to_worklist.c": {"return_code": 0, "stdout": "L"}, "chapter_19/dead_store_elimination/int_only/dont_elim/loop.c": {"return_code": 54}, "chapter_19/dead_store_elimination/int_only/dont_elim/static_vars_fun.c": {"return_code": 5}, "chapter_19/unreachable_code_elimination/remove_useless_starting_label.c": {"return_code": 99}, "chapter_19/unreachable_code_elimination/dead_for_loop.c": {"return_code": 10}, "chapter_19/unreachable_code_elimination/remove_jnz.c": {"return_code": 1}, "chapter_19/unreachable_code_elimination/dead_branch_inside_loop.c": {"return_code": 19}, "chapter_19/unreachable_code_elimination/empty.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/constant_if_else.c": {"return_code": 45}, "chapter_19/unreachable_code_elimination/loop_in_dead_branch.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/dead_after_return.c": {"return_code": 2}, "chapter_19/unreachable_code_elimination/empty_block.c": {"return_code": 1}, "chapter_19/unreachable_code_elimination/dead_after_if_else.c": {"return_code": 1}, "chapter_19/unreachable_code_elimination/dont_elim/keep_final_jump.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_cast_to_double.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_ulong.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_double.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_long.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_uint.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_cast_from_double.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/truncate.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/zero_and_sign_extend.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_divide_by_zero.c": {"return_code": 1}, "chapter_19/constant_folding/int_only/fold_unary.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_dead_branch.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_conditional_jump.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_comparisons.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_arithmetic.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_overflow.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/pointer_arithmetic.c": {"return_code": 2}, "chapter_19/copy_propagation/all_types/store_doesnt_kill.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/unsigned_wraparound.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/propagate_doubles.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/unsigned_compare.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/signed_unsigned_conversion.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/char_type_conversion.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/not_char.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/char_round_trip_2.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/alias_analysis.c": {"return_code": 24}, "chapter_19/copy_propagation/all_types/const_fold_sign_extend.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/copy_struct.c": {"return_code": 6}, "chapter_19/copy_propagation/all_types/propagate_null_pointer.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/char_round_trip.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/const_fold_type_conversions.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/const_fold_sign_extend_2.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/dont_propagate/static_are_aliased.c": {"return_code": 8}, "chapter_19/copy_propagation/all_types/dont_propagate/store_kills_aliased.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/copy_to_offset.c": {"return_code": 3}, "chapter_19/copy_propagation/all_types/dont_propagate/dont_propagate_addr_of.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/type_conversion.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/dont_propagate/zero_neg_zero_different.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/dont_propagate/funcall_kills_aliased.c": {"return_code": 2}, "chapter_19/copy_propagation/int_only/propagate_fun_args.c": {"return_code": 220}, "chapter_19/copy_propagation/int_only/killed_then_redefined.c": {"return_code": 2}, "chapter_19/copy_propagation/int_only/redundant_copies_2.c": {"return_code": 10}, "chapter_19/copy_propagation/int_only/multi_path_no_kill.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/redundant_copies.c": {"return_code": 10}, "chapter_19/copy_propagation/int_only/fig_19_8.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/kill_and_add_copies.c": {"return_code": 14}, "chapter_19/copy_propagation/int_only/multi_instance_same_copy.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/init_all_copies.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/complex_const_fold.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/copy_prop_const_fold.c": {"return_code": 6}, "chapter_19/copy_propagation/int_only/prop_static_var.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/propagate_var.c": {"return_code": 6}, "chapter_19/copy_propagation/int_only/multi_path.c": {"return_code": 6}, "chapter_19/copy_propagation/int_only/loop.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/dont_propagate/source_killed_on_one_path.c": {"return_code": 8}, "chapter_19/copy_propagation/int_only/dont_propagate/one_reaching_copy.c": {"return_code": 3}, "chapter_19/copy_propagation/int_only/dont_propagate/listing_20_15.c": {"return_code": 101}, "chapter_19/copy_propagation/int_only/dont_propagate/dest_killed.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/no_copies_reach_entry.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/add_all_blocks_to_worklist.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/multi_values.c": {"return_code": 7}, "chapter_19/copy_propagation/int_only/dont_propagate/static_dst_killed.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/static_src_killed.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/dont_propagate/source_killed.c": {"return_code": 10}, "chapter_20/all_types/no_coalescing/mixed_ints.c": {"return_code": 9}, "chapter_20/all_types/no_coalescing/dbl_trivially_colorable.c": {"return_code": 3}, "chapter_20/all_types/no_coalescing/spill_movz_dst.c": {"return_code": 29}, "chapter_20/all_types/no_coalescing/push_xmm.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/dbl_fun_call.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/stack_alignment.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/track_dbl_arg_registers.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/fourteen_pseudos_interfere.c": {"return_code": 0}, "chapter_20/all_types/no_coalescing/div_interference.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/test_spilling_dbls.c": {"return_code": 3}, "chapter_20/all_types/no_coalescing/store_pointer_in_register.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/same_instr_interference.c": {"return_code": 6}, "chapter_20/int_only/no_coalescing/spills_rewrites_compare.c": {"return_code": 3}, "chapter_20/int_only/no_coalescing/copy_and_separate_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/spills_and_rewrites.c": {"return_code": 23}, "chapter_20/int_only/no_coalescing/cmp_liveness.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/rewrite_large_multiply.c": {"return_code": 58}, "chapter_20/int_only/no_coalescing/spill_callee_saved.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/test_spill_metric.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/unary_interference.c": {"return_code": 10}, "chapter_20/int_only/no_coalescing/optimistic_coloring.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/track_arg_registers.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/many_pseudos_fewer_conflicts.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/same_instr_no_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/copy_no_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/force_spill.c": {"return_code": 9}, "chapter_20/int_only/no_coalescing/callee_saved_stack_alignment.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/idiv_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/preserve_across_fun_call.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/use_all_hardregs.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/test_spill_metric_2.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/loop.c": {"return_code": 6}, "chapter_20/int_only/no_coalescing/trivially_colorable.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/cdq_interference.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/cdq_generates_ax.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/callee_saved_live_at_exit.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/coalesce_prevents_spill.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/george_coalesce.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/unary_generates_dst.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/briggs_coalesce.c": {"return_code": 2}, "chapter_20/int_only/with_coalescing/bin_generates_dst.c": {"return_code": 187}, "chapter_20/int_only/with_coalescing/briggs_coalesce_tmps.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/cmp_generates_operands.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/funcall_generates_args.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/eax_live_at_exit.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/semantic_analysis/resolve_tags.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/semantic_analysis/namespaces.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/semantic_analysis/incomplete_structs.c": {"return_code": 0, "stdout": "I'm a struct!\n"}, "chapter_18/valid/no_structure_parameters/semantic_analysis/cast_struct_to_void.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/param_struct_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/return_struct_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/opaque_struct.c": {"return_code": 0, "stdout": "new struct\nstatic struct\nglobal struct\n"}, "chapter_18/valid/no_structure_parameters/libraries/initializers/auto_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/static_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/nested_static_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/nested_auto_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/smoke_tests/static_vs_auto.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/smoke_tests/simple.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/member_offsets.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/sizeof_exps.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/sizeof_type.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/arrow.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/linked_list.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/static_structs.c": {"return_code": 0, "stdout": "zero\nmn\nop\nwx\nyz\nBCD\nCDE\nDEF\nEFG\nbcd\ncde\n"}, "chapter_18/valid/no_structure_parameters/scalar_member_access/nested_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/dot.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/parse_and_lex/trailing_comma.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/load_test.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c": {"return_code": 7}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_with_arrow_operator.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_with_dot_operator.c": {"return_code": 0}} \ No newline at end of file +{"chapter_6/valid/rh_assignment.c": {"return_code": 1}, "chapter_6/valid/if_nested_2.c": {"return_code": 2}, "chapter_6/valid/if_nested_3.c": {"return_code": 3}, "chapter_6/valid/nested_ternary.c": {"return_code": 7}, "chapter_6/valid/binary_false_condition.c": {"return_code": 0}, "chapter_6/valid/else.c": {"return_code": 2}, "chapter_6/valid/nested_ternary_2.c": {"return_code": 15}, "chapter_6/valid/ternary_short_circuit.c": {"return_code": 1}, "chapter_6/valid/multiple_if.c": {"return_code": 8}, "chapter_6/valid/if_null_body.c": {"return_code": 1}, "chapter_6/valid/ternary_rh_binop.c": {"return_code": 1}, "chapter_6/valid/ternary_middle_assignment.c": {"return_code": 2}, "chapter_6/valid/if_nested_4.c": {"return_code": 4}, "chapter_6/valid/ternary_middle_binop.c": {"return_code": 1}, "chapter_6/valid/if_taken.c": {"return_code": 1}, "chapter_6/valid/if_not_taken.c": {"return_code": 0}, "chapter_6/valid/if_nested_5.c": {"return_code": 1}, "chapter_6/valid/assign_ternary.c": {"return_code": 2}, "chapter_6/valid/ternary.c": {"return_code": 4}, "chapter_6/valid/if_nested.c": {"return_code": 1}, "chapter_6/valid/ternary_short_circuit_2.c": {"return_code": 2}, "chapter_6/valid/binary_condition.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_and_var.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_main_2.c": {"return_code": 0}, "chapter_6/valid/extra_credit/bitwise_ternary.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label_main.c": {"return_code": 0}, "chapter_6/valid/extra_credit/goto_nested_label.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_backwards.c": {"return_code": 5}, "chapter_6/valid/extra_credit/goto_label.c": {"return_code": 1}, "chapter_6/valid/extra_credit/compound_if_expression.c": {"return_code": 1}, "chapter_6/valid/extra_credit/goto_after_declaration.c": {"return_code": 1}, "chapter_8/valid/for.c": {"return_code": 16}, "chapter_8/valid/continue.c": {"return_code": 1}, "chapter_8/valid/multi_continue_same_loop.c": {"return_code": 1}, "chapter_8/valid/for_absent_post.c": {"return_code": 0}, "chapter_8/valid/null_for_header.c": {"return_code": 4}, "chapter_8/valid/nested_loop.c": {"return_code": 1}, "chapter_8/valid/nested_break.c": {"return_code": 250}, "chapter_8/valid/do_while.c": {"return_code": 16}, "chapter_8/valid/for_absent_condition.c": {"return_code": 0}, "chapter_8/valid/do_while_break_immediate.c": {"return_code": 10}, "chapter_8/valid/continue_empty_post.c": {"return_code": 30}, "chapter_8/valid/nested_continue.c": {"return_code": 24}, "chapter_8/valid/break.c": {"return_code": 1}, "chapter_8/valid/for_nested_shadow.c": {"return_code": 1}, "chapter_8/valid/empty_expression.c": {"return_code": 0}, "chapter_8/valid/multi_break.c": {"return_code": 1}, "chapter_8/valid/for_decl.c": {"return_code": 101}, "chapter_8/valid/for_shadow.c": {"return_code": 1}, "chapter_8/valid/break_immediate.c": {"return_code": 1}, "chapter_8/valid/while.c": {"return_code": 6}, "chapter_8/valid/empty_loop_body.c": {"return_code": 252}, "chapter_8/valid/extra_credit/switch_fallthrough.c": {"return_code": 4}, "chapter_8/valid/extra_credit/compound_assignment_for_loop.c": {"return_code": 10}, "chapter_8/valid/extra_credit/switch_break.c": {"return_code": 5}, "chapter_8/valid/extra_credit/switch_default.c": {"return_code": 22}, "chapter_8/valid/extra_credit/switch_default_fallthrough.c": {"return_code": 0}, "chapter_8/valid/extra_credit/switch_with_loop.c": {"return_code": 123}, "chapter_8/valid/extra_credit/switch_assign_in_body.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_in_loop.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_no_case.c": {"return_code": 4}, "chapter_8/valid/extra_credit/switch_nested_case.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_nested_not_taken.c": {"return_code": 2}, "chapter_8/valid/extra_credit/switch_decl.c": {"return_code": 7}, "chapter_8/valid/extra_credit/switch_with_continue.c": {"return_code": 5}, "chapter_8/valid/extra_credit/switch_empty.c": {"return_code": 10}, "chapter_8/valid/extra_credit/goto_loop_body.c": {"return_code": 1}, "chapter_8/valid/extra_credit/goto_bypass_condition.c": {"return_code": 10}, "chapter_8/valid/extra_credit/switch_nested_switch.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_block.c": {"return_code": 1}, "chapter_8/valid/extra_credit/switch_default_not_last.c": {"return_code": 0}, "chapter_8/valid/extra_credit/switch_assign_in_condition.c": {"return_code": 2}, "chapter_8/valid/extra_credit/switch.c": {"return_code": 3}, "chapter_8/valid/extra_credit/switch_goto_mid_case.c": {"return_code": 1}, "chapter_14/valid/libraries/static_pointer.c": {"return_code": 0}, "chapter_14/valid/libraries/global_pointer.c": {"return_code": 1}, "chapter_14/valid/function_calls/address_of_argument.c": {"return_code": 0}, "chapter_14/valid/function_calls/update_value_through_pointer_parameter.c": {"return_code": 0}, "chapter_14/valid/function_calls/return_pointer.c": {"return_code": 0}, "chapter_14/valid/extra_credit/incr_through_pointer.c": {"return_code": 11}, "chapter_14/valid/extra_credit/compound_assign_through_pointer.c": {"return_code": 1}, "chapter_14/valid/declarators/declare_pointer_in_for_loop.c": {"return_code": 5}, "chapter_14/valid/declarators/abstract_declarators.c": {"return_code": 0}, "chapter_14/valid/declarators/declarators.c": {"return_code": 0}, "chapter_14/valid/dereference/static_var_indirection.c": {"return_code": 0}, "chapter_14/valid/dereference/multilevel_indirection.c": {"return_code": 0}, "chapter_14/valid/dereference/read_through_pointers.c": {"return_code": 0}, "chapter_14/valid/dereference/update_through_pointers.c": {"return_code": 0}, "chapter_14/valid/dereference/address_of_dereference.c": {"return_code": 0}, "chapter_14/valid/dereference/simple.c": {"return_code": 3}, "chapter_14/valid/dereference/dereference_expression_result.c": {"return_code": 0}, "chapter_14/valid/casts/cast_between_pointer_types.c": {"return_code": 0}, "chapter_14/valid/casts/pointer_int_casts.c": {"return_code": 0}, "chapter_14/valid/casts/null_pointer_conversion.c": {"return_code": 0}, "chapter_14/valid/comparisons/compare_pointers.c": {"return_code": 0}, "chapter_14/valid/comparisons/pointers_as_conditions.c": {"return_code": 0}, "chapter_14/valid/comparisons/compare_to_null.c": {"return_code": 0}, "chapter_10/valid/static_then_extern.c": {"return_code": 3}, "chapter_10/valid/push_arg_on_page_boundary.c": {"return_code": 1}, "chapter_10/valid/static_local_multiple_scopes.c": {"return_code": 0, "stdout": "Aa\nBb\nCc\nDd\nEe\nFf\nGg\nHh\nIi\nJj\nKk\nLl\nMm\nNn\nOo\nPp\nQq\nRr\nSs\nTt\nUu\nVv\nWw\nXx\nYy\nZz\n"}, "chapter_10/valid/tentative_definition.c": {"return_code": 5}, "chapter_10/valid/static_variables_in_expressions.c": {"return_code": 0}, "chapter_10/valid/static_recursive_call.c": {"return_code": 0, "stdout": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, "chapter_10/valid/shadow_static_local_var.c": {"return_code": 0}, "chapter_10/valid/multiple_static_local.c": {"return_code": 29}, "chapter_10/valid/multiple_static_file_scope_vars.c": {"return_code": 4}, "chapter_10/valid/static_local_uninitialized.c": {"return_code": 4}, "chapter_10/valid/type_before_storage_class.c": {"return_code": 7}, "chapter_10/valid/extern_block_scope_variable.c": {"return_code": 3}, "chapter_10/valid/distinct_local_and_extern.c": {"return_code": 7}, "chapter_10/valid/libraries/internal_hides_external_linkage.c": {"return_code": 0}, "chapter_10/valid/libraries/external_tentative_var.c": {"return_code": 0}, "chapter_10/valid/libraries/external_linkage_function.c": {"return_code": 0}, "chapter_10/valid/libraries/external_variable.c": {"return_code": 0}, "chapter_10/valid/libraries/internal_linkage_var.c": {"return_code": 0}, "chapter_10/valid/libraries/external_var_scoping.c": {"return_code": 0}, "chapter_10/valid/libraries/internal_linkage_function.c": {"return_code": 0}, "chapter_10/valid/extra_credit/goto_skip_static_initializer.c": {"return_code": 10}, "chapter_2/valid/neg.c": {"return_code": 251}, "chapter_2/valid/negate_int_max.c": {"return_code": 1}, "chapter_2/valid/redundant_parens.c": {"return_code": 246}, "chapter_2/valid/neg_zero.c": {"return_code": 0}, "chapter_2/valid/bitwise_int_min.c": {"return_code": 254}, "chapter_2/valid/bitwise_zero.c": {"return_code": 255}, "chapter_2/valid/parens_3.c": {"return_code": 4}, "chapter_2/valid/parens_2.c": {"return_code": 253}, "chapter_2/valid/bitwise.c": {"return_code": 243}, "chapter_2/valid/nested_ops_2.c": {"return_code": 1}, "chapter_2/valid/nested_ops.c": {"return_code": 2}, "chapter_2/valid/parens.c": {"return_code": 254}, "chapter_1/valid/return_0.c": {"return_code": 0}, "chapter_1/valid/newlines.c": {"return_code": 0}, "chapter_1/valid/return_2.c": {"return_code": 2}, "chapter_1/valid/multi_digit.c": {"return_code": 100}, "chapter_1/valid/tabs.c": {"return_code": 0}, "chapter_1/valid/spaces.c": {"return_code": 0}, "chapter_1/valid/no_newlines.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/logical.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/static_initialized_double.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/comparisons.c": {"return_code": 0}, "chapter_13/valid/floating_expressions/simple.c": {"return_code": 1}, "chapter_13/valid/floating_expressions/loop_controlling_expression.c": {"return_code": 100}, "chapter_13/valid/libraries/double_parameters.c": {"return_code": 0}, "chapter_13/valid/libraries/use_arg_after_fun_call.c": {"return_code": 4}, "chapter_13/valid/libraries/double_and_int_params_recursive.c": {"return_code": 0}, "chapter_13/valid/libraries/extern_double.c": {"return_code": 1}, "chapter_13/valid/libraries/double_params_and_result.c": {"return_code": 1}, "chapter_13/valid/explicit_casts/cvttsd2i_rewrite.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/double_to_signed.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/unsigned_to_double.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/signed_to_double.c": {"return_code": 0}, "chapter_13/valid/explicit_casts/double_to_unsigned.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/convert_for_assignment.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/static_initializers.c": {"return_code": 0}, "chapter_13/valid/implicit_casts/complex_arithmetic_common_type.c": {"return_code": 1}, "chapter_13/valid/constants/round_constants.c": {"return_code": 0}, "chapter_13/valid/constants/constant_doubles.c": {"return_code": 0}, "chapter_13/valid/special_values/subnormal_not_zero.c": {"return_code": 0}, "chapter_13/valid/special_values/negative_zero.c": {"return_code": 0}, "chapter_13/valid/special_values/infinity.c": {"return_code": 0}, "chapter_13/valid/function_calls/double_parameters.c": {"return_code": 0}, "chapter_13/valid/function_calls/double_and_int_parameters.c": {"return_code": 0}, "chapter_13/valid/function_calls/standard_library_call.c": {"return_code": 0}, "chapter_13/valid/function_calls/use_arg_after_fun_call.c": {"return_code": 4}, "chapter_13/valid/function_calls/return_double.c": {"return_code": 1}, "chapter_13/valid/function_calls/double_and_int_params_recursive.c": {"return_code": 0}, "chapter_13/valid/extra_credit/compound_assign.c": {"return_code": 1}, "chapter_13/valid/extra_credit/nan.c": {"return_code": 0}, "chapter_13/valid/extra_credit/compound_assign_implicit_cast.c": {"return_code": 1}, "chapter_18/valid/params_and_returns/pass_and_return_struct.c": {"return_code": 11}, "chapter_18/valid/params_and_returns/temporary_lifetime.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_struct_on_page_boundary.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_incomplete_type.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/cast_struct_to_void.c": {"return_code": 2}, "chapter_18/valid/params_and_returns/return_struct.c": {"return_code": 11}, "chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/pass_wonky_struct.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/missing_retval.c": {"return_code": 1}, "chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/pass_pointer_to_struct.c": {"return_code": 112}, "chapter_18/valid/no_structure_parameters/typecheck/deref_incomplete_var.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/typecheck/conditional_struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/typecheck/block_scope_forward_decl.c": {"return_code": 3}, "chapter_18/valid/no_structure_parameters/typecheck/define_then_declare.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/typecheck/incomplete_var_completed.c": {"return_code": 100}, "chapter_18/valid/no_structure_parameters/typecheck/file_scope_forward_decl.c": {"return_code": 2}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/copy_struct_with_array_2.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/load_test.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/copy_struct_into_member.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/copy_struct.c": {"return_code": 7}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/array_of_structs_padding.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/array_of_structs.c": {"return_code": 19}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/copy_from_offset_test.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy_tests/copy_struct_with_array.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/global_struct.c": {"return_code": 7}, "chapter_18/valid/no_structure_parameters/member_access_tests/deref_arrow.c": {"return_code": 3}, "chapter_18/valid/no_structure_parameters/member_access_tests/linked_list.c": {"return_code": 30}, "chapter_18/valid/no_structure_parameters/member_access_tests/assign_to_struct.c": {"return_code": 10}, "chapter_18/valid/no_structure_parameters/member_access_tests/pointer_to_struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/get_array_through_pointer.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/nested_struct.c": {"return_code": 16}, "chapter_18/valid/no_structure_parameters/member_access_tests/addr_of_arrow.c": {"return_code": 10}, "chapter_18/valid/no_structure_parameters/member_access_tests/copy_from_pointer.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/static_struct.c": {"return_code": 19}, "chapter_18/valid/no_structure_parameters/member_access_tests/global_nested_struct.c": {"return_code": 8}, "chapter_18/valid/no_structure_parameters/member_access_tests/non_static_struct.c": {"return_code": 9}, "chapter_18/valid/no_structure_parameters/member_access_tests/get_member_addresses.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/member_access_tests/nested_address_calculations.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/member_access_tests/aggregate_through_arrow.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/member_access_tests/copy_to_pointer.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/member_access_tests/assign_to_struct_pointer.c": {"return_code": 10}, "chapter_18/valid/no_structure_parameters/libraries/global_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/incomplete_var.c": {"return_code": 5}, "chapter_18/valid/no_structure_parameters/libraries/nested_pointer_access.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/sizeof/sizeof_wonky.c": {"return_code": 19}, "chapter_18/valid/no_structure_parameters/sizeof/sizeof_struct.c": {"return_code": 8}, "chapter_18/valid/no_structure_parameters/sizeof/sizeof_padded.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/parse_and_lex/postfix_precedence.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/parse_and_lex/space_around_struct_member.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/parse_and_lex/struct_member_looks_like_const.c": {"return_code": 3}, "chapter_18/valid/no_structure_parameters/initializers/nested_struct_init.c": {"return_code": 157}, "chapter_18/valid/no_structure_parameters/initializers/mixed_initialization.c": {"return_code": 7}, "chapter_18/valid/no_structure_parameters/initializers/load_addr_in_init.c": {"return_code": 6}, "chapter_18/valid/no_structure_parameters/initializers/partial_struct_init.c": {"return_code": 26}, "chapter_18/valid/no_structure_parameters/initializers/string_in_global_struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/initializers/string_in_struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/scoping_tests/scoped_struct.c": {"return_code": 2}, "chapter_18/valid/no_structure_parameters/scoping_tests/resolve_tag_for_loop_decl.c": {"return_code": 10}, "chapter_18/valid/no_structure_parameters/scoping_tests/same_tag_name.c": {"return_code": 8}, "chapter_18/valid/no_structure_parameters/scoping_tests/resolve_tags_derived_types.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/scoping_tests/different_namespaces_same_ids.c": {"return_code": 10}, "chapter_18/valid/no_structure_parameters/scoping_tests/resolve_tag_sizeof.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/scoping_tests/same_tag_name_simple.c": {"return_code": 4}, "chapter_18/valid/no_structure_parameters/scoping_tests/declare_struct.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/scoping_tests/shared_struct_and_var_names.c": {"return_code": 1}, "chapter_18/valid/parameters/pass_struct_as_arg.c": {"return_code": 1}, "chapter_18/valid/parameters/pass_args_on_page_boundary.c": {"return_code": 0}, "chapter_18/valid/parameters/incomplete_param_type.c": {"return_code": 3}, "chapter_18/valid/parameters/pass_struct_and_other_args.c": {"return_code": 1}, "chapter_18/valid/parameters/libraries/param_calling_conventions.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/preserve_stack.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/struct_sizes.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/pass_struct.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/array_of_structs.c": {"return_code": 0}, "chapter_15/valid/initialization/automatic.c": {"return_code": 0}, "chapter_15/valid/initialization/static.c": {"return_code": 0}, "chapter_15/valid/initialization/trailing_comma_initializer.c": {"return_code": 3}, "chapter_15/valid/initialization/automatic_nested.c": {"return_code": 0}, "chapter_15/valid/initialization/static_nested.c": {"return_code": 0}, "chapter_15/valid/libraries/set_array_val.c": {"return_code": 0}, "chapter_15/valid/libraries/return_pointer_to_array.c": {"return_code": 0}, "chapter_15/valid/libraries/global_array.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_nested.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_pointer.c": {"return_code": 0}, "chapter_15/valid/subscripting/array_of_pointers_to_arrays.c": {"return_code": 0}, "chapter_15/valid/subscripting/simple_subscripts.c": {"return_code": 0}, "chapter_15/valid/subscripting/simple.c": {"return_code": 3}, "chapter_15/valid/subscripting/complex_operands.c": {"return_code": 0}, "chapter_15/valid/subscripting/addition_subscript_equivalence.c": {"return_code": 0}, "chapter_15/valid/subscripting/subscript_precedence.c": {"return_code": 1}, "chapter_15/valid/allocation/test_alignment.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/pointer_add.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/add_dereference_and_assign.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/pointer_diff.c": {"return_code": 0}, "chapter_15/valid/pointer_arithmetic/compare.c": {"return_code": 0}, "chapter_15/valid/extra_credit/incr_ptr.c": {"return_code": 1}, "chapter_15/valid/declarators/big_array.c": {"return_code": 0}, "chapter_15/valid/declarators/equivalent_declarators.c": {"return_code": 0}, "chapter_15/valid/declarators/return_nested_array.c": {"return_code": 0}, "chapter_15/valid/declarators/array_as_argument.c": {"return_code": 0}, "chapter_15/valid/declarators/for_loop_array.c": {"return_code": 0}, "chapter_15/valid/casts/multi_dim_casts.c": {"return_code": 0}, "chapter_15/valid/casts/implicit_and_explicit_conversions.c": {"return_code": 0}, "chapter_15/valid/casts/cast_array_of_pointers.c": {"return_code": 1}, "chapter_17/valid/void/cast_to_void.c": {"return_code": 12}, "chapter_17/valid/void/void_function.c": {"return_code": 0}, "chapter_17/valid/void/void_for_loop.c": {"return_code": 0, "stdout": "ZYXWVUTSRQPONMLKJIHGFEDCBAABCDEFGHIJKLMNOPQRSTUVWXYZZYXWVUTSRQPONMLKJIHGFEDCBA"}, "chapter_17/valid/void/ternary.c": {"return_code": 0}, "chapter_17/valid/libraries/pass_alloced_memory.c": {"return_code": 0}, "chapter_17/valid/libraries/test_for_memory_leaks.c": {"return_code": 0}, "chapter_17/valid/libraries/sizeof_extern.c": {"return_code": 1}, "chapter_17/valid/sizeof/sizeof_basic_types.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_consts.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_expressions.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_array.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_derived_types.c": {"return_code": 0}, "chapter_17/valid/sizeof/simple.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_result_is_ulong.c": {"return_code": 0}, "chapter_17/valid/sizeof/sizeof_not_evaluated.c": {"return_code": 4}, "chapter_17/valid/void_pointer/array_of_pointers_to_void.c": {"return_code": 0}, "chapter_17/valid/void_pointer/conversion_by_assignment.c": {"return_code": 0}, "chapter_17/valid/void_pointer/explicit_cast.c": {"return_code": 0}, "chapter_17/valid/void_pointer/simple.c": {"return_code": 100}, "chapter_17/valid/void_pointer/memory_management_functions.c": {"return_code": 0}, "chapter_17/valid/void_pointer/common_pointer_type.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/addr_of_string.c": {"return_code": 0, "stdout": "Sample\tstring!\n\n"}, "chapter_16/valid/strings_as_lvalues/standard_library_calls.c": {"return_code": 0, "stdout": "Hello, World!\n"}, "chapter_16/valid/strings_as_lvalues/array_of_strings.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/cast_string_pointer.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/empty_string.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/pointer_operations.c": {"return_code": 0}, "chapter_16/valid/strings_as_lvalues/simple.c": {"return_code": 108}, "chapter_16/valid/strings_as_lvalues/adjacent_strings.c": {"return_code": 0, "stdout": "Hello, World\n"}, "chapter_16/valid/strings_as_lvalues/string_special_characters.c": {"return_code": 0, "stdout": "Hello\"world\nHello\\World\nLine\nbreak!\nTesting, 123.\n^@1 _\\]\n"}, "chapter_16/valid/strings_as_lvalues/strings_in_function_calls.c": {"return_code": 0}, "chapter_16/valid/libraries/return_char.c": {"return_code": 0}, "chapter_16/valid/libraries/char_arguments.c": {"return_code": 0}, "chapter_16/valid/libraries/global_char.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/array_init_special_chars.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/terminating_null_bytes.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/simple.c": {"return_code": 99}, "chapter_16/valid/strings_as_initializers/partial_initialize_via_string.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/adjacent_strings_in_initializer.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/transfer_by_eightbyte.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/literals_and_compound_initializers.c": {"return_code": 0}, "chapter_16/valid/strings_as_initializers/write_to_array.c": {"return_code": 0, "stdout": "abc\nabx\nHello\nWorld\nJello\n"}, "chapter_16/valid/strings_as_initializers/test_alignment.c": {"return_code": 0}, "chapter_16/valid/char_constants/return_char_constant.c": {"return_code": 99}, "chapter_16/valid/char_constants/escape_sequences.c": {"return_code": 0}, "chapter_16/valid/char_constants/control_characters.c": {"return_code": 0}, "chapter_16/valid/char_constants/char_constant_operations.c": {"return_code": 0}, "chapter_16/valid/chars/partial_initialization.c": {"return_code": 0}, "chapter_16/valid/chars/convert_by_assignment.c": {"return_code": 0}, "chapter_16/valid/chars/type_specifiers.c": {"return_code": 0}, "chapter_16/valid/chars/push_arg_on_page_boundary.c": {"return_code": 1}, "chapter_16/valid/chars/integer_promotion.c": {"return_code": 0}, "chapter_16/valid/chars/chained_casts.c": {"return_code": 0}, "chapter_16/valid/chars/return_char.c": {"return_code": 0}, "chapter_16/valid/chars/char_arguments.c": {"return_code": 0}, "chapter_16/valid/chars/char_expressions.c": {"return_code": 0}, "chapter_16/valid/chars/access_through_char_pointer.c": {"return_code": 0}, "chapter_16/valid/chars/common_type.c": {"return_code": 0}, "chapter_16/valid/chars/static_initializers.c": {"return_code": 0}, "chapter_16/valid/chars/explicit_casts.c": {"return_code": 0}, "chapter_9/valid/arguments_in_registers/parameter_shadows_own_function.c": {"return_code": 2}, "chapter_9/valid/arguments_in_registers/expression_args.c": {"return_code": 2}, "chapter_9/valid/arguments_in_registers/single_arg.c": {"return_code": 6}, "chapter_9/valid/arguments_in_registers/hello_world.c": {"return_code": 0, "stdout": "Hello, World!\n"}, "chapter_9/valid/arguments_in_registers/parameter_shadows_function.c": {"return_code": 3}, "chapter_9/valid/arguments_in_registers/parameters_are_preserved.c": {"return_code": 1}, "chapter_9/valid/arguments_in_registers/forward_decl_multi_arg.c": {"return_code": 1}, "chapter_9/valid/arguments_in_registers/fibonacci.c": {"return_code": 8}, "chapter_9/valid/arguments_in_registers/param_shadows_local_var.c": {"return_code": 20}, "chapter_9/valid/no_arguments/function_shadows_variable.c": {"return_code": 11}, "chapter_9/valid/no_arguments/use_function_in_expression.c": {"return_code": 21}, "chapter_9/valid/no_arguments/no_return_value.c": {"return_code": 3}, "chapter_9/valid/no_arguments/multiple_declarations.c": {"return_code": 3}, "chapter_9/valid/no_arguments/precedence.c": {"return_code": 0}, "chapter_9/valid/no_arguments/forward_decl.c": {"return_code": 3}, "chapter_9/valid/no_arguments/variable_shadows_function.c": {"return_code": 7}, "chapter_9/valid/libraries/system_call.c": {"return_code": 0, "stdout": "H"}, "chapter_9/valid/libraries/many_args.c": {"return_code": 115}, "chapter_9/valid/libraries/addition.c": {"return_code": 3}, "chapter_9/valid/libraries/no_function_calls/division.c": {"return_code": 1}, "chapter_9/valid/libraries/no_function_calls/local_stack_variables.c": {"return_code": 100}, "chapter_9/valid/extra_credit/compound_assign_function_result.c": {"return_code": 1}, "chapter_9/valid/extra_credit/goto_label_multiple_functions.c": {"return_code": 5}, "chapter_9/valid/extra_credit/goto_shared_name.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/call_putchar.c": {"return_code": 8, "stdout": "A"}, "chapter_9/valid/stack_arguments/lots_of_arguments.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/stack_alignment.c": {"return_code": 1}, "chapter_9/valid/stack_arguments/test_for_memory_leaks.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/logical.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/arithmetic_wraparound.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/comparisons.c": {"return_code": 0}, "chapter_12/valid/unsigned_expressions/simple.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/static_variables.c": {"return_code": 1}, "chapter_12/valid/unsigned_expressions/locals.c": {"return_code": 0}, "chapter_12/valid/libraries/unsigned_args.c": {"return_code": 0}, "chapter_12/valid/libraries/unsigned_global_var.c": {"return_code": 1}, "chapter_12/valid/explicit_casts/same_size_conversion.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/extension.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/round_trip_casts.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/chained_casts.c": {"return_code": 0}, "chapter_12/valid/explicit_casts/truncate.c": {"return_code": 0}, "chapter_12/valid/type_specifiers/signed_type_specifiers.c": {"return_code": 0}, "chapter_12/valid/type_specifiers/unsigned_type_specifiers.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/convert_by_assignment.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/promote_constants.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_12/valid/implicit_casts/static_initializers.c": {"return_code": 0}, "chapter_12/valid/extra_credit/switch_uint.c": {"return_code": 0}, "chapter_12/valid/extra_credit/compound_assign_uint.c": {"return_code": 1}, "chapter_12/valid/extra_credit/bitwise_unsigned_shift.c": {"return_code": 1}, "chapter_12/valid/extra_credit/bitwise_unsigned_ops.c": {"return_code": 1}, "chapter_5/valid/null_then_return.c": {"return_code": 0}, "chapter_5/valid/empty_function_body.c": {"return_code": 0}, "chapter_5/valid/short_circuit_or.c": {"return_code": 0}, "chapter_5/valid/assignment_in_initializer.c": {"return_code": 0}, "chapter_5/valid/non_short_circuit_or.c": {"return_code": 1}, "chapter_5/valid/null_statement.c": {"return_code": 0}, "chapter_5/valid/short_circuit_and_fail.c": {"return_code": 0}, "chapter_5/valid/local_var_missing_return.c": {"return_code": 0}, "chapter_5/valid/exp_then_declaration.c": {"return_code": 1}, "chapter_5/valid/add_variables.c": {"return_code": 3}, "chapter_5/valid/assign_val_in_initializer.c": {"return_code": 5}, "chapter_5/valid/assignment_lowest_precedence.c": {"return_code": 1}, "chapter_5/valid/allocate_temps_and_vars.c": {"return_code": 1}, "chapter_5/valid/use_assignment_result.c": {"return_code": 4}, "chapter_5/valid/use_val_in_own_initializer.c": {"return_code": 0}, "chapter_5/valid/unused_exp.c": {"return_code": 0}, "chapter_5/valid/return_var.c": {"return_code": 2}, "chapter_5/valid/mixed_precedence_assignment.c": {"return_code": 4}, "chapter_5/valid/assign.c": {"return_code": 2}, "chapter_5/valid/extra_credit/bitwise_shiftr_assign.c": {"return_code": 77}, "chapter_5/valid/extra_credit/bitwise_shiftl_variable.c": {"return_code": 24}, "chapter_5/valid/extra_credit/compound_bitwise_and.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_minus.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_multiply.c": {"return_code": 12}, "chapter_5/valid/extra_credit/compound_bitwise_xor.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_bitwise_or.c": {"return_code": 31}, "chapter_5/valid/extra_credit/compound_assignment_chained.c": {"return_code": 4}, "chapter_5/valid/extra_credit/compound_divide.c": {"return_code": 2}, "chapter_5/valid/extra_credit/compound_bitwise_shiftr.c": {"return_code": 102}, "chapter_5/valid/extra_credit/compound_assignment_use_result.c": {"return_code": 8}, "chapter_5/valid/extra_credit/compound_bitwise_shiftl.c": {"return_code": 48}, "chapter_5/valid/extra_credit/compound_plus.c": {"return_code": 4}, "chapter_5/valid/extra_credit/compound_mod.c": {"return_code": 2}, "chapter_5/valid/extra_credit/bitwise_and_vars.c": {"return_code": 1}, "chapter_7/valid/declaration_only.c": {"return_code": 1}, "chapter_7/valid/assign_to_self_2.c": {"return_code": 3}, "chapter_7/valid/hidden_then_visible.c": {"return_code": 1}, "chapter_7/valid/hidden_variable.c": {"return_code": 1}, "chapter_7/valid/assign_to_self.c": {"return_code": 4}, "chapter_7/valid/inner_uninitialized.c": {"return_code": 4}, "chapter_7/valid/multiple_vars_same_name.c": {"return_code": 2}, "chapter_7/valid/use_in_inner_scope.c": {"return_code": 3}, "chapter_7/valid/empty_blocks.c": {"return_code": 30}, "chapter_7/valid/nested_if.c": {"return_code": 1}, "chapter_7/valid/similar_var_names.c": {"return_code": 28}, "chapter_7/valid/extra_credit/goto_before_declaration.c": {"return_code": 0}, "chapter_7/valid/extra_credit/compound_subtract_in_block.c": {"return_code": 1}, "chapter_7/valid/extra_credit/goto_inner_scope.c": {"return_code": 1}, "chapter_4/valid/le_true.c": {"return_code": 2}, "chapter_4/valid/ne_true.c": {"return_code": 1}, "chapter_4/valid/ge_false.c": {"return_code": 0}, "chapter_4/valid/not_zero.c": {"return_code": 1}, "chapter_4/valid/precedence_2.c": {"return_code": 0}, "chapter_4/valid/ge_true.c": {"return_code": 2}, "chapter_4/valid/eq_precedence.c": {"return_code": 1}, "chapter_4/valid/eq_false.c": {"return_code": 0}, "chapter_4/valid/or_short_circuit.c": {"return_code": 1}, "chapter_4/valid/not_sum.c": {"return_code": 1}, "chapter_4/valid/precedence_4.c": {"return_code": 1}, "chapter_4/valid/and_short_circuit.c": {"return_code": 0}, "chapter_4/valid/precedence_3.c": {"return_code": 0}, "chapter_4/valid/compare_arithmetic_results.c": {"return_code": 1}, "chapter_4/valid/and_false.c": {"return_code": 0}, "chapter_4/valid/precedence_5.c": {"return_code": 1}, "chapter_4/valid/associativity.c": {"return_code": 1}, "chapter_4/valid/gt_true.c": {"return_code": 1}, "chapter_4/valid/lt_false.c": {"return_code": 0}, "chapter_4/valid/or_true.c": {"return_code": 3}, "chapter_4/valid/or_false.c": {"return_code": 0}, "chapter_4/valid/eq_true.c": {"return_code": 1}, "chapter_4/valid/ne_false.c": {"return_code": 0}, "chapter_4/valid/multi_short_circuit.c": {"return_code": 0}, "chapter_4/valid/gt_false.c": {"return_code": 0}, "chapter_4/valid/operate_on_booleans.c": {"return_code": 0}, "chapter_4/valid/not.c": {"return_code": 0}, "chapter_4/valid/le_false.c": {"return_code": 0}, "chapter_4/valid/nested_ops.c": {"return_code": 0}, "chapter_4/valid/precedence.c": {"return_code": 1}, "chapter_4/valid/not_sum_2.c": {"return_code": 0}, "chapter_4/valid/and_true.c": {"return_code": 1}, "chapter_4/valid/lt_true.c": {"return_code": 1}, "chapter_4/valid/extra_credit/bitwise_precedence.c": {"return_code": 1}, "chapter_3/valid/mod.c": {"return_code": 0}, "chapter_3/valid/unop_add.c": {"return_code": 0}, "chapter_3/valid/associativity_3.c": {"return_code": 8}, "chapter_3/valid/mult.c": {"return_code": 6}, "chapter_3/valid/sub.c": {"return_code": 255}, "chapter_3/valid/div_neg.c": {"return_code": 254}, "chapter_3/valid/unop_parens.c": {"return_code": 253}, "chapter_3/valid/add.c": {"return_code": 3}, "chapter_3/valid/associativity.c": {"return_code": 252}, "chapter_3/valid/associativity_2.c": {"return_code": 1}, "chapter_3/valid/div.c": {"return_code": 2}, "chapter_3/valid/sub_neg.c": {"return_code": 3}, "chapter_3/valid/associativity_and_precedence.c": {"return_code": 10}, "chapter_3/valid/parens.c": {"return_code": 14}, "chapter_3/valid/precedence.c": {"return_code": 14}, "chapter_3/valid/extra_credit/bitwise_shiftr.c": {"return_code": 62}, "chapter_3/valid/extra_credit/bitwise_and.c": {"return_code": 1}, "chapter_3/valid/extra_credit/bitwise_shiftl.c": {"return_code": 140}, "chapter_3/valid/extra_credit/bitwise_or.c": {"return_code": 3}, "chapter_3/valid/extra_credit/bitwise_shift_precedence.c": {"return_code": 0}, "chapter_3/valid/extra_credit/bitwise_xor.c": {"return_code": 6}, "chapter_3/valid/extra_credit/bitwise_shift_associativity_2.c": {"return_code": 16}, "chapter_3/valid/extra_credit/bitwise_shift_associativity.c": {"return_code": 66}, "chapter_3/valid/extra_credit/bitwise_precedence.c": {"return_code": 21}, "chapter_11/valid/long_expressions/long_args.c": {"return_code": 0}, "chapter_11/valid/long_expressions/logical.c": {"return_code": 0}, "chapter_11/valid/long_expressions/type_specifiers.c": {"return_code": 0}, "chapter_11/valid/long_expressions/multi_op.c": {"return_code": 1}, "chapter_11/valid/long_expressions/large_constants.c": {"return_code": 0}, "chapter_11/valid/long_expressions/arithmetic_ops.c": {"return_code": 0}, "chapter_11/valid/long_expressions/return_long.c": {"return_code": 1}, "chapter_11/valid/long_expressions/comparisons.c": {"return_code": 0}, "chapter_11/valid/long_expressions/simple.c": {"return_code": 1}, "chapter_11/valid/long_expressions/static_long.c": {"return_code": 1}, "chapter_11/valid/long_expressions/long_and_int_locals.c": {"return_code": 0}, "chapter_11/valid/long_expressions/assign.c": {"return_code": 1}, "chapter_11/valid/libraries/long_args.c": {"return_code": 0}, "chapter_11/valid/libraries/maintain_stack_alignment.c": {"return_code": 12}, "chapter_11/valid/libraries/return_long.c": {"return_code": 1}, "chapter_11/valid/libraries/long_global_var.c": {"return_code": 0}, "chapter_11/valid/explicit_casts/truncate.c": {"return_code": 0}, "chapter_11/valid/explicit_casts/sign_extend.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_by_assignment.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/common_type.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/long_constants.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_function_arguments.c": {"return_code": 0}, "chapter_11/valid/implicit_casts/convert_static_initializer.c": {"return_code": 0}, "chapter_11/valid/extra_credit/bitwise_long_op.c": {"return_code": 1}, "chapter_11/valid/extra_credit/compound_assign_to_int.c": {"return_code": 1}, "chapter_11/valid/extra_credit/compound_assign_to_long.c": {"return_code": 1}, "chapter_11/valid/extra_credit/switch_int.c": {"return_code": 1}, "chapter_11/valid/extra_credit/switch_long.c": {"return_code": 1}, "chapter_19/whole_pipeline/all_types/alias_analysis_change.c": {"return_code": 0}, "chapter_19/whole_pipeline/int_only/dead_condition.c": {"return_code": 10}, "chapter_19/whole_pipeline/int_only/elim_and_copy_prop.c": {"return_code": 10}, "chapter_19/whole_pipeline/int_only/remainder_test.c": {"return_code": 1}, "chapter_19/dead_store_elimination/all_types/aliased_dead_at_exit.c": {"return_code": 1}, "chapter_19/dead_store_elimination/all_types/getaddr_doesnt_gen.c": {"return_code": 0}, "chapter_19/dead_store_elimination/all_types/copy_to_dead_struct.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/dont_elim/copytooffset_doesnt_kill.c": {"return_code": 101}, "chapter_19/dead_store_elimination/all_types/dont_elim/store_generates_dst.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/dont_elim/load_generates_pointer.c": {"return_code": 10}, "chapter_19/dead_store_elimination/all_types/dont_elim/load_through_pointer.c": {"return_code": 10}, "chapter_19/dead_store_elimination/all_types/dont_elim/pass_pointer_to_fun.c": {"return_code": 5}, "chapter_19/dead_store_elimination/all_types/dont_elim/never_kill_store.c": {"return_code": 4}, "chapter_19/dead_store_elimination/all_types/dont_elim/copyfromoffset_gen.c": {"return_code": 3}, "chapter_19/dead_store_elimination/int_only/fig_19_12.c": {"return_code": 9}, "chapter_19/dead_store_elimination/int_only/use_and_kill.c": {"return_code": 5}, "chapter_19/dead_store_elimination/int_only/dead_store_static_var.c": {"return_code": 1}, "chapter_19/dead_store_elimination/int_only/loop_dead_store.c": {"return_code": 51}, "chapter_19/dead_store_elimination/int_only/simple.c": {"return_code": 3}, "chapter_19/dead_store_elimination/int_only/elim_second_copy.c": {"return_code": 10}, "chapter_19/dead_store_elimination/int_only/dont_elim/static_vars_at_exit.c": {"return_code": 1}, "chapter_19/dead_store_elimination/int_only/dont_elim/used_one_path.c": {"return_code": 40}, "chapter_19/dead_store_elimination/int_only/dont_elim/dont_remove_funcall.c": {"return_code": 0, "stdout": "C"}, "chapter_19/dead_store_elimination/int_only/dont_elim/add_all_to_worklist.c": {"return_code": 0, "stdout": "L"}, "chapter_19/dead_store_elimination/int_only/dont_elim/loop.c": {"return_code": 54}, "chapter_19/dead_store_elimination/int_only/dont_elim/static_vars_fun.c": {"return_code": 5}, "chapter_19/unreachable_code_elimination/remove_useless_starting_label.c": {"return_code": 99}, "chapter_19/unreachable_code_elimination/dead_for_loop.c": {"return_code": 10}, "chapter_19/unreachable_code_elimination/remove_jnz.c": {"return_code": 1}, "chapter_19/unreachable_code_elimination/dead_branch_inside_loop.c": {"return_code": 19}, "chapter_19/unreachable_code_elimination/empty.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/constant_if_else.c": {"return_code": 45}, "chapter_19/unreachable_code_elimination/loop_in_dead_branch.c": {"return_code": 0}, "chapter_19/unreachable_code_elimination/dead_after_return.c": {"return_code": 2}, "chapter_19/unreachable_code_elimination/empty_block.c": {"return_code": 1}, "chapter_19/unreachable_code_elimination/dead_after_if_else.c": {"return_code": 1}, "chapter_19/unreachable_code_elimination/dont_elim/keep_final_jump.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_cast_to_double.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_ulong.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_double.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_long.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_uint.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/fold_cast_from_double.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/truncate.c": {"return_code": 0}, "chapter_19/constant_folding/all_types/zero_and_sign_extend.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_divide_by_zero.c": {"return_code": 1}, "chapter_19/constant_folding/int_only/fold_unary.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_dead_branch.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_conditional_jump.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_comparisons.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_arithmetic.c": {"return_code": 0}, "chapter_19/constant_folding/int_only/fold_overflow.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/pointer_arithmetic.c": {"return_code": 2}, "chapter_19/copy_propagation/all_types/store_doesnt_kill.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/unsigned_wraparound.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/propagate_doubles.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/unsigned_compare.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/signed_unsigned_conversion.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/char_type_conversion.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/not_char.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/char_round_trip_2.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/alias_analysis.c": {"return_code": 24}, "chapter_19/copy_propagation/all_types/const_fold_sign_extend.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/copy_struct.c": {"return_code": 6}, "chapter_19/copy_propagation/all_types/propagate_null_pointer.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/char_round_trip.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/const_fold_type_conversions.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/const_fold_sign_extend_2.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/dont_propagate/static_are_aliased.c": {"return_code": 8}, "chapter_19/copy_propagation/all_types/dont_propagate/store_kills_aliased.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/copy_to_offset.c": {"return_code": 3}, "chapter_19/copy_propagation/all_types/dont_propagate/dont_propagate_addr_of.c": {"return_code": 0}, "chapter_19/copy_propagation/all_types/dont_propagate/type_conversion.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/dont_propagate/zero_neg_zero_different.c": {"return_code": 1}, "chapter_19/copy_propagation/all_types/dont_propagate/funcall_kills_aliased.c": {"return_code": 2}, "chapter_19/copy_propagation/int_only/propagate_fun_args.c": {"return_code": 220}, "chapter_19/copy_propagation/int_only/killed_then_redefined.c": {"return_code": 2}, "chapter_19/copy_propagation/int_only/redundant_copies_2.c": {"return_code": 10}, "chapter_19/copy_propagation/int_only/multi_path_no_kill.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/redundant_copies.c": {"return_code": 10}, "chapter_19/copy_propagation/int_only/fig_19_8.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/kill_and_add_copies.c": {"return_code": 14}, "chapter_19/copy_propagation/int_only/multi_instance_same_copy.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/init_all_copies.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/complex_const_fold.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/copy_prop_const_fold.c": {"return_code": 6}, "chapter_19/copy_propagation/int_only/prop_static_var.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/propagate_var.c": {"return_code": 6}, "chapter_19/copy_propagation/int_only/multi_path.c": {"return_code": 6}, "chapter_19/copy_propagation/int_only/loop.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/dont_propagate/source_killed_on_one_path.c": {"return_code": 8}, "chapter_19/copy_propagation/int_only/dont_propagate/one_reaching_copy.c": {"return_code": 3}, "chapter_19/copy_propagation/int_only/dont_propagate/listing_20_15.c": {"return_code": 101}, "chapter_19/copy_propagation/int_only/dont_propagate/dest_killed.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/no_copies_reach_entry.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/add_all_blocks_to_worklist.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/multi_values.c": {"return_code": 7}, "chapter_19/copy_propagation/int_only/dont_propagate/static_dst_killed.c": {"return_code": 4}, "chapter_19/copy_propagation/int_only/dont_propagate/static_src_killed.c": {"return_code": 1}, "chapter_19/copy_propagation/int_only/dont_propagate/source_killed.c": {"return_code": 10}, "chapter_20/all_types/no_coalescing/mixed_ints.c": {"return_code": 9}, "chapter_20/all_types/no_coalescing/dbl_trivially_colorable.c": {"return_code": 3}, "chapter_20/all_types/no_coalescing/spill_movz_dst.c": {"return_code": 29}, "chapter_20/all_types/no_coalescing/push_xmm.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/dbl_fun_call.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/stack_alignment.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/track_dbl_arg_registers.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/fourteen_pseudos_interfere.c": {"return_code": 0}, "chapter_20/all_types/no_coalescing/div_interference.c": {"return_code": 1}, "chapter_20/all_types/no_coalescing/test_spilling_dbls.c": {"return_code": 3}, "chapter_20/all_types/no_coalescing/store_pointer_in_register.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/same_instr_interference.c": {"return_code": 6}, "chapter_20/int_only/no_coalescing/spills_rewrites_compare.c": {"return_code": 3}, "chapter_20/int_only/no_coalescing/copy_and_separate_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/spills_and_rewrites.c": {"return_code": 23}, "chapter_20/int_only/no_coalescing/cmp_liveness.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/rewrite_large_multiply.c": {"return_code": 58}, "chapter_20/int_only/no_coalescing/spill_callee_saved.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/test_spill_metric.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/unary_interference.c": {"return_code": 10}, "chapter_20/int_only/no_coalescing/optimistic_coloring.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/track_arg_registers.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/many_pseudos_fewer_conflicts.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/same_instr_no_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/copy_no_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/force_spill.c": {"return_code": 9}, "chapter_20/int_only/no_coalescing/callee_saved_stack_alignment.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/idiv_interference.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/preserve_across_fun_call.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/use_all_hardregs.c": {"return_code": 0}, "chapter_20/int_only/no_coalescing/test_spill_metric_2.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/loop.c": {"return_code": 6}, "chapter_20/int_only/no_coalescing/trivially_colorable.c": {"return_code": 1}, "chapter_20/int_only/no_coalescing/cdq_interference.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/cdq_generates_ax.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/callee_saved_live_at_exit.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/coalesce_prevents_spill.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/george_coalesce.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/unary_generates_dst.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/briggs_coalesce.c": {"return_code": 2}, "chapter_20/int_only/with_coalescing/bin_generates_dst.c": {"return_code": 187}, "chapter_20/int_only/with_coalescing/briggs_coalesce_tmps.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/cmp_generates_operands.c": {"return_code": 1}, "chapter_20/int_only/with_coalescing/funcall_generates_args.c": {"return_code": 0}, "chapter_20/int_only/with_coalescing/eax_live_at_exit.c": {"return_code": 1}, "chapter_18/valid/no_structure_parameters/semantic_analysis/resolve_tags.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/semantic_analysis/namespaces.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/semantic_analysis/incomplete_structs.c": {"return_code": 0, "stdout": "I'm a struct!\n"}, "chapter_18/valid/no_structure_parameters/semantic_analysis/cast_struct_to_void.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/param_struct_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/return_struct_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/opaque_struct.c": {"return_code": 0, "stdout": "new struct\nstatic struct\nglobal struct\n"}, "chapter_18/valid/no_structure_parameters/libraries/array_of_structs.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/auto_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/static_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/nested_static_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/libraries/initializers/nested_auto_struct_initializers.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/smoke_tests/static_vs_auto.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/smoke_tests/simple.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/member_offsets.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/sizeof_exps.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/size_and_offset_calculations/sizeof_type.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/arrow.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/linked_list.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/static_structs.c": {"return_code": 0, "stdout": "zero\nmn\nop\nwx\nyz\nBCD\nCDE\nDEF\nEFG\nbcd\ncde\n"}, "chapter_18/valid/no_structure_parameters/scalar_member_access/nested_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/scalar_member_access/dot.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/parse_and_lex/trailing_comma.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/load_test.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_with_arrow_operator.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct.c": {"return_code": 0}, "chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_with_dot_operator.c": {"return_code": 0}, "chapter_18/valid/parameters/simple.c": {"return_code": 0}, "chapter_18/valid/parameters/stack_clobber.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/modify_param.c": {"return_code": 0}, "chapter_18/valid/parameters/libraries/classify_params.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/ignore_retval.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_space_overlap.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/return_big_struct_on_page_boundary.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/simple.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/stack_clobber.c": {"return_code": 0}, "chapter_18/valid/params_and_returns/libraries/access_retval_members.c": {"return_code": 0}} \ No newline at end of file diff --git a/test_framework/basic.py b/test_framework/basic.py index 82c68782..ed040c47 100644 --- a/test_framework/basic.py +++ b/test_framework/basic.py @@ -53,11 +53,13 @@ def needs_mathlib(prog: Path) -> bool: key = get_props_key(prog) return key in REQUIRES_MATHLIB and not IS_OSX + def print_stderr(proc: subprocess.CompletedProcess[str]) -> None: """Print out stderr of CompletedProcess if it's not empty. Intended to print assembler/linker warnings""" if proc.stderr: print(proc.stderr) + def gcc_build_obj(prog: Path) -> None: """Use the 'gcc' command to compile source file to an object file. This is used to test ABI compatibility between our compiler and the system compiler @@ -119,7 +121,6 @@ def gcc_compile_and_run( # TODO better handling of internal problems with test suite raise RuntimeError(err.stderr) from err - # run it return subprocess.run([exe], check=False, text=True, capture_output=True) @@ -178,7 +179,7 @@ def tearDown(self) -> None: f for f in self.test_dir.rglob("*") if not f.is_dir() - and f.suffix not in [".c", ".h"] + and f.suffix not in [".c", ".h", ".md"] and f.name not in ASSEMBLY_LIBS ) diff --git a/test_framework/tacky/dead_store_elim.py b/test_framework/tacky/dead_store_elim.py index 67136d12..eb6e682f 100644 --- a/test_framework/tacky/dead_store_elim.py +++ b/test_framework/tacky/dead_store_elim.py @@ -18,7 +18,7 @@ class TestDeadStoreElimination(common.TackyOptimizationTest): Each dynamically generated test calls one of the following main test methods: * compile_and_run, defined in TestChapter: validate behavior but don't inspect assembly - * store_eliminated_test: make sure a particular mov instrucion was eliminated + * store_eliminated_test: make sure a particular mov instruction was eliminated * return_const_test: make sure entire funcion is reduce to a return instruction """ diff --git a/test_framework/test_tests/test_programs.py b/test_framework/test_tests/test_programs.py index 205d3049..6ea64238 100644 --- a/test_framework/test_tests/test_programs.py +++ b/test_framework/test_tests/test_programs.py @@ -121,7 +121,7 @@ def tearDown(self) -> None: garbage_files = ( f for f in basic.TEST_DIR.rglob("*") - if not f.is_dir() and f.suffix not in [".c", ".h", ".s"] + if not f.is_dir() and f.suffix not in [".c", ".h", ".s", ".md"] ) for junk in garbage_files: diff --git a/test_properties.json b/test_properties.json index 3ad70a88..9c9103bf 100644 --- a/test_properties.json +++ b/test_properties.json @@ -386,6 +386,14 @@ "chapter_18/valid/params_and_returns/return_struct_on_page_boundary.c": { "linux": "data_on_page_boundary_linux.s", "os_x": "data_on_page_boundary_osx.s" + }, + "chapter_18/valid/params_and_returns/return_big_struct_on_page_boundary.c": { + "linux": "big_data_on_page_boundary_linux.s", + "os_x": "big_data_on_page_boundary_osx.s" + }, + "chapter_18/valid/params_and_returns/return_space_overlap.c": { + "linux": "return_space_address_overlap_linux.s", + "os_x": "return_space_address_overlap_osx.s" } } } \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/array_of_structs.c b/tests/chapter_18/valid/no_structure_parameters/libraries/array_of_structs.c similarity index 61% rename from tests/chapter_18/valid/parameters/libraries/array_of_structs.c rename to tests/chapter_18/valid/no_structure_parameters/libraries/array_of_structs.c index 8d89fc10..651f4e10 100644 --- a/tests/chapter_18/valid/parameters/libraries/array_of_structs.c +++ b/tests/chapter_18/valid/no_structure_parameters/libraries/array_of_structs.c @@ -1,15 +1,17 @@ +/* Test that we can pass a pointer to an array of structures as a parameter */ + #include "array_of_structs.h" int validate_struct_array(struct outer *struct_array) { for (int i = 0; i < 3; i = i + 1) { if (struct_array[i].a != i * 2) - return i; + return 0; if (struct_array[i].b.l != i * 3) - return i * 10; + return 0; if (struct_array[i].b.arr[0] != i * 4) - return i * 25; + return 0; if (struct_array[i].b.arr[1] != i * 5) - return i * 11; + return 0; } - return 0; + return 1; // success } \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/array_of_structs.h b/tests/chapter_18/valid/no_structure_parameters/libraries/array_of_structs.h similarity index 76% rename from tests/chapter_18/valid/parameters/libraries/array_of_structs.h rename to tests/chapter_18/valid/no_structure_parameters/libraries/array_of_structs.h index fb20b6ef..33b3a915 100644 --- a/tests/chapter_18/valid/parameters/libraries/array_of_structs.h +++ b/tests/chapter_18/valid/no_structure_parameters/libraries/array_of_structs.h @@ -1,3 +1,5 @@ +/* Test that we can pass a pointer to an array of structures as a parameter */ + struct inner { long l; char arr[2]; diff --git a/tests/chapter_18/valid/no_structure_parameters/libraries/array_of_structs_client.c b/tests/chapter_18/valid/no_structure_parameters/libraries/array_of_structs_client.c new file mode 100644 index 00000000..35f1dea8 --- /dev/null +++ b/tests/chapter_18/valid/no_structure_parameters/libraries/array_of_structs_client.c @@ -0,0 +1,24 @@ +/* Test that we can pass a pointer to an array of structures as a parameter */ + +#include "array_of_structs.h" + +static struct outer static_array[3] = { + {0, {0, {0, 0}}}, {2, {3, {4, 5}}}, {4, {6, {8, 10}}}}; + +int main(void) { + struct outer auto_array[3] = { + {0, {0, {0, 0}}}, {2, {3, {4, 5}}}, {4, {6, {8, 10}}}}; + + // pass pointers to struct arrays with both static and automatic storage + // both have same contents so we can validate them with the same function + + if (!validate_struct_array(static_array)) { + return 1; + } + + if (!validate_struct_array(auto_array)) { + return 2; + } + + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_18/valid/no_structure_parameters/libraries/initializers/auto_struct_initializers.h b/tests/chapter_18/valid/no_structure_parameters/libraries/initializers/auto_struct_initializers.h index 6d747a1a..aa109f28 100644 --- a/tests/chapter_18/valid/no_structure_parameters/libraries/initializers/auto_struct_initializers.h +++ b/tests/chapter_18/valid/no_structure_parameters/libraries/initializers/auto_struct_initializers.h @@ -14,7 +14,7 @@ #endif #endif -// library functoins +// library functions int strcmp(char *s1, char *s2); void *malloc(unsigned long size); diff --git a/tests/chapter_18/valid/no_structure_parameters/libraries/opaque_struct.c b/tests/chapter_18/valid/no_structure_parameters/libraries/opaque_struct.c index feecd38b..da0bc8c2 100644 --- a/tests/chapter_18/valid/no_structure_parameters/libraries/opaque_struct.c +++ b/tests/chapter_18/valid/no_structure_parameters/libraries/opaque_struct.c @@ -10,7 +10,7 @@ #endif #endif -// library functoins +// library functions int strcmp(char *s1, char *s2); int puts(char *s); void *malloc(unsigned long size); diff --git a/tests/chapter_18/valid/no_structure_parameters/libraries/return_struct_pointer_client.c b/tests/chapter_18/valid/no_structure_parameters/libraries/return_struct_pointer_client.c index 51b859ee..140919fe 100644 --- a/tests/chapter_18/valid/no_structure_parameters/libraries/return_struct_pointer_client.c +++ b/tests/chapter_18/valid/no_structure_parameters/libraries/return_struct_pointer_client.c @@ -87,5 +87,9 @@ int main(void) { return 3; } + if (!test_update_nested_struct_thru_retval()) { + return 4; + } + return 0; } \ No newline at end of file diff --git a/tests/chapter_18/valid/no_structure_parameters/semantic_analysis/incomplete_structs.c b/tests/chapter_18/valid/no_structure_parameters/semantic_analysis/incomplete_structs.c index a8259438..cb4bfe31 100644 --- a/tests/chapter_18/valid/no_structure_parameters/semantic_analysis/incomplete_structs.c +++ b/tests/chapter_18/valid/no_structure_parameters/semantic_analysis/incomplete_structs.c @@ -18,8 +18,6 @@ int strcmp(char *s1, char *s2); // test 1: you can declare a function that accepts/returns incomplete struct // types we don't define or use this function, we just need to validate that // this declaration doesn't cause a compiler error -// TODO include test in appropriate folder where we define/call this after -// completing the type struct never_used; struct never_used incomplete_fun(struct never_used x); @@ -162,6 +160,7 @@ int test_use_incomplete_struct_pointers(void) { return 0; } + // can pass them as parameters if (use_struct_pointers(ptr3)) { return 0; } diff --git a/tests/chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c b/tests/chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c index 2023c76b..7a3fc7e1 100644 --- a/tests/chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c +++ b/tests/chapter_18/valid/no_structure_parameters/struct_copy/copy_struct_through_pointer.c @@ -119,9 +119,9 @@ int test_copy_array_element_with_padding(void) { struct with_end_padding arr[3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}; struct with_end_padding elem = {9, 9, 9}; arr[1] = elem; - if (arr[0].a == 0 && arr[0].b == 1 && arr[0].c == 2 && arr[1].a == 9 && - arr[1].b == 9 && arr[1].c == 9 && arr[2].a == 6 && arr[2].b == 7 && - arr[2].c == 8) { + if (arr[0].a != 0 || arr[0].b != 1 || arr[0].c != 2 || arr[1].a != 9 || + arr[1].b != 9 || arr[1].c != 9 || arr[2].a != 6 || arr[2].b != 7 || + arr[2].c != 8) { return 0; } diff --git a/tests/chapter_18/valid/parameters/data_on_page_boundary_linux.s b/tests/chapter_18/valid/parameters/data_on_page_boundary_linux.s index 8ec5f622..c72326f7 100644 --- a/tests/chapter_18/valid/parameters/data_on_page_boundary_linux.s +++ b/tests/chapter_18/valid/parameters/data_on_page_boundary_linux.s @@ -1,7 +1,7 @@ - .bss - .align 4096 - .zero 4085 + .bss # .bss is the last segment in the program image - the page after it will be unampped + .align 4096 # force page alignment + .zero 4085 # write a bunch of zeros so on_page_boundary is at the end of the page .globl on_page_boundary on_page_boundary: - .zero 9 + .zero 11 .section ".note.GNU-stack","",@progbits diff --git a/tests/chapter_18/valid/parameters/data_on_page_boundary_osx.s b/tests/chapter_18/valid/parameters/data_on_page_boundary_osx.s index 1bff28f1..6d86ab5a 100644 --- a/tests/chapter_18/valid/parameters/data_on_page_boundary_osx.s +++ b/tests/chapter_18/valid/parameters/data_on_page_boundary_osx.s @@ -1,6 +1,6 @@ - .bss - .align 12 - .zero 4085 + .bss # .bss is the last segment in the program image - the page after it will be unampped + .align 12 # force page alignment (2^12 == 4096) + .zero 4085 # write a bunch of zeros so on_page_boundary is at the end of the page .globl _on_page_boundary _on_page_boundary: - .zero 9 + .zero 11 diff --git a/tests/chapter_18/valid/parameters/incomplete_param_type.c b/tests/chapter_18/valid/parameters/incomplete_param_type.c index 672ff4a0..8149c6a8 100644 --- a/tests/chapter_18/valid/parameters/incomplete_param_type.c +++ b/tests/chapter_18/valid/parameters/incomplete_param_type.c @@ -1,7 +1,12 @@ +/* Test that we can declare a function with an incomplete parameter type, + * then call/define it after the type is completed */ struct s; +// struct s is incomplete here, so we can declare this function +// but not define it int foo(struct s blah); +// complete the type struct s { int a; int b; @@ -9,7 +14,7 @@ struct s { int main(void) { struct s arg = {1, 2}; - return foo(arg); + return foo(arg); // we can call foo b/c 'struct s' type is completed } int foo(struct s blah) { diff --git a/tests/chapter_18/valid/parameters/libraries/array_of_structs_client.c b/tests/chapter_18/valid/parameters/libraries/array_of_structs_client.c deleted file mode 100644 index bb71a27f..00000000 --- a/tests/chapter_18/valid/parameters/libraries/array_of_structs_client.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "array_of_structs.h" - -static struct outer static_array[3] = { - {0, {0, {0, 0}}}, {2, {3, {4, 5}}}, {4, {6, {8, 10}}}}; - -int main(void) { - struct outer auto_array[3] = { - {0, {0, {0, 0}}}, {2, {3, {4, 5}}}, {4, {6, {8, 10}}}}; - - int static_result = validate_struct_array(static_array); - if (static_result) - return static_result + 3; - return validate_struct_array(auto_array); -} \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/classify_params.c b/tests/chapter_18/valid/parameters/libraries/classify_params.c new file mode 100644 index 00000000..424e2679 --- /dev/null +++ b/tests/chapter_18/valid/parameters/libraries/classify_params.c @@ -0,0 +1,62 @@ +/* Test that we classify structure parameters correctly, + * by passing a variety of structures as arguments. + * Each test function takes only one argument. + * */ + +#include "classify_params.h" + +int test_twelve_bytes(struct twelve_bytes s) { + if (s.i != 0 || strcmp(s.arr, "lmnopqr")) { + return 0; + } + return 1; // success +} +int test_nested_ints(struct nested_ints s) { + if (s.ch1 != 127 || s.nested.i != 2147483647 || s.nested.ch2 != -128) { + return 0; + } + return 1; // success +} +int test_flattened_ints(struct flattened_ints s) { + if (s.c != 127 || s.i != 2147483647 || s.a != -128) { + return 0; + } + + return 1; // success +} +int test_large(struct large s) { + if (s.i != 200000 || s.d != 23.25 || strcmp(s.arr, "abcdefghi")) { + return 0; + } + + return 1; // success +} +int test_two_ints(struct two_ints s) { + if (s.i != 999 || s.i2 != 888) { + return 0; + } + + return 1; // success +} +int test_nested_double(struct nested_double s) { + if (s.array[0] != 25.125e3) { + return 0; + } + + return 1; // success +} +int test_two_eightbytes(struct two_eightbytes s) { + if (s.d != 1000. || s.c != 'x') { + return 0; + } + + return 1; // success +} +int test_pass_in_memory(struct pass_in_memory s) { + if (s.w != 1.7e308 || s.x != -1.7e308 || s.y != -2147483647 || + s.z != -9223372036854775807l) { + return 0; + } + + return 1; // success +} \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/classify_params.h b/tests/chapter_18/valid/parameters/libraries/classify_params.h new file mode 100644 index 00000000..69d17448 --- /dev/null +++ b/tests/chapter_18/valid/parameters/libraries/classify_params.h @@ -0,0 +1,78 @@ +/* Test that we classify structure parameters correctly, + * by passing a variety of structures as arguments. + * Each test function takes only one argument. + * */ + +#ifdef SUPPRESS_WARNINGS +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" +#else +#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" +#endif +#endif + +int strcmp(char *s1, char *s2); + +// from Listing 18-39 +struct twelve_bytes { + int i; + char arr[8]; +}; // two INTEGER eightbytes + +// from Listing 18-40 +struct inner { + int i; + char ch2; +}; + +struct nested_ints { + char ch1; + struct inner nested; +}; // two INTEGER eightbytes + +// from Listing 18-41 +struct flattened_ints { + char c; + int i; + char a; +}; // two INTEGER eightbytes + +// From uncaptioned listing in "Classifying Eightbytes" section +struct large { + int i; + double d; + char arr[10]; +}; // four MEMORY eightbytes + +// Three structure declarations from Listing 18-42 +struct two_ints { + int i; + int i2; +}; // one INTEGER eightbyte + +struct nested_double { + double array[1]; +}; // one SSE eightbyte + +struct two_eightbytes { + double d; + char c; +}; // one SSE eightbyte, one INTEGER eightbyte + +// From Listing 18-47 +struct pass_in_memory { + double w; + double x; + int y; + long z; +}; // four MEMORY eightbytes + +// validation functions defined in library +int test_twelve_bytes(struct twelve_bytes s); +int test_nested_ints(struct nested_ints s); +int test_flattened_ints(struct flattened_ints s); +int test_large(struct large s); +int test_two_ints(struct two_ints s); +int test_nested_double(struct nested_double s); +int test_two_eightbytes(struct two_eightbytes s); +int test_pass_in_memory(struct pass_in_memory s); \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/classify_params_client.c b/tests/chapter_18/valid/parameters/libraries/classify_params_client.c new file mode 100644 index 00000000..89f1444f --- /dev/null +++ b/tests/chapter_18/valid/parameters/libraries/classify_params_client.c @@ -0,0 +1,50 @@ +/* Test that we classify structure parameters correctly, + * by passing a variety of structures as arguments. + * Each test function takes only one argument. + * */ + +#include "classify_params.h" + +int main(void) { + struct twelve_bytes s1 = {0, "lmnopqr"}; + if (!test_twelve_bytes(s1)) { + return 1; + } + + struct nested_ints s2 = {127, {2147483647, -128}}; + if (!test_nested_ints(s2)) { + return 2; + } + + struct flattened_ints s3 = {127, 2147483647, -128}; + if (!test_flattened_ints(s3)) { + return 3; + } + + struct large s4 = {200000, 23.25, "abcdefghi"}; + if (!test_large(s4)) { + return 4; + } + + struct two_ints s5 = {999, 888}; + if (!test_two_ints(s5)) { + return 5; + } + + struct nested_double s6 = {{25.125e3}}; + if (!test_nested_double(s6)) { + return 6; + } + + struct two_eightbytes s7 = {1000., 'x'}; + if (!test_two_eightbytes(s7)) { + return 7; + } + + struct pass_in_memory s8 = {1.7e308, -1.7e308, -2147483647, -9223372036854775807l}; + if (!test_pass_in_memory(s8)) { + return 8; + } + + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/modify_param.c b/tests/chapter_18/valid/parameters/libraries/modify_param.c new file mode 100644 index 00000000..91f983cf --- /dev/null +++ b/tests/chapter_18/valid/parameters/libraries/modify_param.c @@ -0,0 +1,49 @@ +/* Modify a parameter of structure type + * */ + +#include "modify_param.h" + +int modify_simple_struct(struct inner s) { + // copy it + struct inner copy = s; + + // modify it + s.d = 0.0; + + // check its value + if (s.d || s.i != 3) { + return 0; + } + + // check value of copy + if (copy.d != 2.0 || copy.i != 3) { + return 0; + } + + return 1; // success +} + +int modify_nested_struct(struct outer s) { + // copy it + struct outer copy = s; + + // modify it + s.l = 10; + s.s.i = 200; + s.ptr->d = 10.0; + s.ptr->i = 11; + + // check its value + if (s.s.i != 200 || s.s.d != 4.0 || s.l != 10 || s.ptr->d != 10.0 || + s.ptr->i != 11) { + return 0; + } + + // check value of copy + if (copy.s.i != 5 || copy.s.d != 4.0 || copy.l != 1000 || + copy.ptr->d != 10.0 || copy.ptr->i != 11) { + return 0; + } + + return 1; // success +} \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/modify_param.h b/tests/chapter_18/valid/parameters/libraries/modify_param.h new file mode 100644 index 00000000..f246ba32 --- /dev/null +++ b/tests/chapter_18/valid/parameters/libraries/modify_param.h @@ -0,0 +1,16 @@ +/* Modify a parameter of structure type + * */ + +struct inner { + double d; + int i; +}; + +struct outer { + struct inner s; + struct inner *ptr; + long l; +}; + +int modify_simple_struct(struct inner s); +int modify_nested_struct(struct outer s); \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/modify_param_client.c b/tests/chapter_18/valid/parameters/libraries/modify_param_client.c new file mode 100644 index 00000000..079a1024 --- /dev/null +++ b/tests/chapter_18/valid/parameters/libraries/modify_param_client.c @@ -0,0 +1,36 @@ +/* Modify a parameter of structure type + * */ +#include "modify_param.h" + +int main(void) { + struct inner s_inner = {2.0, 3}; + if (!modify_simple_struct(s_inner)) { + return 1; + } + // make sure changing parameter didn't change value in the caller + if (s_inner.d != 2.0 || s_inner.i != 3) { + return 2; + } + + // now try a nested one + struct outer s_o = {{4.0, 5}, &s_inner, 1000l}; + if (!modify_nested_struct(s_o)) { + return 3; + } + // values of most members in s_o shouldn't have changed, + // except for members in s_o->ptr, which points to s_inner + if (s_o.s.d != 4.0 || s_o.s.i != 5 || s_o.l != 1000l) { + return 4; + } + + if (s_o.ptr != &s_inner) { + return 5; + } + + // elements in s_o.ptr were modified + if (s_o.ptr->d != 10.0 || s_o.ptr->i != 11) { + return 6; + } + + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/param_calling_conventions.c b/tests/chapter_18/valid/parameters/libraries/param_calling_conventions.c index 94a05212..79d21d9e 100644 --- a/tests/chapter_18/valid/parameters/libraries/param_calling_conventions.c +++ b/tests/chapter_18/valid/parameters/libraries/param_calling_conventions.c @@ -1,124 +1,179 @@ +/* Test that we can pass a mix of struct and non-struct arguments according to + * the ABI */ + #include "param_calling_conventions.h" +// all arguments fit in registers int pass_small_structs(struct two_xmm two_xmm_struct, struct one_int int_struct, struct one_xmm xmm_struct, struct xmm_and_int mixed_struct, struct twelve_bytes int_struct_2, struct one_int_exactly another_int_struct) { if (two_xmm_struct.d[0] != 55.5 || two_xmm_struct.d[1] != 44.4) - return 1; + return 0; if (int_struct.c != 'c' || int_struct.i != 54320) - return 2; + return 0; if (xmm_struct.d != 5.125) - return 3; + return 0; if (strcmp(mixed_struct.c, "hi") || mixed_struct.dbl.d != 1.234) - return 4; + return 0; if (strcmp(int_struct_2.arr, "string!") || int_struct_2.i != 123) - return 5; + return 0; if (another_int_struct.l != 567890) - return 6; + return 0; + + return 1; // success +} + +// based on example in Listing 18-45 +int a_bunch_of_arguments(int i0, int i1, int i2, int i3, int i4, + struct two_longs param, int i5) { + if (i0 != 0 || i1 != 1 || i2 != 2 || i3 != 3 || i4 != 4 || i5 != 5) { + return 0; + } + + if (param.a != 1234567l || param.b != 89101112l) { + return 0; + } - return 0; + return 1; // success } +// use remaining structure types, mix with scalars int structs_and_scalars(long l, double d, struct odd_size os, struct memory mem, struct one_xmm xmm_struct) { if (l != 10) - return 7; + return 0; if (d != 10.0) - return 8; + return 0; if (strcmp(os.arr, "lmno")) - return 9; + return 0; if (strcmp(mem.c, "rs") || mem.d != 15.75 || mem.i != 3333 || mem.l != 4444) - return 10; + return 0; if (xmm_struct.d != 5.125) - return 11; + return 0; - return 0; + return 1; // success } +// pass fourth_struct in memory b/c we're out of XMM registers int struct_in_mem(double a, double b, double c, struct xmm_and_int first_struct, double d, struct two_xmm second_struct, long l, struct int_and_xmm third_struct, struct one_xmm fourth_struct) { if (a != 10.0 || b != 11.125 || c != 12.0) - return 12; + return 0; if (strcmp(first_struct.c, "hi") || first_struct.dbl.d != 1.234) - return 13; + return 0; if (d != 13.0) - return 14; + return 0; if (second_struct.d[0] != 55.5 || second_struct.d[1] != 44.4) - return 15; + return 0; if (l) - return 16; + return 0; if (third_struct.c != 'p' || third_struct.d != 4.56) - return 17; + return 0; if (fourth_struct.d != 5.125) - return 18; + return 0; - return 0; + return 1; // success } +// pass two_ints_nested in memory - we have one general-purpose reg left for +// parameter passing but it requires two int pass_borderline_struct_in_memory(struct two_ints t_i, char c, struct int_and_xmm i_x, void *ptr, struct two_ints_nested t_i_n, double d) { if (t_i.c != '_' || t_i.arr[0] != 5 || t_i.arr[1] != 6 || t_i.arr[2] != 7) - return 19; + return 0; if (c != '!') - return 20; + return 0; if (i_x.c != 'p' || i_x.d != 4.56) - return 21; + return 0; if (ptr) - return 22; + return 0; if (t_i_n.a.c != 'c' || t_i_n.a.i != 54320) - return 23; + return 0; if (t_i_n.b.c != 'c' || t_i_n.b.i != 54320) - return 24; + return 0; if (d != 7.8) - return 25; - return 0; + return 0; + return 1; // success } +// pass a struct in memory that isn't neatly divisible by 8 int pass_uneven_struct_in_mem(struct twelve_bytes struct1, long a, long b, struct twelve_bytes struct2, struct odd_size os, struct memory m) { if (struct1.i != -1) { - return 26; + return 0; } if (struct1.arr[0] != 127 || struct1.arr[1] != 126 || struct1.arr[2] != 125) { - return 27; + return 0; } if (a != 9223372036854775805l || b != 9223372036854775800l) { - return 28; + return 0; } if (struct2.i != -5) { - return 29; + return 0; } if (struct2.arr[0] != 100 || struct2.arr[1] != 101 || struct2.arr[2] != 102) { - return 30; + return 0; } for (int i = 0; i < 5; i = i + 1) { if (os.arr[i] != 100 - i) { - return 31; + return 0; } } if (m.d != 5.345) { - return 32; + return 0; + } + if (m.c[0] != -1 || m.c[1] != -2 || m.c[2] != -3) { + return 0; + } + if (m.l != 4294967300l) { + return 0; + } + if (m.i != 10000) { + return 0; + } + return 1; // success +} + +int pass_later_structs_in_regs(struct memory m, struct twelve_bytes struct1, + struct one_xmm struct2) { + if (m.d != 5.345) { + return 0; } + if (m.c[0] != -1 || m.c[1] != -2 || m.c[2] != -3) { - return 33; + return 0; } + if (m.l != 4294967300l) { - return 34; + return 0; } + if (m.i != 10000) { - return 35; + return 0; + } + + if (struct1.i != -1) { + return 0; + } + if (struct1.arr[0] != 127 || struct1.arr[1] != 126 || + struct1.arr[2] != 125) { + return 0; + } + + if (struct2.d != 5.125) { + return 0; } - return 0; + return 1; // success } \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/param_calling_conventions.h b/tests/chapter_18/valid/parameters/libraries/param_calling_conventions.h index 3e16795f..5d5c02b1 100644 --- a/tests/chapter_18/valid/parameters/libraries/param_calling_conventions.h +++ b/tests/chapter_18/valid/parameters/libraries/param_calling_conventions.h @@ -1,3 +1,6 @@ +/* Test that we can pass a mix of struct and non-struct arguments according to + * the ABI */ + #ifdef SUPPRESS_WARNINGS #ifdef __clang__ #pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" @@ -9,6 +12,12 @@ int strcmp(char *s1, char *s2); int strncmp(char *s1, char *s2, unsigned long n); +// This type comes from Listing 18-45 +struct two_longs { + long a; + long b; +}; + struct one_int { int i; char c; @@ -71,16 +80,22 @@ int pass_small_structs(struct two_xmm two_xmm_struct, struct one_int int_struct, struct twelve_bytes int_struct_2, struct one_int_exactly another_int_struct); +// based on example in Listing 18-45 +int a_bunch_of_arguments(int i0, int i1, int i2, int i3, int i4, + struct two_longs param, int i5); + // use remaining structure types, mix with scalars int structs_and_scalars(long l, double d, struct odd_size os, struct memory mem, struct one_xmm xmm_struct); -// pass a structure in memory b/c we're out of registers +// pass fourth_struct in memory b/c we're out of XMM registers int struct_in_mem(double a, double b, double c, struct xmm_and_int first_struct, double d, struct two_xmm second_struct, long l, struct int_and_xmm third_struct, struct one_xmm fourth_struct); -// pass two_ints_nested in memory b/c can't fit both eightbytes in quadword + +// pass two_ints_nested in memory - we have one general-purpose reg left for +// parameter passing but it requires two int pass_borderline_struct_in_memory(struct two_ints t_i, char c, struct int_and_xmm i_x, void *ptr, struct two_ints_nested t_i_n, double d); @@ -88,4 +103,7 @@ int pass_borderline_struct_in_memory(struct two_ints t_i, char c, // pass a struct in memory that isn't neatly divisible by 8 int pass_uneven_struct_in_mem(struct twelve_bytes struct1, long a, long b, struct twelve_bytes struct2, struct odd_size os, - struct memory m); \ No newline at end of file + struct memory m); + +// pass first struct in memory, later structs in registers +int pass_later_structs_in_regs(struct memory m, struct twelve_bytes struct1, struct one_xmm struct2); \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/param_calling_conventions_client.c b/tests/chapter_18/valid/parameters/libraries/param_calling_conventions_client.c index de42f670..88999ed9 100644 --- a/tests/chapter_18/valid/parameters/libraries/param_calling_conventions_client.c +++ b/tests/chapter_18/valid/parameters/libraries/param_calling_conventions_client.c @@ -1,6 +1,11 @@ +/* Test that we can pass a mix of struct and non-struct arguments according to + * the ABI */ + #include "param_calling_conventions.h" int main(void) { + // define a bunch of structures + struct two_longs two_longs = {1234567l, 89101112l}; struct one_int one_int = {54320, 'c'}; struct one_int_exactly one_long = {567890l}; struct two_ints two_ints = {'_', {5, 6, 7}}; @@ -15,40 +20,44 @@ int main(void) { struct odd_size odd = {"lmno"}; struct memory mem = {15.75, "rs", 4444, 3333}; - int retval; - - // test parameter passing + // call validation functions - retval = pass_small_structs(two_xmm, one_int, one_xmm, xmm_and_int, xii, - one_long); - if (retval) { - return retval; + if (!pass_small_structs(two_xmm, one_int, one_xmm, xmm_and_int, xii, + one_long)) { + return 1; } - retval = structs_and_scalars(10, 10.0, odd, mem, one_xmm); - if (retval) { - return retval; + // based on example in Listing 18-45 + if (!a_bunch_of_arguments(0, 1, 2, 3, 4, two_longs, 5)) { + return 2; } - retval = struct_in_mem(10.0, 11.125, 12.0, xmm_and_int, 13.0, two_xmm, 0, - int_and_xmm, one_xmm); - if (retval) - return retval; + if (!structs_and_scalars(10, 10.0, odd, mem, one_xmm)) { + return 2; + } - retval = pass_borderline_struct_in_memory(two_ints, '!', int_and_xmm, 0, - two_ints_nested, 7.8); - if (retval) - return retval; + if (!struct_in_mem(10.0, 11.125, 12.0, xmm_and_int, 13.0, two_xmm, 0, + int_and_xmm, one_xmm)) { + return 3; + } + if (!pass_borderline_struct_in_memory(two_ints, '!', int_and_xmm, 0, + two_ints_nested, 7.8)) { + return 4; + } + // define some more structs to use in last two test cases struct twelve_bytes struct1 = {-1, {127, 126, 125}}; struct twelve_bytes struct2 = {-5, {100, 101, 102}}; struct odd_size os = {{100, 99, 98, 97, 96}}; struct memory m = {5.345, {-1, -2, -3}, 4294967300l, 10000}; - retval = pass_uneven_struct_in_mem(struct1, 9223372036854775805l, - 9223372036854775800l, struct2, os, m); + if (!pass_uneven_struct_in_mem(struct1, 9223372036854775805l, + 9223372036854775800l, struct2, os, m)) { + return 5; + } - if (retval) - return retval; + if (!pass_later_structs_in_regs(m, struct1, one_xmm)) { + return 6; + } // success! return 0; diff --git a/tests/chapter_18/valid/parameters/libraries/pass_struct.c b/tests/chapter_18/valid/parameters/libraries/pass_struct.c index 45cd02e9..2e06ffa2 100644 --- a/tests/chapter_18/valid/parameters/libraries/pass_struct.c +++ b/tests/chapter_18/valid/parameters/libraries/pass_struct.c @@ -1,8 +1,13 @@ -struct pair { - int x; - int y; -}; +/* Basic test of passing an argument of structure type: similar to chapter_18/valid/parameters/simple.c + * but split into two translation units + * */ -int foo(struct pair p) { - return p.x + 1; +#include "pass_struct.h" + +int validate_struct_param(struct pair p) { + if (p.x != 1 || p.y != 2) { + return 0; + } + + return 1; // success } \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/pass_struct.h b/tests/chapter_18/valid/parameters/libraries/pass_struct.h new file mode 100644 index 00000000..e8602c3e --- /dev/null +++ b/tests/chapter_18/valid/parameters/libraries/pass_struct.h @@ -0,0 +1,9 @@ +/* Basic test of passing an argument of structure type: similar to chapter_18/valid/parameters/simple.c + * but split into two translation units + * */ +struct pair { + int x; + int y; +}; + +int validate_struct_param(struct pair p); \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/pass_struct_client.c b/tests/chapter_18/valid/parameters/libraries/pass_struct_client.c index 0520e8f0..de9da13d 100644 --- a/tests/chapter_18/valid/parameters/libraries/pass_struct_client.c +++ b/tests/chapter_18/valid/parameters/libraries/pass_struct_client.c @@ -1,11 +1,13 @@ -struct pair { - int x; - int y; -}; +/* Basic test of passing an argument of structure type: similar to chapter_18/valid/parameters/simple.c + * but split into two translation units + * */ -int foo(struct pair p); +#include "pass_struct.h" int main(void) { struct pair arg = {1, 2}; - return foo(arg); + if (!validate_struct_param(arg)) { + return 1; + } + return 0; // success } \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/preserve_stack.c b/tests/chapter_18/valid/parameters/libraries/preserve_stack.c deleted file mode 100644 index f45d196b..00000000 --- a/tests/chapter_18/valid/parameters/libraries/preserve_stack.c +++ /dev/null @@ -1,20 +0,0 @@ -struct my_struct { - char arr[7]; -}; - -static struct my_struct internal; - -void process_struct(struct my_struct arg) { - internal = arg; -} - -int check_struct(void) { - if (internal.arr[0] || internal.arr[1] || internal.arr[2]) { - return 1; - } - if (internal.arr[3] != 1 || internal.arr[4] != 2 || internal.arr[5] != 3 || - internal.arr[6] != 4) { - return 1; - } - return 0; -} \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/preserve_stack_client.c b/tests/chapter_18/valid/parameters/libraries/preserve_stack_client.c deleted file mode 100644 index a2e6d3e8..00000000 --- a/tests/chapter_18/valid/parameters/libraries/preserve_stack_client.c +++ /dev/null @@ -1,34 +0,0 @@ -// Make sure that when we copy values into the red zone during arg passing, we -// don't accidentally clobber the actual stack; this is a regression test for a -// bug in found in NQCC - copied into 0(rsp) instead of -8(rsp) - -struct my_struct { - char arr[7]; -}; - -long glob = 0; - -struct my_struct s = {{0, 0, 0, 1, 2, 3, 4}}; - -void process_struct(struct my_struct arg); -int check_struct( - void); // return 0 if static struct in lib is as expected, 1 otherwise - -long f(void) { - // can we find a less fragile test for this? assembly again? - long x = glob - 2l; // x should be at 0(%rsp) - process_struct(s); // we copy s into red zone and then into RDI - return x; // return X, make sure it wasn't overwritten -} - -int main(void) { - if (f() != -2) { - return 1; - } - - if (check_struct()) { - return 2; - } - - return 0; -} \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/libraries/struct_sizes.c b/tests/chapter_18/valid/parameters/libraries/struct_sizes.c index 64c4007e..18a6115b 100644 --- a/tests/chapter_18/valid/parameters/libraries/struct_sizes.c +++ b/tests/chapter_18/valid/parameters/libraries/struct_sizes.c @@ -1,7 +1,11 @@ +/* Test that we can pass static and automatic structs of every size between 1 and 24 bytes. + * Pass each size both in a register (when possible) and on the stack. */ + #include "struct_sizes.h" int memcmp(void *s1, void *s2, unsigned long n); +// Pass sizes 1 - 6 in registers, remainders on the stack int fun0(struct bytesize1 a, struct bytesize2 b, struct bytesize3 c, struct bytesize4 d, struct bytesize5 e, struct bytesize6 f, struct bytesize7 g, struct bytesize8 h, struct bytesize9 i, @@ -23,103 +27,105 @@ int fun0(struct bytesize1 a, struct bytesize2 b, struct bytesize3 c, unsigned char *u_expected, unsigned char *v_expected, unsigned char *w_expected, unsigned char *x_expected) { if (memcmp(&a, a_expected, sizeof a)) { - return 1; + return 0; } if (memcmp(&b, b_expected, sizeof b)) { - return 1; + return 0; } if (memcmp(&c, c_expected, sizeof c)) { - return 1; + return 0; } if (memcmp(&d, d_expected, sizeof d)) { - return 1; + return 0; } if (memcmp(&e, e_expected, sizeof e)) { - return 1; + return 0; } if (memcmp(&f, f_expected, sizeof f)) { - return 1; + return 0; } if (memcmp(&g, g_expected, sizeof g)) { - return 1; + return 0; } if (memcmp(&h, h_expected, sizeof h)) { - return 1; + return 0; } if (memcmp(&i, i_expected, sizeof i)) { - return 1; + return 0; } if (memcmp(&j, j_expected, sizeof j)) { - return 1; + return 0; } if (memcmp(&k, k_expected, sizeof k)) { - return 1; + return 0; } if (memcmp(&l, l_expected, sizeof l)) { - return 1; + return 0; } if (memcmp(&m, m_expected, sizeof m)) { - return 1; + return 0; } if (memcmp(&n, n_expected, sizeof n)) { - return 1; + return 0; } if (memcmp(&o, o_expected, sizeof o)) { - return 1; + return 0; } if (memcmp(&p, p_expected, sizeof p)) { - return 1; + return 0; } if (memcmp(&q, q_expected, sizeof q)) { - return 1; + return 0; } if (memcmp(&r, r_expected, sizeof r)) { - return 1; + return 0; } if (memcmp(&s, s_expected, sizeof s)) { - return 1; + return 0; } if (memcmp(&t, t_expected, sizeof t)) { - return 1; + return 0; } if (memcmp(&u, u_expected, sizeof u)) { - return 1; + return 0; } if (memcmp(&v, v_expected, sizeof v)) { - return 1; + return 0; } if (memcmp(&w, w_expected, sizeof w)) { - return 1; + return 0; } if (memcmp(&x, x_expected, sizeof x)) { - return 1; + return 0; } - return 0; + return 1; // success } + +// Pass sizes 7-10 bytes in regs, 1-6 on the stack int fun1(struct bytesize7 a, struct bytesize8 b, struct bytesize9 c, struct bytesize10 d, struct bytesize1 e, struct bytesize2 f, struct bytesize3 g, struct bytesize4 h, struct bytesize5 i, @@ -130,156 +136,92 @@ int fun1(struct bytesize7 a, struct bytesize8 b, struct bytesize9 c, unsigned char *h_expected, unsigned char *i_expected, unsigned char *j_expected) { if (memcmp(&a, a_expected, sizeof a)) { - return 1; + return 0; } if (memcmp(&b, b_expected, sizeof b)) { - return 1; + return 0; } if (memcmp(&c, c_expected, sizeof c)) { - return 1; + return 0; } if (memcmp(&d, d_expected, sizeof d)) { - return 1; + return 0; } if (memcmp(&e, e_expected, sizeof e)) { - return 1; + return 0; } if (memcmp(&f, f_expected, sizeof f)) { - return 1; + return 0; } if (memcmp(&g, g_expected, sizeof g)) { - return 1; + return 0; } if (memcmp(&h, h_expected, sizeof h)) { - return 1; + return 0; } if (memcmp(&i, i_expected, sizeof i)) { - return 1; + return 0; } if (memcmp(&j, j_expected, sizeof j)) { - return 1; + return 0; } - return 0; + return 1; // success } + +// Pass sizes 11-13 in regs, 1 on the stack int fun2(struct bytesize11 a, struct bytesize12 b, struct bytesize13 c, struct bytesize1 d, unsigned char *a_expected, unsigned char *b_expected, unsigned char *c_expected, unsigned char *d_expected) { if (memcmp(&a, a_expected, sizeof a)) { - return 1; + return 0; } if (memcmp(&b, b_expected, sizeof b)) { - return 1; + return 0; } if (memcmp(&c, c_expected, sizeof c)) { - return 1; + return 0; } if (memcmp(&d, d_expected, sizeof d)) { - return 1; + return 0; } - return 0; + return 1; // success } + +// pass sizes 14-16 in regs, 2 on the stack int fun3(struct bytesize14 a, struct bytesize15 b, struct bytesize16 c, struct bytesize2 d, unsigned char *a_expected, unsigned char *b_expected, unsigned char *c_expected, unsigned char *d_expected) { if (memcmp(&a, a_expected, sizeof a)) { - return 1; + return 0; } if (memcmp(&b, b_expected, sizeof b)) { - return 1; + return 0; } if (memcmp(&c, c_expected, sizeof c)) { - return 1; + return 0; } if (memcmp(&d, d_expected, sizeof d)) { - return 1; - } - - return 0; -} -int fun4(struct bytesize17 a, struct bytesize18 b, struct bytesize3 c, - unsigned char *a_expected, unsigned char *b_expected, - unsigned char *c_expected) { - if (memcmp(&a, a_expected, sizeof a)) { - return 1; - } - - if (memcmp(&b, b_expected, sizeof b)) { - return 1; - } - - if (memcmp(&c, c_expected, sizeof c)) { - return 1; - } - - return 0; -} -int fun5(struct bytesize19 a, struct bytesize20 b, struct bytesize4 c, - unsigned char *a_expected, unsigned char *b_expected, - unsigned char *c_expected) { - if (memcmp(&a, a_expected, sizeof a)) { - return 1; - } - - if (memcmp(&b, b_expected, sizeof b)) { - return 1; - } - - if (memcmp(&c, c_expected, sizeof c)) { - return 1; - } - - return 0; -} -int fun6(struct bytesize21 a, struct bytesize22 b, struct bytesize5 c, - unsigned char *a_expected, unsigned char *b_expected, - unsigned char *c_expected) { - if (memcmp(&a, a_expected, sizeof a)) { - return 1; - } - - if (memcmp(&b, b_expected, sizeof b)) { - return 1; - } - - if (memcmp(&c, c_expected, sizeof c)) { - return 1; - } - - return 0; -} -int fun7(struct bytesize23 a, struct bytesize24 b, struct bytesize4 c, - unsigned char *a_expected, unsigned char *b_expected, - unsigned char *c_expected) { - if (memcmp(&a, a_expected, sizeof a)) { - return 1; - } - - if (memcmp(&b, b_expected, sizeof b)) { - return 1; - } - - if (memcmp(&c, c_expected, sizeof c)) { - return 1; + return 0; } - return 0; + return 1; // success } diff --git a/tests/chapter_18/valid/parameters/libraries/struct_sizes.h b/tests/chapter_18/valid/parameters/libraries/struct_sizes.h index 60e4c5e6..639c354b 100644 --- a/tests/chapter_18/valid/parameters/libraries/struct_sizes.h +++ b/tests/chapter_18/valid/parameters/libraries/struct_sizes.h @@ -1,3 +1,6 @@ +/* Test that we can pass static and automatic structs of every size between 1 and 24 bytes. + * Pass each size both in a register (when possible) and on the stack. */ + #ifdef SUPPRESS_WARNINGS #ifdef __clang__ #pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" @@ -149,6 +152,8 @@ struct bytesize24 { }; extern struct bytesize24 globvar_24; + +// Pass sizes 1 - 6 in registers, remainders on the stack int fun0(struct bytesize1 a, struct bytesize2 b, struct bytesize3 c, struct bytesize4 d, struct bytesize5 e, struct bytesize6 f, struct bytesize7 g, struct bytesize8 h, struct bytesize9 i, @@ -169,6 +174,8 @@ int fun0(struct bytesize1 a, struct bytesize2 b, struct bytesize3 c, unsigned char *s_expected, unsigned char *t_expected, unsigned char *u_expected, unsigned char *v_expected, unsigned char *w_expected, unsigned char *x_expected); + +// Pass sizes 7-10 bytes in regs, 1-6 on the stack int fun1(struct bytesize7 a, struct bytesize8 b, struct bytesize9 c, struct bytesize10 d, struct bytesize1 e, struct bytesize2 f, struct bytesize3 g, struct bytesize4 h, struct bytesize5 i, @@ -178,23 +185,15 @@ int fun1(struct bytesize7 a, struct bytesize8 b, struct bytesize9 c, unsigned char *f_expected, unsigned char *g_expected, unsigned char *h_expected, unsigned char *i_expected, unsigned char *j_expected); + +// Pass sizes 11-13 in regs, 1 on the stack int fun2(struct bytesize11 a, struct bytesize12 b, struct bytesize13 c, struct bytesize1 d, unsigned char *a_expected, unsigned char *b_expected, unsigned char *c_expected, unsigned char *d_expected); + +// pass sizes 14-16 in regs, 2 on the stack int fun3(struct bytesize14 a, struct bytesize15 b, struct bytesize16 c, struct bytesize2 d, unsigned char *a_expected, unsigned char *b_expected, unsigned char *c_expected, unsigned char *d_expected); -int fun4(struct bytesize17 a, struct bytesize18 b, struct bytesize3 c, - unsigned char *a_expected, unsigned char *b_expected, - unsigned char *c_expected); -int fun5(struct bytesize19 a, struct bytesize20 b, struct bytesize4 c, - unsigned char *a_expected, unsigned char *b_expected, - unsigned char *c_expected); -int fun6(struct bytesize21 a, struct bytesize22 b, struct bytesize5 c, - unsigned char *a_expected, unsigned char *b_expected, - unsigned char *c_expected); -int fun7(struct bytesize23 a, struct bytesize24 b, struct bytesize4 c, - unsigned char *a_expected, unsigned char *b_expected, - unsigned char *c_expected); diff --git a/tests/chapter_18/valid/parameters/libraries/struct_sizes_client.c b/tests/chapter_18/valid/parameters/libraries/struct_sizes_client.c index bd4cc714..c9837921 100644 --- a/tests/chapter_18/valid/parameters/libraries/struct_sizes_client.c +++ b/tests/chapter_18/valid/parameters/libraries/struct_sizes_client.c @@ -1,8 +1,11 @@ - +/* Test that we can pass static and automatic structs of every size between 1 and 24 bytes. + * Pass each size both in a register (when possible) and on the stack. */ #include "struct_sizes.h" int main(void) { - if (fun0(globvar_1, globvar_2, globvar_3, globvar_4, globvar_5, globvar_6, + + // pass global variables of each size + if (!fun0(globvar_1, globvar_2, globvar_3, globvar_4, globvar_5, globvar_6, globvar_7, globvar_8, globvar_9, globvar_10, globvar_11, globvar_12, globvar_13, globvar_14, globvar_15, globvar_16, globvar_17, globvar_18, globvar_19, globvar_20, globvar_21, @@ -16,7 +19,7 @@ int main(void) { return 1; } - if (fun1(globvar_7, globvar_8, globvar_9, globvar_10, globvar_1, globvar_2, + if (!fun1(globvar_7, globvar_8, globvar_9, globvar_10, globvar_1, globvar_2, globvar_3, globvar_4, globvar_5, globvar_6, globvar_7.arr, globvar_8.arr, globvar_9.arr, globvar_10.arr, globvar_1.arr, globvar_2.arr, globvar_3.arr, globvar_4.arr, globvar_5.arr, @@ -24,36 +27,17 @@ int main(void) { return 2; } - if (fun2(globvar_11, globvar_12, globvar_13, globvar_1, globvar_11.arr, + if (!fun2(globvar_11, globvar_12, globvar_13, globvar_1, globvar_11.arr, globvar_12.arr, globvar_13.arr, globvar_1.arr)) { return 3; } - if (fun3(globvar_14, globvar_15, globvar_16, globvar_2, globvar_14.arr, + if (!fun3(globvar_14, globvar_15, globvar_16, globvar_2, globvar_14.arr, globvar_15.arr, globvar_16.arr, globvar_2.arr)) { return 4; } - if (fun4(globvar_17, globvar_18, globvar_3, globvar_17.arr, globvar_18.arr, - globvar_3.arr)) { - return 5; - } - - if (fun5(globvar_19, globvar_20, globvar_4, globvar_19.arr, globvar_20.arr, - globvar_4.arr)) { - return 6; - } - - if (fun6(globvar_21, globvar_22, globvar_5, globvar_21.arr, globvar_22.arr, - globvar_5.arr)) { - return 7; - } - - if (fun7(globvar_23, globvar_24, globvar_4, globvar_23.arr, globvar_24.arr, - globvar_4.arr)) { - return 8; - } - + // define local variables of each size struct bytesize1 locvar_1 = {{0}}; struct bytesize2 locvar_2 = {{1, 2}}; @@ -123,7 +107,8 @@ int main(void) { 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43}}; - if (fun0(locvar_1, locvar_2, locvar_3, locvar_4, locvar_5, locvar_6, + // pass local variables of each size + if (!fun0(locvar_1, locvar_2, locvar_3, locvar_4, locvar_5, locvar_6, locvar_7, locvar_8, locvar_9, locvar_10, locvar_11, locvar_12, locvar_13, locvar_14, locvar_15, locvar_16, locvar_17, locvar_18, locvar_19, locvar_20, locvar_21, locvar_22, locvar_23, locvar_24, @@ -133,43 +118,23 @@ int main(void) { locvar_13.arr, locvar_14.arr, locvar_15.arr, locvar_16.arr, locvar_17.arr, locvar_18.arr, locvar_19.arr, locvar_20.arr, locvar_21.arr, locvar_22.arr, locvar_23.arr, locvar_24.arr)) { - return 1; + return 5; } - if (fun1(locvar_7, locvar_8, locvar_9, locvar_10, locvar_1, locvar_2, + if (!fun1(locvar_7, locvar_8, locvar_9, locvar_10, locvar_1, locvar_2, locvar_3, locvar_4, locvar_5, locvar_6, locvar_7.arr, locvar_8.arr, locvar_9.arr, locvar_10.arr, locvar_1.arr, locvar_2.arr, locvar_3.arr, locvar_4.arr, locvar_5.arr, locvar_6.arr)) { - return 2; - } - - if (fun2(locvar_11, locvar_12, locvar_13, locvar_1, locvar_11.arr, - locvar_12.arr, locvar_13.arr, locvar_1.arr)) { - return 3; - } - - if (fun3(locvar_14, locvar_15, locvar_16, locvar_2, locvar_14.arr, - locvar_15.arr, locvar_16.arr, locvar_2.arr)) { - return 4; - } - - if (fun4(locvar_17, locvar_18, locvar_3, locvar_17.arr, locvar_18.arr, - locvar_3.arr)) { - return 5; - } - - if (fun5(locvar_19, locvar_20, locvar_4, locvar_19.arr, locvar_20.arr, - locvar_4.arr)) { return 6; } - if (fun6(locvar_21, locvar_22, locvar_5, locvar_21.arr, locvar_22.arr, - locvar_5.arr)) { + if (!fun2(locvar_11, locvar_12, locvar_13, locvar_1, locvar_11.arr, + locvar_12.arr, locvar_13.arr, locvar_1.arr)) { return 7; } - if (fun7(locvar_23, locvar_24, locvar_4, locvar_23.arr, locvar_24.arr, - locvar_4.arr)) { + if (!fun3(locvar_14, locvar_15, locvar_16, locvar_2, locvar_14.arr, + locvar_15.arr, locvar_16.arr, locvar_2.arr)) { return 8; } diff --git a/tests/chapter_18/valid/parameters/pass_args_on_page_boundary.c b/tests/chapter_18/valid/parameters/pass_args_on_page_boundary.c index aaf55748..336b2543 100644 --- a/tests/chapter_18/valid/parameters/pass_args_on_page_boundary.c +++ b/tests/chapter_18/valid/parameters/pass_args_on_page_boundary.c @@ -1,17 +1,53 @@ -#ifdef SUPPRESS_WARNINGS -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif +/* Test that we don't read past the bounds of a structure when passing it as a + * parameter: pass a structure parameter that ends at the end + * of a page, where the next page isn't mapped. If we read past the end of the + * structure we'll trigger a memory access violation and crash the program. + * */ +// structure type is two eightbytes struct nine_bytes { - char arr[9]; + char arr[11]; }; -// irregularly-sized struct that's right on a page boundary +// irregularly-sized struct that's right on a page boundary, +// defined in data_on_page_boundary_.s extern struct nine_bytes on_page_boundary; int f(struct nine_bytes in_reg, int a, int b, int c, int d, int e, - struct nine_bytes stack1) { - return in_reg.arr[2] + stack1.arr[3] + stack1.arr[8]; + struct nine_bytes on_stack) { + // validate structs + for (int i = 0; i < 9; i = i + 1) { + char in_reg_c = in_reg.arr[i]; + char on_stack_c = on_stack.arr[i]; + if (i == 2) { + // on_page_boundary[2] == 4 + if (in_reg_c != 4 || on_stack_c != 4) { + return 1; + } + } else if (i == 3) { + // on_page_boundary[3] == 5 + if (in_reg_c != 5 || on_stack_c != 5) { + return 2; + } + } else if (i == 8) { + // on_page_boundary[8] == 6 + if (in_reg_c != 6 || on_stack_c != 6) { + return 3; + } + } else { + // all other array elements are 0 + if (in_reg_c || on_stack_c) { + return 4; + } + } + } + + // validate other args + if (a != 101 || b != 102 || c != 103 || d != 104 || e != 105) { + return 5; + } + + return 0; // success } int main(void) { @@ -19,5 +55,6 @@ int main(void) { on_page_boundary.arr[3] = 5; on_page_boundary.arr[8] = 6; // pass this struct in register and on stack - return f(on_page_boundary, 0, 0, 0, 0, 0, on_page_boundary); + return f(on_page_boundary, 101, 102, 103, 104, 105, + on_page_boundary); // 0 is success } \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/pass_struct_and_other_args.c b/tests/chapter_18/valid/parameters/pass_struct_and_other_args.c deleted file mode 100644 index fe6176eb..00000000 --- a/tests/chapter_18/valid/parameters/pass_struct_and_other_args.c +++ /dev/null @@ -1,17 +0,0 @@ -#ifdef SUPPRESS_WARNINGS -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -struct pair { - int x; - double y; -}; - -double foo(struct pair p, int a, int b, int c, int d, int e, int f, int g) { - return p.y + g; -} - -int main(void) { - struct pair x = {1, 2.0}; - return foo(x, 0, 0, 0, 0, 0, 0, 1) == 3.0; -} \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/pass_struct_as_arg.c b/tests/chapter_18/valid/parameters/pass_struct_as_arg.c deleted file mode 100644 index 6a3b9c7d..00000000 --- a/tests/chapter_18/valid/parameters/pass_struct_as_arg.c +++ /dev/null @@ -1,13 +0,0 @@ -struct pair { - int x; - double y; -}; - -double foo(struct pair p) { - return p.y; -} - -int main(void) { - struct pair x = {1, 2.0}; - return foo(x) == 2.0; -} \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/simple.c b/tests/chapter_18/valid/parameters/simple.c new file mode 100644 index 00000000..321df97b --- /dev/null +++ b/tests/chapter_18/valid/parameters/simple.c @@ -0,0 +1,22 @@ +/* Basic test of passing an argument of structure type */ +struct pair { + int x; + double y; +}; + +// pass x in EDI and y and XMM0 +double test_struct_param(struct pair p) { + if (p.x != 1 || p.y != 2.0) { + return 0; + } + + return 1; // success +} + +int main(void) { + struct pair x = {1, 2.0}; + if (!test_struct_param(x)) { + return 1; + } + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_18/valid/parameters/stack_clobber.c b/tests/chapter_18/valid/parameters/stack_clobber.c new file mode 100644 index 00000000..323acd73 --- /dev/null +++ b/tests/chapter_18/valid/parameters/stack_clobber.c @@ -0,0 +1,226 @@ +/* Test that passing structures as parameters doesn't clobber the stack + * To test this, we store some bytes to the stack, pass the struct, then + * validate that those bytes haven't changed. In the functions whose stacks we + * validate, we don't store _any_ temporary values on the stack; the only values + * on the stack should be the bytes we explicitly validate. This means these + * tests don't call functions that return values, evaluate any expressions that + * undergo array decay (because the result of GetAddr would be stored on the + * stack) or perform any other computations that produce intermediate + * expressions. This ensures that if any value on the stack is clobbered, we'll + * detect it. + */ + +#ifdef SUPPRESS_WARNINGS +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" +#else +#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" +#endif +#endif + +int strcmp(char *s1, char *s2); +void exit(int status); + +struct stack_bytes { + char bytes[16]; +}; + +// we copy bytes from the stack to here, then validate them +static struct stack_bytes to_validate; + +// use this to validate to_validate after copying bytes from stack to it +void validate_stack_bytes(int code) { + if (strcmp(to_validate.bytes, "efghijklmnopqrs")) { + exit(code); + } + return; +} + +// test case 1: passing a struct holding four-byte int +struct one_longword { + int i; +}; + +void take_longword(struct one_longword s, int code) { + if (s.i != 10) { + exit(code); + } + return; +} + +int pass_longword(void) { + // write some bytes to the stack + struct stack_bytes bytes = {"efghijklmnopqrs"}; + // make this static so it's not on the stack + static struct one_longword my_var = {10}; + // this funcall doesn't require temporary values on the stack + // b/c its args are just a variable and int (not more complex expressions) + // and its return type is void + take_longword(my_var, 1); + + // assigning a variable doesn't produce any temporary values + to_validate = bytes; + + // this funcall doesn't require temporary values on the stack + // b/c its arg is just an int(not a more complex expression) + // and its return type + validate_stack_bytes(2); + return 0; +} + +// test case #2: passing a struct holding an eight-byte int +struct one_quadword { + long l; +}; + +void take_quadword(struct one_quadword s, int code) { + if (s.l != 10) { + exit(code); + } + return; +} + +int pass_quadword(void) { + // write some bytes to the stack + struct stack_bytes bytes = {"efghijklmnopqrs"}; + + static struct one_quadword my_var = {10}; + take_quadword(my_var, 3); + + // validate stack + to_validate = bytes; + validate_stack_bytes(4); + return 0; +} + +// test case #3: passing a struct holding a double +struct one_double { + double d; +}; + +void take_double(struct one_double s, int code) { + if (s.d != 10) { + exit(code); + } + return; +} + +int pass_double(void) { + // write some bytes to the stack + struct stack_bytes bytes = {"efghijklmnopqrs"}; + static struct one_double my_var = {10}; + take_double(my_var, 5); + + // validate stack + to_validate = bytes; + validate_stack_bytes(6); + return 0; +} + +// test case #4: passing a struct holding twelve bytes +struct twelve_bytes { + char arr[12]; +}; + +void take_twelve_bytes(struct twelve_bytes s, int code) { + if (strcmp(s.arr, "abcdefghijk")) { + exit(code); + } + return; +} + +int pass_twelve_bytes(void) { + struct stack_bytes bytes = {"efghijklmnopqrs"}; + static struct twelve_bytes my_var = {"abcdefghijk"}; + take_twelve_bytes(my_var, 7); + + // validate stack + to_validate = bytes; + validate_stack_bytes(8); + return 0; +} + +// test case #5: passing a struct in memory +// make sure this is an even number of quadwords so we don't need to add stack +// padding +struct memory { + char arr[32]; +}; + +void take_struct_in_mem(struct memory s, int code) { + if (strcmp(s.arr, "Here's the thing: I'm a string.")) { + exit(code); + } + return; +} + +int pass_struct_in_mem(void) { + struct stack_bytes bytes = {"efghijklmnopqrs"}; + static struct memory my_var = {"Here's the thing: I'm a string."}; + take_struct_in_mem(my_var, 9); + + // validate stack + to_validate = bytes; + validate_stack_bytes(10); + return 0; +} + +// test case #6: passing a 3-byte struct +struct irregular { + char arr[3]; +}; + +void take_irregular_struct(struct irregular s, int code) { + if (strcmp(s.arr, "12")) { + exit(code); + } + return; +} + +int pass_irregular_struct(void) { + struct stack_bytes bytes = {"efghijklmnopqrs"}; + static struct irregular my_var = {"12"}; + take_irregular_struct(my_var, 11); + + // validate stack + to_validate = bytes; + validate_stack_bytes(12); + return 0; +} + +// test case #7: passing an irregularly-sized struct in memory +// make sure this is an even number of quadwords so we don't need to add stack +// padding +struct irregular_memory { + char arr[27]; +}; + +void take_irregular_memory_struct(struct irregular_memory s, int code) { + if (strcmp(s.arr, "The quick brown fox jumped")) { + exit(code); + } + return; +} + +int pass_irregular_memory_struct(void) { + struct stack_bytes bytes = {"efghijklmnopqrs"}; + + static struct irregular_memory my_var = {"The quick brown fox jumped"}; + take_irregular_memory_struct(my_var, 13); + + // validate stack + to_validate = bytes; + validate_stack_bytes(14); + return 0; +} + +int main(void) { + pass_longword(); + pass_quadword(); + pass_double(); + pass_twelve_bytes(); + pass_struct_in_mem(); + pass_irregular_struct(); + pass_irregular_memory_struct(); + return 0; +} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/cast_struct_to_void.c b/tests/chapter_18/valid/params_and_returns/cast_struct_to_void.c deleted file mode 100644 index 1bfb1cd4..00000000 --- a/tests/chapter_18/valid/params_and_returns/cast_struct_to_void.c +++ /dev/null @@ -1,13 +0,0 @@ -struct s { - int x; -}; -struct s glob = {0}; -struct s f(void) { - glob.x = glob.x + 1; - return glob; -} -int main(void) { - (void)f(); - (void)f(); - return glob.x; -} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/data_on_page_boundary_linux.s b/tests/chapter_18/valid/params_and_returns/data_on_page_boundary_linux.s index 701a6651..2c921328 100644 --- a/tests/chapter_18/valid/params_and_returns/data_on_page_boundary_linux.s +++ b/tests/chapter_18/valid/params_and_returns/data_on_page_boundary_linux.s @@ -1,6 +1,6 @@ - .bss - .align 4096 - .zero 4084 + .bss # .bss is the last segment in the program image - the page after it will be unampped + .align 4096 # force page alignment + .zero 4086 # write a bunch of zeros so on_page_boundary is at the end of the page .globl on_page_boundary on_page_boundary: .zero 10 diff --git a/tests/chapter_18/valid/params_and_returns/data_on_page_boundary_osx.s b/tests/chapter_18/valid/params_and_returns/data_on_page_boundary_osx.s index cb39d88f..2cbc9ae5 100644 --- a/tests/chapter_18/valid/params_and_returns/data_on_page_boundary_osx.s +++ b/tests/chapter_18/valid/params_and_returns/data_on_page_boundary_osx.s @@ -1,6 +1,6 @@ - .bss - .align 12 # 2^12 = 4096 - .zero 4084 + .bss # .bss is the last segment in the program image - the page after it will be unampped + .align 12 # force page alignment (2^12 == 4096) + .zero 4085 # write a bunch of zeros so on_page_boundary is at the end of the page .globl _on_page_boundary _on_page_boundary: .zero 10 diff --git a/tests/chapter_18/valid/params_and_returns/ignore_retval.c b/tests/chapter_18/valid/params_and_returns/ignore_retval.c new file mode 100644 index 00000000..a124ff69 --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/ignore_retval.c @@ -0,0 +1,45 @@ +/* Test returning a struct and discarding the result + * Make sure this works for structs passed in registers and + * on the stack + * */ + +struct small { + int x; +}; + +struct big { + double d; + int x; + long l; +}; + +struct small globl = {0}; +struct small return_in_reg(void) { + globl.x = globl.x + 1; + return globl; +} + +struct big globl2 = {1.25, 2, 300}; +struct big return_in_mem(void) { + globl2.d = globl2.d * 2; + globl2.x = globl2.x * 3; + globl2.l = globl2.l * 4; + return globl2; +} + +int main(void) { + // can either explicitly cast result to void or just not use it + (void)return_in_reg(); + return_in_reg(); + if (globl.x != 2) { + return 1; + } + + // do the same for struct return in memory + return_in_mem(); + (void)return_in_mem(); + if (globl2.d != 5.0 || globl2.x != 18 || globl2.l != 4800) { + return 2; + } + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/libraries/access_retval_members.c b/tests/chapter_18/valid/params_and_returns/libraries/access_retval_members.c new file mode 100644 index 00000000..5c712b05 --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/libraries/access_retval_members.c @@ -0,0 +1,20 @@ +/* Test for accessing the members in a return value of structure type */ +#include "access_retval_members.h" + +struct inner return_small_struct(void) { + struct inner i = {101, 102}; + return i; +} + +struct outer return_nested_struct(void) { + static struct outer ret = {2.0, 0, {10, 11}}; + + // on first call to this function, initializer ret.ptr + if (!ret.ptr) { + ret.ptr = calloc(1, sizeof(struct inner)); + ret.ptr->x = 12; + ret.ptr->y = 13; + } + + return ret; +} diff --git a/tests/chapter_18/valid/params_and_returns/libraries/access_retval_members.h b/tests/chapter_18/valid/params_and_returns/libraries/access_retval_members.h new file mode 100644 index 00000000..1503e593 --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/libraries/access_retval_members.h @@ -0,0 +1,16 @@ +/* Test for accessing the members in a return value of structure type */ +struct inner { + char x; + long y; +}; + +struct outer { + double d; + struct inner *ptr; + struct inner s; +}; + +void *calloc(unsigned long nmemb, unsigned long size); + +struct inner return_small_struct(void); +struct outer return_nested_struct(void); \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/libraries/access_retval_members_client.c b/tests/chapter_18/valid/params_and_returns/libraries/access_retval_members_client.c new file mode 100644 index 00000000..4d362525 --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/libraries/access_retval_members_client.c @@ -0,0 +1,33 @@ +/* Test for accessing the members in a return value of structure type */ +#include "access_retval_members.h" + +int main(void) { + // get member in a non-nested struct + if (return_small_struct().y != 102) { + return 1; + } + + // get members in nested struct + if (return_nested_struct().d != 2.0 || return_nested_struct().s.x != 10 || + return_nested_struct().s.y != 11) { + return 3; + } + + // get members thru pointer in nested struct + if (return_nested_struct().ptr->x != 12 || + return_nested_struct().ptr->y != 13) { + return 4; + } + + // update members through pointer in nested struct + return_nested_struct().ptr->x = 70; + return_nested_struct().ptr->y = 71; + + // validate updated values + if (return_nested_struct().ptr->x != 70 || + return_nested_struct().ptr->y != 71) { + return 5; + } + + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/libraries/missing_retval.c b/tests/chapter_18/valid/params_and_returns/libraries/missing_retval.c index ac2a67f4..b5dce763 100644 --- a/tests/chapter_18/valid/params_and_returns/libraries/missing_retval.c +++ b/tests/chapter_18/valid/params_and_returns/libraries/missing_retval.c @@ -1,3 +1,8 @@ +/* Test case where the return type would be passed on the stack, but the callee + * is missing a return statement This is well-defined as long as the caller + * doesn't try to use the return value + * */ + #include "missing_retval.h" #ifdef SUPPRESS_WARNINGS diff --git a/tests/chapter_18/valid/params_and_returns/libraries/missing_retval.h b/tests/chapter_18/valid/params_and_returns/libraries/missing_retval.h index ea5d620d..c60c30b2 100644 --- a/tests/chapter_18/valid/params_and_returns/libraries/missing_retval.h +++ b/tests/chapter_18/valid/params_and_returns/libraries/missing_retval.h @@ -1,8 +1,9 @@ +/* Test case where the return type would be passed on the stack, but the callee + * is missing a return statement This is well-defined as long as the caller + * doesn't try to use the return value + * */ struct big { char arr[25]; }; -// make sure we correctly handle calls to functions with return values -// passed on stack, even if return statement is missing, -// as long as caller doesn't use return value struct big missing_return_value(int *i); \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/libraries/missing_retval_client.c b/tests/chapter_18/valid/params_and_returns/libraries/missing_retval_client.c index 2cd8d8ad..2dfd50dd 100644 --- a/tests/chapter_18/valid/params_and_returns/libraries/missing_retval_client.c +++ b/tests/chapter_18/valid/params_and_returns/libraries/missing_retval_client.c @@ -1,7 +1,13 @@ +/* Test case where the return type would be passed on the stack, but the callee + * is missing a return statement. This is well-defined as long as the caller + * doesn't try to use the return value + * */ #include "missing_retval.h" int main(void) { int array[4] = {1, 2, 3, 4}; missing_return_value(array + 2); + // make sure the function returns normally and it updated array[2] + // as expected return array[2] == 10; } \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/libraries/pass_wonky_struct.c b/tests/chapter_18/valid/params_and_returns/libraries/pass_wonky_struct.c deleted file mode 100644 index f7923c64..00000000 --- a/tests/chapter_18/valid/params_and_returns/libraries/pass_wonky_struct.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "pass_wonky_struct.h" -void exit(int status); - -// make sure we can successfully pass and return structures on the stack -// whose size is not exactly divisible by 8 -// (e.g. returning won't clobber neighboring stack values) - -struct wonky change_struct(struct wonky arg) { - char *arr = arg.arr; - // first make sure it's all zero - for (int i = 0; i < 19; i = i + 1) { - if (arr[i]) { - exit(2); - } - } - arr[0] = 1; - arr[6] = 6; - arr[17] = -1; - return arg; -} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/libraries/pass_wonky_struct.h b/tests/chapter_18/valid/params_and_returns/libraries/pass_wonky_struct.h deleted file mode 100644 index 7305937c..00000000 --- a/tests/chapter_18/valid/params_and_returns/libraries/pass_wonky_struct.h +++ /dev/null @@ -1,6 +0,0 @@ -// larger than 16 bytes but size is not divisible by 8 bytes -struct wonky { - char arr[19]; -}; - -struct wonky change_struct(struct wonky arg); \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/libraries/pass_wonky_struct_client.c b/tests/chapter_18/valid/params_and_returns/libraries/pass_wonky_struct_client.c deleted file mode 100644 index 0648c7da..00000000 --- a/tests/chapter_18/valid/params_and_returns/libraries/pass_wonky_struct_client.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "pass_wonky_struct.h" - -int main(void) { - // because this is static, it will be initialized to all zeros - static struct wonky all_zeros; - - struct wonky modified = change_struct(all_zeros); - if (modified.arr[0] != 1) - return 100; - if (modified.arr[6] != 6) - return 101; - if (modified.arr[17] != -1) - return 102; - for (int i = 0; i < 14; i = i + 1) { - if (i == 0 || i == 6 || i == 13) - continue; - if (modified.arr[i] != 0) - return i; - } - - return 0; -} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c b/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c index 7e33013b..68f0ae6a 100644 --- a/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c +++ b/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.c @@ -1,3 +1,4 @@ +/* Test that we return a wide range of struct types according to the ABI */ #include "return_calling_conventions.h" struct one_int return_int_struct(void) { @@ -37,44 +38,50 @@ int f(char c, double d) { return 1; } +int leaf_call(struct two_ints t_i, char c, double d) { + // validate t_i + if (t_i.c != '_' || t_i.arr[0] != 5 || t_i.arr[1] != 6 || t_i.arr[2] != 7) { + return 0; + } + + // validate c1 and d1 (originally passed in a struct int_and_xmm) + if (c != 'p' || d != 4.56) { + return 0; + } + return 1; // success +} + struct memory pass_and_return_regs(int i, double d, struct int_and_xmm strct, char c, struct two_ints t_i, long l, struct one_int_exactly o_i_e, char c2) { - // include stack variables to make sure they don't overwrite return value + // include a stack variable to make sure it doen't overwrite return value // pointer or vice versa - int local1 = i * 2; - double local2 = d * 2; + char stackbytes[8] = "zyxwvut"; struct memory retval = {0, {0, 0, 0}, 0, 0}; - if (local1 != 12 || local2 != 8.0) { + // make another function call to ensure that passing parameters + // doesn't overwrite return address in RDI or other struct eightybtes + // passed in registers; validate t_i and strct while we're at it + if (!leaf_call(t_i, strct.c, strct.d)) { retval.i = 1; return retval; } - int local3 = f(strct.c, strct.d); - if (local3) { + // validate scalar params + if (i != 6 || d != 4.0 || c != 5 || l != 77 || c2 != 99) { retval.i = 2; return retval; } - if (c != 5) { + // validate remainign struct + if (o_i_e.l != 567890) { retval.i = 3; return retval; } - if (t_i.c != '_' || t_i.arr[0] != 5 || t_i.arr[1] != 6 || t_i.arr[2] != 7) { + + // validate stackbytes + if (strcmp(stackbytes, "zyxwvut")) { retval.i = 4; return retval; } - if (l != 77) { - retval.i = 5; - return retval; - } - if (o_i_e.l != 567890) { - retval.i = 6; - return retval; - } - if (c2 != 99) { - retval.i = 7; - return retval; - } retval.l = 100; - return retval; + return retval; // success } \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.h b/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.h index a38fddf6..32c0ac18 100644 --- a/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.h +++ b/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions.h @@ -1,3 +1,4 @@ +/* Test that we return a wide range of struct types according to the ABI */ #ifdef SUPPRESS_WARNINGS #ifdef __clang__ #pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" diff --git a/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions_client.c b/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions_client.c index 607fd4bc..ef9d6db9 100644 --- a/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions_client.c +++ b/tests/chapter_18/valid/params_and_returns/libraries/return_calling_conventions_client.c @@ -1,3 +1,4 @@ +/* Test that we return a wide range of struct types according to the ABI */ #include "return_calling_conventions.h" int main(void) { @@ -9,48 +10,44 @@ int main(void) { struct one_int s1 = return_int_struct(); if (s1.i != 1 || s1.c != 2) { - return 26; + return 1; } struct twelve_bytes s2 = return_two_int_struct(); if (s2.i != 10 || strncmp(s2.arr, "12345678", sizeof s2.arr)) - return 27; + return 2; struct one_xmm s3 = return_double_struct(); if (s3.d != 100.625) - return 28; + return 3; struct two_xmm s4 = return_two_double_struct(); if (s4.d[0] != 8.8 || s4.d[1] != 7.8) - return 29; + return 4; struct xmm_and_int s5 = return_mixed(); if (s5.dbl.d != 10.0 || strcmp(s5.c, "ab")) - return 30; + return 5; struct int_and_xmm s6 = return_mixed2(); if (s6.c != 127 || s6.d != 34e43) - return 31; + return 6; struct memory s7 = return_on_stack(); if (s7.d != 1.25 || strcmp(s7.c, "xy") || s7.l != 100l || s7.i != 44) - return 32; - - // call return_on_stack again and ignore the value; make sure we still - // allocate space for it - return_on_stack(); + return 7; s7 = pass_and_return_regs(6, 4.0, int_and_xmm, 5, two_ints, 77, one_long, 99); // something was clobbered or set incorrectly in retval if (s7.d || s7.c[0] || s7.c[1] || s7.c[2]) - return 33; + return 8; // i was set to indicate problem w/ parameter passing if (s7.i) - return 100 + s7.i; + return 9; if (s7.l != 100) - return 34; // l field was clobbered or set incorrectly + return 10; // l field was clobbered or set incorrectly // success! return 0; diff --git a/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.c b/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.c index 26929638..3f8b5304 100644 --- a/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.c +++ b/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.c @@ -1,4 +1,5 @@ +/* Test that we can return structs of every size between 1 and 24 bytes. */ #include "retval_struct_sizes.h" struct bytesize1 fun1(void) { diff --git a/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.h b/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.h index 25579823..f35a2483 100644 --- a/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.h +++ b/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes.h @@ -1,3 +1,4 @@ +/* Test that we can return structs of every size between 1 and 24 bytes. */ #ifdef SUPPRESS_WARNINGS #ifdef __clang__ #pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" diff --git a/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes_client.c b/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes_client.c index 52c83eca..2f58d129 100644 --- a/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes_client.c +++ b/tests/chapter_18/valid/params_and_returns/libraries/retval_struct_sizes_client.c @@ -1,4 +1,4 @@ - +/* Test that we can return structs of every size between 1 and 24 bytes. */ #include "retval_struct_sizes.h" int memcmp(void *s1, void *s2, unsigned long n); diff --git a/tests/chapter_18/valid/params_and_returns/pass_and_return_struct.c b/tests/chapter_18/valid/params_and_returns/pass_and_return_struct.c deleted file mode 100644 index ef7f6356..00000000 --- a/tests/chapter_18/valid/params_and_returns/pass_and_return_struct.c +++ /dev/null @@ -1,15 +0,0 @@ -struct pair { - int x; - char y; -}; - -struct pair add_to_x(struct pair p) { - p.x = p.x + 5; - return p; -} - -int main(void) { - struct pair arg = {1, 4}; - struct pair result = add_to_x(arg); - return result.x + arg.x + result.y; -} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/return_big_struct_on_page_boundary.c b/tests/chapter_18/valid/params_and_returns/return_big_struct_on_page_boundary.c new file mode 100644 index 00000000..87b80846 --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/return_big_struct_on_page_boundary.c @@ -0,0 +1,54 @@ +/* Test that we don't read past the bounds of a structure when passing it as a + * return value: return a structure that ends at the end + * of a page, where the next page isn't mapped. If we read past the end of the + * structure we'll trigger a memory access violation and crash the program. + * This test is similar to return_struct_on_page_boundary except the struct is + * large enough to be passed in memory instead of registers + * */ + +struct eighteen_bytes { + char arr[18]; +}; + +// irregularly-sized struct that's right on a page boundary, +// defined in big_data_on_page_boundary_.s +extern struct eighteen_bytes on_page_boundary; + +struct eighteen_bytes return_struct(void) { + on_page_boundary.arr[17] = 12; + on_page_boundary.arr[9] = -1; + on_page_boundary.arr[8] = -2; + on_page_boundary.arr[7] = -3; + return on_page_boundary; +} + +int main(void) { + // call function that returns on_page_boundary + struct eighteen_bytes x = return_struct(); + + // validate it + for (int i = 0; i < 18; i = i + 1) { + char val = x.arr[i]; + if (i == 7) { + if (val != -3) { + return 1; + } + } else if (i == 8) { + if (val != -2) { + return 2; + } + } else if (i == 9) { + if (val != -1) { + return 3; + } + } else if (i == 17) { + if (val != 12) { + return 4; + } + } else if (x.arr[i]) { // all other elements are 0 + return 5; + } + } + + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/return_incomplete_type.c b/tests/chapter_18/valid/params_and_returns/return_incomplete_type.c index 392d9341..ca1d8858 100644 --- a/tests/chapter_18/valid/params_and_returns/return_incomplete_type.c +++ b/tests/chapter_18/valid/params_and_returns/return_incomplete_type.c @@ -1,17 +1,30 @@ +/* Test that we can declare a function with incomplete parameter and return + * types, then call/define it after the type is completed + * */ + struct s; -struct s return_struct(void); +struct s increment_struct(struct s param); +// complete the type struct s { int a; int b; }; int main(void) { - struct s val = return_struct(); - return val.a; + struct s arg = {1, 2}; + + // we can call increment_struct now that the 'struct s' type is complete + struct s val = increment_struct(arg); + if (val.a != 2 || val.b != 3) { + return 1; + } + return 0; // success } -struct s return_struct(void) { - struct s result = {1, 2}; - return result; +struct s increment_struct(struct s param) { + // increment both members + param.a = param.a + 1; + param.b = param.b + 1; + return param; } \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/return_space_overlap.c b/tests/chapter_18/valid/params_and_returns/return_space_overlap.c new file mode 100644 index 00000000..0433ef42 --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/return_space_overlap.c @@ -0,0 +1,22 @@ +struct s { + long l1; + long l2; + long l3; +}; + +extern struct s globvar; +struct s overlap_with_globvar(void); +struct s overlap_with_pointer(struct s *ptr); +int main(void) { + globvar = overlap_with_globvar(); + if (globvar.l1 != 400l || globvar.l2 != 500l || globvar.l3 != 600l) { + return 2; + } + + struct s my_struct = {10l, 9l, 8l}; + my_struct = overlap_with_pointer(&my_struct); + if (my_struct.l1 != 20l || my_struct.l2 != 18l || my_struct.l3 != 16l) { + return 4; + } + return 0; +} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/return_struct.c b/tests/chapter_18/valid/params_and_returns/return_struct.c deleted file mode 100644 index 52814863..00000000 --- a/tests/chapter_18/valid/params_and_returns/return_struct.c +++ /dev/null @@ -1,13 +0,0 @@ -struct pair { - char x; - long y; -}; - -struct pair return_pair(void) { - struct pair ret = {1, 11l}; - return ret; -} - -int main(void) { - return return_pair().y; -} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/return_struct_on_page_boundary.c b/tests/chapter_18/valid/params_and_returns/return_struct_on_page_boundary.c index 387385b3..a7f72f9f 100644 --- a/tests/chapter_18/valid/params_and_returns/return_struct_on_page_boundary.c +++ b/tests/chapter_18/valid/params_and_returns/return_struct_on_page_boundary.c @@ -1,8 +1,15 @@ +/* Test that we don't read past the bounds of a structure when passing it as a + * return value: return a structure that ends at the end + * of a page, where the next page isn't mapped. If we read past the end of the + * structure we'll trigger a memory access violation and crash the program. + * */ + struct ten_bytes { char arr[10]; }; -// irregularly-sized struct that's right on a page boundary +// irregularly-sized struct that's right on a page boundary, +// defined in data_on_page_boundary_.s extern struct ten_bytes on_page_boundary; struct ten_bytes return_struct(void) { @@ -13,7 +20,10 @@ struct ten_bytes return_struct(void) { } int main(void) { + // call function that returns on_page_boundary struct ten_bytes x = return_struct(); + + // validate it for (int i = 0; i < 7; i = i + 1) { if (x.arr[i]) { return 1; @@ -29,5 +39,5 @@ int main(void) { if (x.arr[9] != -1) { return 3; } - return 0; + return 0; // success } \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/simple.c b/tests/chapter_18/valid/params_and_returns/simple.c new file mode 100644 index 00000000..abd1fe7b --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/simple.c @@ -0,0 +1,29 @@ +/* Basic test case for having both parameters and return values of + * structure type + * */ +struct pair { + int x; + char y; +}; + +struct pair2 { + double d; + long l; +}; + +/* construct a pair2 by multiplying each value from pair1 by 2 */ +struct pair2 double_members(struct pair p) { + struct pair2 retval = {p.x * 2, p.y * 2}; + return retval; +} + +int main(void) { + struct pair arg = {1, 4}; + struct pair2 result = double_members(arg); + + // validate + if (result.d != 2.0 || result.l != 8) { + return 1; + } + return 0; // success +} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/stack_clobber.c b/tests/chapter_18/valid/params_and_returns/stack_clobber.c new file mode 100644 index 00000000..97c6a8b8 --- /dev/null +++ b/tests/chapter_18/valid/params_and_returns/stack_clobber.c @@ -0,0 +1,304 @@ +/* Test that returning a struct doesn't clobber the stack. + * This is most likely when we're returning structs in memory, but test other + * types of structs too. + * To test this, we store some bytes on the stack, call a function that returns + * the struct, then validate that those bytes haven't changed. In the functions + * whose stacks we validate, we don't store any values on the stack except the + * bytes to validate and the return value. This ensures that if the return + * value clobbers any other bytes on the stack, we'll detect it. + * (This is a similar technique to chapter_18/valid/parameters/stack_clobber.c) + */ + +#ifdef SUPPRESS_WARNINGS +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wincompatible-library-redeclaration" +#else +#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" +#endif +#endif + +int strcmp(char *s1, char *s2); +void exit(int status); + +struct stack_bytes { + char bytes[16]; +}; + +// we copy bytes from the stack to here, then validate them +static struct stack_bytes to_validate; + +// use this to validate to_validate after copying bytes from stack to it +void validate_stack_bytes(int code) { + if (strcmp(to_validate.bytes, "efghijklmnopqrs")) { + exit(code); + } + return; +} + +// test case 1: return a struct in a general-purpose register +struct one_int_reg { + char cs[7]; +}; + +struct one_int_reg return_int_struct(void) { + struct one_int_reg retval = {{0, 0, 0, 0, 0, 0, 0}}; + return retval; +} + +static struct one_int_reg one_int_struct; +void validate_one_int_struct(int code) { + for (int i = 0; i < 7; i = i + 1) { + if (one_int_struct.cs[i]) { + exit(code); + } + } +} + +int test_int_struct(void) { + // write some bytes to the stack + struct stack_bytes bytes = {"efghijklmnopqrs"}; + + // call a function that returns a one-int struct + // copy it to a static variable so we can validate it later + // without putting more temproary variables on the satck + one_int_struct = return_int_struct(); + + // assigning a variable doesn't produce any temporary values + to_validate = bytes; + + // this funcall doesn't require temporary values on the stack + // b/c its arg is just an int(not a more complex expression) + // and its return type + validate_stack_bytes(1); + + /// validate the static struct we copied the return val into earlier + validate_one_int_struct(2); + return 0; +} + +// test case 2: return a struct in two general-purpose registers +struct two_int_regs { + char cs[15]; +}; + +struct two_int_regs return_two_int_struct(void) { + struct two_int_regs retval = { + {20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34}}; + return retval; +} + +static struct two_int_regs two_int_struct; +void validate_two_int_struct(int code) { + for (int i = 0; i < 15; i = i + 1) + if (two_int_struct.cs[i] != i + 20) { + exit(code); + } +} + +int test_two_int_struct(void) { + // write some bytes to the stack + struct stack_bytes bytes = {"efghijklmnopqrs"}; + + two_int_struct = return_two_int_struct(); + + // assigning a variable doesn't produce any temporary values + to_validate = bytes; + + // validate stack + validate_stack_bytes(3); + + /// validate returned struct + validate_two_int_struct(4); + return 0; +} + +// test case 3: return a struct in one XMM register +struct one_xmm_reg { + double d; +}; + +struct one_xmm_reg return_one_xmm_struct(void) { + struct one_xmm_reg retval = {234.5}; + return retval; +} + +static struct one_xmm_reg one_double_struct; +void validate_one_double_struct(int code) { + if (one_double_struct.d != 234.5) { + exit(code); + } +} + +int test_one_double_struct(void) { + // write some bytes to the stack + struct stack_bytes bytes = {"efghijklmnopqrs"}; + + one_double_struct = return_one_xmm_struct(); + + // assigning a variable doesn't produce any temporary values + to_validate = bytes; + + // validate stack + validate_stack_bytes(5); + + /// validate returned struct + validate_one_double_struct(6); + return 0; +} + +// test case 4: return a struct in two XMM registers +struct two_xmm_regs { + double d1; + double d2; +}; + +struct two_xmm_regs return_two_xmm_struct(void) { + struct two_xmm_regs retval = {234.5, 678.25}; + return retval; +} + +static struct two_xmm_regs two_doubles_struct; +void validate_two_doubles_struct(int code) { + if (two_doubles_struct.d1 != 234.5 || two_doubles_struct.d2 != 678.25) { + exit(code); + } +} + +int test_two_doubles_struct(void) { + // write some bytes to the stack + struct stack_bytes bytes = {"efghijklmnopqrs"}; + + two_doubles_struct = return_two_xmm_struct(); + + // assigning a variable doesn't produce any temporary values + to_validate = bytes; + + // validate stack + validate_stack_bytes(7); + + /// validate returned struct + validate_two_doubles_struct(8); + return 0; +} + +// test case 5: return a stuct in general-purpose and XMM registers + +struct int_and_xmm { + char c; + double d; +}; + +struct int_and_xmm return_mixed_struct(void) { + struct int_and_xmm retval = {125, 678.25}; + return retval; +} + +static struct int_and_xmm mixed_struct; +void validate_mixed_struct(int code) { + if (mixed_struct.c != 125 || mixed_struct.d != 678.25) { + exit(code); + } +} + +int test_mixed_struct(void) { + // write some bytes to the stack + struct stack_bytes bytes = {"efghijklmnopqrs"}; + + mixed_struct = return_mixed_struct(); + + // assigning a variable doesn't produce any temporary values + to_validate = bytes; + + // validate stack + validate_stack_bytes(9); + + /// validate returned struct + validate_mixed_struct(10); + return 0; +} + +// test case 6: return a struct on the stack +struct stack { + char cs[28]; +}; + +struct stack return_stack_struct(void) { + struct stack retval = {{90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117}}; + return retval; +} + +static struct stack stack_struct; +void validate_stack_struct(int code) { + for (int i = 0; i < 28; i = i + 1) { + if (stack_struct.cs[i] != i + 90) { + exit(code); + } + } +} + +int test_stack_struct(void) { + // write some bytes to the stack + struct stack_bytes bytes = {"efghijklmnopqrs"}; + + stack_struct = return_stack_struct(); + + // assigning a variable doesn't produce any temporary values + to_validate = bytes; + + // validate stack + validate_stack_bytes(11); + + /// validate returned struct + validate_stack_struct(12); + return 0; +} + +// test case 7: return an irregularly-slized struct on the stack +struct stack_irregular { + char cs[19]; +}; + +struct stack_irregular return_irregular_stack_struct(void) { + struct stack_irregular retval = {{70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88}}; + return retval; +} + +static struct stack_irregular irregular_stack_struct; +void validate_irregular_stack_struct(int code) { + for (int i = 0; i < 19; i = i + 1) { + if (irregular_stack_struct.cs[i] != i + 70) { + exit(code); + } + } +} + +int test_irregular_stack_struct(void) { + // write some bytes to the stack + struct stack_bytes bytes = {"efghijklmnopqrs"}; + + irregular_stack_struct = return_irregular_stack_struct(); + + // assigning a variable doesn't produce any temporary values + to_validate = bytes; + + // validate stack + validate_stack_bytes(13); + + /// validate returned struct + validate_irregular_stack_struct(14); + return 0; +} + +int main(void) { + test_int_struct(); + test_two_int_struct(); + test_one_double_struct(); + test_two_doubles_struct(); + test_mixed_struct(); + test_stack_struct(); + test_irregular_stack_struct(); + return 0; +} \ No newline at end of file diff --git a/tests/chapter_18/valid/params_and_returns/temporary_lifetime.c b/tests/chapter_18/valid/params_and_returns/temporary_lifetime.c index fed7e197..d469da4d 100644 --- a/tests/chapter_18/valid/params_and_returns/temporary_lifetime.c +++ b/tests/chapter_18/valid/params_and_returns/temporary_lifetime.c @@ -1,26 +1,33 @@ -// a non-lvalue structure that contains an array -// has temporary lifetime; -// you can get the array's address implicitly (but not explicitly) -// NB modifying an array w/ temporary lifetime is undefined -// TODO make this explicitly based on Listing 18-27? +/* A non-lvalue structure that contains anarray has temporary lifetime; + * test that you can get this array's address implicitly (even though + * you can't load it explicitly) + * Adapted from Listing 18-27 + * */ -struct inner { - int a; - int b; +struct s { + int arr[3]; }; -struct contains_array { - struct inner array[4]; -}; - -struct contains_array get_struct(void) { - struct inner obj = {1, 2}; - struct inner obj2 = {3, 4}; - struct contains_array result = {{obj, obj2, obj}}; - return result; +struct s f(void) { + struct s retval = {{1, 2, 3}}; + return retval; } int main(void) { - int i = get_struct().array[2].a; - return i; + int i = f().arr[0]; + int j = f().arr[1]; + int k = f().arr[2]; + + if (i != 1) { + return 1; + } + + if (j != 2) { + return 2; + } + + if (k != 3) { + return 3; + } + return 0; // success } \ No newline at end of file