comparison gcc/go/go-gcc.cc @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 // go-gcc.cc -- Go frontend to gcc IR. 1 // go-gcc.cc -- Go frontend to gcc IR.
2 // Copyright (C) 2011-2017 Free Software Foundation, Inc. 2 // Copyright (C) 2011-2018 Free Software Foundation, Inc.
3 // Contributed by Ian Lance Taylor, Google. 3 // Contributed by Ian Lance Taylor, Google.
4 4
5 // This file is part of GCC. 5 // This file is part of GCC.
6 6
7 // GCC is free software; you can redistribute it and/or modify it under 7 // GCC is free software; you can redistribute it and/or modify it under
274 Bexpression* 274 Bexpression*
275 nil_pointer_expression() 275 nil_pointer_expression()
276 { return this->make_expression(null_pointer_node); } 276 { return this->make_expression(null_pointer_node); }
277 277
278 Bexpression* 278 Bexpression*
279 var_expression(Bvariable* var, Varexpr_context, Location); 279 var_expression(Bvariable* var, Location);
280 280
281 Bexpression* 281 Bexpression*
282 indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location); 282 indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location);
283 283
284 Bexpression* 284 Bexpression*
349 349
350 Bexpression* 350 Bexpression*
351 call_expression(Bfunction* caller, Bexpression* fn, 351 call_expression(Bfunction* caller, Bexpression* fn,
352 const std::vector<Bexpression*>& args, 352 const std::vector<Bexpression*>& args,
353 Bexpression* static_chain, Location); 353 Bexpression* static_chain, Location);
354
355 Bexpression*
356 stack_allocation_expression(int64_t size, Location);
357 354
358 // Statements. 355 // Statements.
359 356
360 Bstatement* 357 Bstatement*
361 error_statement() 358 error_statement()
424 421
425 void 422 void
426 global_variable_set_init(Bvariable*, Bexpression*); 423 global_variable_set_init(Bvariable*, Bexpression*);
427 424
428 Bvariable* 425 Bvariable*
429 local_variable(Bfunction*, const std::string&, Btype*, bool, 426 local_variable(Bfunction*, const std::string&, Btype*, Bvariable*, bool,
430 Location); 427 Location);
431 428
432 Bvariable* 429 Bvariable*
433 parameter_variable(Bfunction*, const std::string&, Btype*, bool, 430 parameter_variable(Bfunction*, const std::string&, Btype*, bool,
434 Location); 431 Location);
484 { return this->make_function(error_mark_node); } 481 { return this->make_function(error_mark_node); }
485 482
486 Bfunction* 483 Bfunction*
487 function(Btype* fntype, const std::string& name, const std::string& asm_name, 484 function(Btype* fntype, const std::string& name, const std::string& asm_name,
488 bool is_visible, bool is_declaration, bool is_inlinable, 485 bool is_visible, bool is_declaration, bool is_inlinable,
489 bool disable_split_stack, bool in_unique_section, Location); 486 bool disable_split_stack, bool does_not_return,
487 bool in_unique_section, Location);
490 488
491 Bstatement* 489 Bstatement*
492 function_defer_statement(Bfunction* function, Bexpression* undefer, 490 function_defer_statement(Bfunction* function, Bexpression* undefer,
493 Bexpression* defer, Location); 491 Bexpression* defer, Location);
494 492
537 Btype* 535 Btype*
538 fill_in_array(Btype*, Btype*, Bexpression*); 536 fill_in_array(Btype*, Btype*, Bexpression*);
539 537
540 tree 538 tree
541 non_zero_size_type(tree); 539 non_zero_size_type(tree);
540
541 tree
542 convert_tree(tree, tree, Location);
542 543
543 private: 544 private:
544 void 545 void
545 define_builtin(built_in_function bcode, const char* name, const char* libname, 546 define_builtin(built_in_function bcode, const char* name, const char* libname,
546 tree fntype, bool const_p, bool noreturn_p); 547 tree fntype, bool const_p, bool noreturn_p);
630 tree math_function_type = build_function_type_list(double_type_node, 631 tree math_function_type = build_function_type_list(double_type_node,
631 double_type_node, 632 double_type_node,
632 NULL_TREE); 633 NULL_TREE);
633 tree math_function_type_long = 634 tree math_function_type_long =
634 build_function_type_list(long_double_type_node, long_double_type_node, 635 build_function_type_list(long_double_type_node, long_double_type_node,
635 long_double_type_node, NULL_TREE); 636 NULL_TREE);
636 tree math_function_type_two = build_function_type_list(double_type_node, 637 tree math_function_type_two = build_function_type_list(double_type_node,
637 double_type_node, 638 double_type_node,
638 double_type_node, 639 double_type_node,
639 NULL_TREE); 640 NULL_TREE);
640 tree math_function_type_long_two = 641 tree math_function_type_long_two =
758 this->define_builtin(BUILT_IN_PREFETCH, "__builtin_prefetch", NULL, 759 this->define_builtin(BUILT_IN_PREFETCH, "__builtin_prefetch", NULL,
759 build_varargs_function_type_list(void_type_node, 760 build_varargs_function_type_list(void_type_node,
760 const_ptr_type_node, 761 const_ptr_type_node,
761 NULL_TREE), 762 NULL_TREE),
762 false, false); 763 false, false);
764
765 // The compiler uses __builtin_unreachable for cases that can not
766 // occur.
767 this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
768 build_function_type(void_type_node, void_list_node),
769 true, true);
763 } 770 }
764 771
765 // Get an unnamed integer type. 772 // Get an unnamed integer type.
766 773
767 Btype* 774 Btype*
950 *pp = field; 957 *pp = field;
951 pp = &DECL_CHAIN(field); 958 pp = &DECL_CHAIN(field);
952 } 959 }
953 TYPE_FIELDS(fill_tree) = field_trees; 960 TYPE_FIELDS(fill_tree) = field_trees;
954 layout_type(fill_tree); 961 layout_type(fill_tree);
962
963 // Because Go permits converting between named struct types and
964 // equivalent struct types, for which we use VIEW_CONVERT_EXPR, and
965 // because we don't try to maintain TYPE_CANONICAL for struct types,
966 // we need to tell the middle-end to use structural equality.
967 SET_TYPE_STRUCTURAL_EQUALITY(fill_tree);
968
955 return fill; 969 return fill;
956 } 970 }
957 971
958 // Make an array type. 972 // Make an array type.
959 973
1084 Btype* r = this->fill_in_struct(placeholder, fields); 1098 Btype* r = this->fill_in_struct(placeholder, fields);
1085 1099
1086 if (TYPE_NAME(t) != NULL_TREE) 1100 if (TYPE_NAME(t) != NULL_TREE)
1087 { 1101 {
1088 // Build the data structure gcc wants to see for a typedef. 1102 // Build the data structure gcc wants to see for a typedef.
1089 tree copy = build_distinct_type_copy(t); 1103 tree copy = build_variant_type_copy(t);
1090 TYPE_NAME(copy) = NULL_TREE; 1104 TYPE_NAME(copy) = NULL_TREE;
1091 DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy; 1105 DECL_ORIGINAL_TYPE(TYPE_NAME(t)) = copy;
1092 } 1106 }
1093 1107
1094 return r->get_tree() != error_mark_node; 1108 return r->get_tree() != error_mark_node;
1185 Gcc_backend::type_size(Btype* btype) 1199 Gcc_backend::type_size(Btype* btype)
1186 { 1200 {
1187 tree t = btype->get_tree(); 1201 tree t = btype->get_tree();
1188 if (t == error_mark_node) 1202 if (t == error_mark_node)
1189 return 1; 1203 return 1;
1204 if (t == void_type_node)
1205 return 0;
1190 t = TYPE_SIZE_UNIT(t); 1206 t = TYPE_SIZE_UNIT(t);
1191 gcc_assert(tree_fits_uhwi_p (t)); 1207 gcc_assert(tree_fits_uhwi_p (t));
1192 unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t); 1208 unsigned HOST_WIDE_INT val_wide = TREE_INT_CST_LOW(t);
1193 int64_t ret = static_cast<int64_t>(val_wide); 1209 int64_t ret = static_cast<int64_t>(val_wide);
1194 if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide) 1210 if (ret < 0 || static_cast<unsigned HOST_WIDE_INT>(ret) != val_wide)
1254 } 1270 }
1255 1271
1256 // An expression that references a variable. 1272 // An expression that references a variable.
1257 1273
1258 Bexpression* 1274 Bexpression*
1259 Gcc_backend::var_expression(Bvariable* var, Varexpr_context, Location location) 1275 Gcc_backend::var_expression(Bvariable* var, Location location)
1260 { 1276 {
1261 tree ret = var->get_tree(location); 1277 tree ret = var->get_tree(location);
1262 if (ret == error_mark_node) 1278 if (ret == error_mark_node)
1263 return this->error_expression(); 1279 return this->error_expression();
1264 return this->make_expression(ret); 1280 return this->make_expression(ret);
1454 || expr_tree == error_mark_node 1470 || expr_tree == error_mark_node
1455 || TREE_TYPE(expr_tree) == error_mark_node) 1471 || TREE_TYPE(expr_tree) == error_mark_node)
1456 return this->error_expression(); 1472 return this->error_expression();
1457 1473
1458 tree ret; 1474 tree ret;
1459 if (this->type_size(type) == 0) 1475 if (this->type_size(type) == 0
1476 || TREE_TYPE(expr_tree) == void_type_node)
1460 { 1477 {
1461 // Do not convert zero-sized types. 1478 // Do not convert zero-sized types.
1462 ret = expr_tree; 1479 ret = expr_tree;
1463 } 1480 }
1464 else if (TREE_CODE(type_tree) == INTEGER_TYPE) 1481 else if (TREE_CODE(type_tree) == INTEGER_TYPE)
1776 } 1793 }
1777 1794
1778 constructor_elt empty = {NULL, NULL}; 1795 constructor_elt empty = {NULL, NULL};
1779 constructor_elt* elt = init->quick_push(empty); 1796 constructor_elt* elt = init->quick_push(empty);
1780 elt->index = field; 1797 elt->index = field;
1781 elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field), 1798 elt->value = this->convert_tree(TREE_TYPE(field), val, location);
1782 val);
1783 if (!TREE_CONSTANT(elt->value)) 1799 if (!TREE_CONSTANT(elt->value))
1784 is_constant = false; 1800 is_constant = false;
1785 } 1801 }
1786 gcc_assert(field == NULL_TREE); 1802 gcc_assert(field == NULL_TREE);
1787 tree ret = build_constructor(type_tree, init); 1803 tree ret = build_constructor(type_tree, init);
1883 if (array_tree == error_mark_node 1899 if (array_tree == error_mark_node
1884 || TREE_TYPE(array_tree) == error_mark_node 1900 || TREE_TYPE(array_tree) == error_mark_node
1885 || index_tree == error_mark_node) 1901 || index_tree == error_mark_node)
1886 return this->error_expression(); 1902 return this->error_expression();
1887 1903
1888 tree ret = build4_loc(location.gcc_location(), ARRAY_REF, 1904 // A function call that returns a zero sized object will have been
1889 TREE_TYPE(TREE_TYPE(array_tree)), array_tree, 1905 // changed to return void. If we see void here, assume we are
1890 index_tree, NULL_TREE, NULL_TREE); 1906 // dealing with a zero sized type and just evaluate the operands.
1907 tree ret;
1908 if (TREE_TYPE(array_tree) != void_type_node)
1909 ret = build4_loc(location.gcc_location(), ARRAY_REF,
1910 TREE_TYPE(TREE_TYPE(array_tree)), array_tree,
1911 index_tree, NULL_TREE, NULL_TREE);
1912 else
1913 ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR,
1914 void_type_node, array_tree, index_tree);
1915
1891 return this->make_expression(ret); 1916 return this->make_expression(ret);
1892 } 1917 }
1893 1918
1894 // Create an expression for a call to FN_EXPR with FN_ARGS. 1919 // Create an expression for a call to FN_EXPR with FN_ARGS.
1895 Bexpression* 1920 Bexpression*
1921 1946
1922 // This is to support builtin math functions when using 80387 math. 1947 // This is to support builtin math functions when using 80387 math.
1923 tree excess_type = NULL_TREE; 1948 tree excess_type = NULL_TREE;
1924 if (optimize 1949 if (optimize
1925 && TREE_CODE(fndecl) == FUNCTION_DECL 1950 && TREE_CODE(fndecl) == FUNCTION_DECL
1926 && DECL_IS_BUILTIN(fndecl) 1951 && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
1927 && DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL 1952 && DECL_IS_BUILTIN (fndecl)
1928 && nargs > 0 1953 && nargs > 0
1929 && ((SCALAR_FLOAT_TYPE_P(rettype) 1954 && ((SCALAR_FLOAT_TYPE_P(rettype)
1930 && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0]))) 1955 && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0])))
1931 || (COMPLEX_FLOAT_TYPE_P(rettype) 1956 || (COMPLEX_FLOAT_TYPE_P(rettype)
1932 && COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[0]))))) 1957 && COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[0])))))
1969 1994
1970 delete[] args; 1995 delete[] args;
1971 return this->make_expression(ret); 1996 return this->make_expression(ret);
1972 } 1997 }
1973 1998
1974 // Return an expression that allocates SIZE bytes on the stack.
1975
1976 Bexpression*
1977 Gcc_backend::stack_allocation_expression(int64_t size, Location location)
1978 {
1979 tree alloca = builtin_decl_explicit(BUILT_IN_ALLOCA);
1980 tree size_tree = build_int_cst(integer_type_node, size);
1981 tree ret = build_call_expr_loc(location.gcc_location(), alloca, 1, size_tree);
1982 tree memset = builtin_decl_explicit(BUILT_IN_MEMSET);
1983 ret = build_call_expr_loc(location.gcc_location(), memset, 3,
1984 ret, integer_zero_node, size_tree);
1985 return this->make_expression(ret);
1986 }
1987
1988 // An expression as a statement. 1999 // An expression as a statement.
1989 2000
1990 Bstatement* 2001 Bstatement*
1991 Gcc_backend::expression_statement(Bfunction*, Bexpression* expr) 2002 Gcc_backend::expression_statement(Bfunction*, Bexpression* expr)
1992 { 2003 {
2009 // initialization of a zero-sized expression to a non-zero sized 2020 // initialization of a zero-sized expression to a non-zero sized
2010 // variable, or vice-versa. Avoid crashes by omitting the 2021 // variable, or vice-versa. Avoid crashes by omitting the
2011 // initializer. Such initializations don't mean anything anyhow. 2022 // initializer. Such initializations don't mean anything anyhow.
2012 if (int_size_in_bytes(TREE_TYPE(var_tree)) != 0 2023 if (int_size_in_bytes(TREE_TYPE(var_tree)) != 0
2013 && init_tree != NULL_TREE 2024 && init_tree != NULL_TREE
2025 && TREE_TYPE(init_tree) != void_type_node
2014 && int_size_in_bytes(TREE_TYPE(init_tree)) != 0) 2026 && int_size_in_bytes(TREE_TYPE(init_tree)) != 0)
2015 { 2027 {
2016 DECL_INITIAL(var_tree) = init_tree; 2028 DECL_INITIAL(var_tree) = init_tree;
2017 init_tree = NULL_TREE; 2029 init_tree = NULL_TREE;
2018 } 2030 }
2041 // externally visible variables. That might lead us to doing an 2053 // externally visible variables. That might lead us to doing an
2042 // assignment of a zero-sized expression to a non-zero sized 2054 // assignment of a zero-sized expression to a non-zero sized
2043 // expression; avoid crashes here by avoiding assignments of 2055 // expression; avoid crashes here by avoiding assignments of
2044 // zero-sized expressions. Such assignments don't really mean 2056 // zero-sized expressions. Such assignments don't really mean
2045 // anything anyhow. 2057 // anything anyhow.
2046 if (int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0 2058 if (TREE_TYPE(lhs_tree) == void_type_node
2059 || int_size_in_bytes(TREE_TYPE(lhs_tree)) == 0
2060 || TREE_TYPE(rhs_tree) == void_type_node
2047 || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0) 2061 || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0)
2048 return this->compound_statement(this->expression_statement(bfn, lhs), 2062 return this->compound_statement(this->expression_statement(bfn, lhs),
2049 this->expression_statement(bfn, rhs)); 2063 this->expression_statement(bfn, rhs));
2050 2064
2051 // Sometimes the same unnamed Go type can be created multiple times 2065 rhs_tree = this->convert_tree(TREE_TYPE(lhs_tree), rhs_tree, location);
2052 // and thus have multiple tree representations. Make sure this does
2053 // not confuse the middle-end.
2054 if (TREE_TYPE(lhs_tree) != TREE_TYPE(rhs_tree))
2055 {
2056 tree lhs_type_tree = TREE_TYPE(lhs_tree);
2057 gcc_assert(TREE_CODE(lhs_type_tree) == TREE_CODE(TREE_TYPE(rhs_tree)));
2058 if (POINTER_TYPE_P(lhs_type_tree)
2059 || INTEGRAL_TYPE_P(lhs_type_tree)
2060 || SCALAR_FLOAT_TYPE_P(lhs_type_tree)
2061 || COMPLEX_FLOAT_TYPE_P(lhs_type_tree))
2062 rhs_tree = fold_convert_loc(location.gcc_location(), lhs_type_tree,
2063 rhs_tree);
2064 else if (TREE_CODE(lhs_type_tree) == RECORD_TYPE
2065 || TREE_CODE(lhs_type_tree) == ARRAY_TYPE)
2066 {
2067 gcc_assert(int_size_in_bytes(lhs_type_tree)
2068 == int_size_in_bytes(TREE_TYPE(rhs_tree)));
2069 rhs_tree = fold_build1_loc(location.gcc_location(),
2070 VIEW_CONVERT_EXPR,
2071 lhs_type_tree, rhs_tree);
2072 }
2073 }
2074 2066
2075 return this->make_statement(fold_build2_loc(location.gcc_location(), 2067 return this->make_statement(fold_build2_loc(location.gcc_location(),
2076 MODIFY_EXPR, 2068 MODIFY_EXPR,
2077 void_type_node, 2069 void_type_node,
2078 lhs_tree, rhs_tree)); 2070 lhs_tree, rhs_tree));
2287 pop_cfun(); 2279 pop_cfun();
2288 2280
2289 tree tv = value->get_tree(); 2281 tree tv = value->get_tree();
2290 if (tv == error_mark_node) 2282 if (tv == error_mark_node)
2291 return this->error_statement(); 2283 return this->error_statement();
2292 tree t = build3_loc(switch_location.gcc_location(), SWITCH_EXPR, 2284 tree t = build2_loc(switch_location.gcc_location(), SWITCH_EXPR,
2293 NULL_TREE, tv, stmt_list, NULL_TREE); 2285 NULL_TREE, tv, stmt_list);
2294 return this->make_statement(t); 2286 return this->make_statement(t);
2295 } 2287 }
2296 2288
2297 // Pair of statements. 2289 // Pair of statements.
2298 2290
2498 } 2490 }
2499 2491
2500 gcc_unreachable(); 2492 gcc_unreachable();
2501 } 2493 }
2502 2494
2495 // Convert EXPR_TREE to TYPE_TREE. Sometimes the same unnamed Go type
2496 // can be created multiple times and thus have multiple tree
2497 // representations. Make sure this does not confuse the middle-end.
2498
2499 tree
2500 Gcc_backend::convert_tree(tree type_tree, tree expr_tree, Location location)
2501 {
2502 if (type_tree == TREE_TYPE(expr_tree))
2503 return expr_tree;
2504
2505 if (type_tree == error_mark_node
2506 || expr_tree == error_mark_node
2507 || TREE_TYPE(expr_tree) == error_mark_node)
2508 return error_mark_node;
2509
2510 gcc_assert(TREE_CODE(type_tree) == TREE_CODE(TREE_TYPE(expr_tree)));
2511 if (POINTER_TYPE_P(type_tree)
2512 || INTEGRAL_TYPE_P(type_tree)
2513 || SCALAR_FLOAT_TYPE_P(type_tree)
2514 || COMPLEX_FLOAT_TYPE_P(type_tree))
2515 return fold_convert_loc(location.gcc_location(), type_tree, expr_tree);
2516 else if (TREE_CODE(type_tree) == RECORD_TYPE
2517 || TREE_CODE(type_tree) == ARRAY_TYPE)
2518 {
2519 gcc_assert(int_size_in_bytes(type_tree)
2520 == int_size_in_bytes(TREE_TYPE(expr_tree)));
2521 if (TYPE_MAIN_VARIANT(type_tree)
2522 == TYPE_MAIN_VARIANT(TREE_TYPE(expr_tree)))
2523 return fold_build1_loc(location.gcc_location(), NOP_EXPR,
2524 type_tree, expr_tree);
2525 return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
2526 type_tree, expr_tree);
2527 }
2528
2529 gcc_unreachable();
2530 }
2531
2503 // Make a global variable. 2532 // Make a global variable.
2504 2533
2505 Bvariable* 2534 Bvariable*
2506 Gcc_backend::global_variable(const std::string& var_name, 2535 Gcc_backend::global_variable(const std::string& var_name,
2507 const std::string& asm_name, 2536 const std::string& asm_name,
2575 2604
2576 // Make a local variable. 2605 // Make a local variable.
2577 2606
2578 Bvariable* 2607 Bvariable*
2579 Gcc_backend::local_variable(Bfunction* function, const std::string& name, 2608 Gcc_backend::local_variable(Bfunction* function, const std::string& name,
2580 Btype* btype, bool is_address_taken, 2609 Btype* btype, Bvariable* decl_var,
2581 Location location) 2610 bool is_address_taken, Location location)
2582 { 2611 {
2583 tree type_tree = btype->get_tree(); 2612 tree type_tree = btype->get_tree();
2584 if (type_tree == error_mark_node) 2613 if (type_tree == error_mark_node)
2585 return this->error_variable(); 2614 return this->error_variable();
2586 tree decl = build_decl(location.gcc_location(), VAR_DECL, 2615 tree decl = build_decl(location.gcc_location(), VAR_DECL,
2588 type_tree); 2617 type_tree);
2589 DECL_CONTEXT(decl) = function->get_tree(); 2618 DECL_CONTEXT(decl) = function->get_tree();
2590 TREE_USED(decl) = 1; 2619 TREE_USED(decl) = 1;
2591 if (is_address_taken) 2620 if (is_address_taken)
2592 TREE_ADDRESSABLE(decl) = 1; 2621 TREE_ADDRESSABLE(decl) = 1;
2622 if (decl_var != NULL)
2623 {
2624 DECL_HAS_VALUE_EXPR_P(decl) = 1;
2625 SET_DECL_VALUE_EXPR(decl, decl_var->get_decl());
2626 }
2593 go_preserve_from_gc(decl); 2627 go_preserve_from_gc(decl);
2594 return new Bvariable(decl); 2628 return new Bvariable(decl);
2595 } 2629 }
2596 2630
2597 // Make a function parameter variable. 2631 // Make a function parameter variable.
2702 DECL_CHAIN(var) = BLOCK_VARS(block_tree); 2736 DECL_CHAIN(var) = BLOCK_VARS(block_tree);
2703 BLOCK_VARS(block_tree) = var; 2737 BLOCK_VARS(block_tree) = var;
2704 BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree); 2738 BIND_EXPR_VARS(bind_tree) = BLOCK_VARS(block_tree);
2705 } 2739 }
2706 2740
2707 if (this->type_size(btype) != 0 && init_tree != NULL_TREE) 2741 if (this->type_size(btype) != 0
2708 DECL_INITIAL(var) = fold_convert_loc(location.gcc_location(), type_tree, 2742 && init_tree != NULL_TREE
2709 init_tree); 2743 && TREE_TYPE(init_tree) != void_type_node)
2744 DECL_INITIAL(var) = this->convert_tree(type_tree, init_tree, location);
2710 2745
2711 if (is_address_taken) 2746 if (is_address_taken)
2712 TREE_ADDRESSABLE(var) = 1; 2747 TREE_ADDRESSABLE(var) = 1;
2713 2748
2714 *pstatement = this->make_statement(build1_loc(location.gcc_location(), 2749 *pstatement = this->make_statement(build1_loc(location.gcc_location(),
2715 DECL_EXPR, 2750 DECL_EXPR,
2716 void_type_node, var)); 2751 void_type_node, var));
2717 2752
2718 // Don't initialize VAR with BINIT, but still evaluate BINIT for 2753 // For a zero sized type, don't initialize VAR with BINIT, but still
2719 // its side effects. 2754 // evaluate BINIT for its side effects.
2720 if (this->type_size(btype) == 0 && init_tree != NULL_TREE) 2755 if (init_tree != NULL_TREE
2756 && (this->type_size(btype) == 0
2757 || TREE_TYPE(init_tree) == void_type_node))
2721 *pstatement = 2758 *pstatement =
2722 this->compound_statement(this->expression_statement(function, binit), 2759 this->compound_statement(this->expression_statement(function, binit),
2723 *pstatement); 2760 *pstatement);
2724 2761
2725 return new Bvariable(var); 2762 return new Bvariable(var);
3010 3047
3011 Bfunction* 3048 Bfunction*
3012 Gcc_backend::function(Btype* fntype, const std::string& name, 3049 Gcc_backend::function(Btype* fntype, const std::string& name,
3013 const std::string& asm_name, bool is_visible, 3050 const std::string& asm_name, bool is_visible,
3014 bool is_declaration, bool is_inlinable, 3051 bool is_declaration, bool is_inlinable,
3015 bool disable_split_stack, bool in_unique_section, 3052 bool disable_split_stack, bool does_not_return,
3016 Location location) 3053 bool in_unique_section, Location location)
3017 { 3054 {
3018 tree functype = fntype->get_tree(); 3055 tree functype = fntype->get_tree();
3019 if (functype != error_mark_node) 3056 if (functype != error_mark_node)
3020 { 3057 {
3021 gcc_assert(FUNCTION_POINTER_TYPE_P(functype)); 3058 gcc_assert(FUNCTION_POINTER_TYPE_P(functype));
3047 if (disable_split_stack) 3084 if (disable_split_stack)
3048 { 3085 {
3049 tree attr = get_identifier ("no_split_stack"); 3086 tree attr = get_identifier ("no_split_stack");
3050 DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE); 3087 DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE);
3051 } 3088 }
3089 if (does_not_return)
3090 TREE_THIS_VOLATILE(decl) = 1;
3052 if (in_unique_section) 3091 if (in_unique_section)
3053 resolve_unique_section(decl, 0, 1); 3092 resolve_unique_section(decl, 0, 1);
3054 3093
3055 go_preserve_from_gc(decl); 3094 go_preserve_from_gc(decl);
3056 return new Bfunction(decl); 3095 return new Bfunction(decl);