aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/backend/rust-compile-base.cc103
-rw-r--r--gcc/rust/backend/rust-compile-base.h34
-rw-r--r--gcc/rust/backend/rust-compile-block.cc41
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc149
-rw-r--r--gcc/rust/backend/rust-compile-implitem.cc13
-rw-r--r--gcc/rust/backend/rust-compile-item.cc10
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc6
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc6
-rw-r--r--gcc/rust/backend/rust-compile-type.cc31
-rw-r--r--gcc/rust/backend/rust-compile-type.h2
-rw-r--r--gcc/rust/backend/rust-constexpr.cc1
-rw-r--r--gcc/rust/rust-backend.h11
-rw-r--r--gcc/rust/rust-gcc.cc116
-rw-r--r--gcc/testsuite/rust/compile/issue-2188.rs1
14 files changed, 205 insertions, 319 deletions
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 60ae25c..70147a3 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -35,6 +35,7 @@
#include "stringpool.h"
#include "attribs.h"
#include "tree.h"
+#include "print-tree.h"
namespace Rust {
namespace Compile {
@@ -466,9 +467,9 @@ HIRCompileBase::compile_locals_for_block (Context *ctx, Resolver::Rib &rib,
}
void
-HIRCompileBase::compile_function_body (Context *ctx, tree fndecl,
+HIRCompileBase::compile_function_body (tree fndecl,
HIR::BlockExpr &function_body,
- bool has_return_type)
+ TyTy::BaseType *fn_return_ty)
{
for (auto &s : function_body.get_statements ())
{
@@ -482,40 +483,48 @@ HIRCompileBase::compile_function_body (Context *ctx, tree fndecl,
if (function_body.has_expr ())
{
- // the previous passes will ensure this is a valid return
- // or a valid trailing expression
- tree compiled_expr
- = CompileExpr::Compile (function_body.expr.get (), ctx);
+ Location locus = function_body.get_final_expr ()->get_locus ();
+ tree return_value = CompileExpr::Compile (function_body.expr.get (), ctx);
- if (compiled_expr != nullptr)
+ // we can only return this if non unit value return type
+ if (!fn_return_ty->is_unit ())
{
- if (has_return_type)
- {
- std::vector<tree> retstmts;
- retstmts.push_back (compiled_expr);
-
- auto ret = ctx->get_backend ()->return_statement (
- fndecl, retstmts,
- function_body.get_final_expr ()->get_locus ());
- ctx->add_statement (ret);
- }
- else
- {
- // FIXME can this actually happen?
- ctx->add_statement (compiled_expr);
- }
+ tree return_stmt
+ = ctx->get_backend ()->return_statement (fndecl, return_value,
+ locus);
+ ctx->add_statement (return_stmt);
}
+ else
+ {
+ // just add the stmt expression
+ ctx->add_statement (return_value);
+
+ // now just return unit expression
+ tree unit_expr = unit_expression (ctx, locus);
+ tree return_stmt
+ = ctx->get_backend ()->return_statement (fndecl, unit_expr, locus);
+ ctx->add_statement (return_stmt);
+ }
+ }
+ else if (fn_return_ty->is_unit ())
+ {
+ // we can only do this if the function is of unit type otherwise other
+ // errors should have occurred
+ Location locus = function_body.get_locus ();
+ tree return_value = unit_expression (ctx, locus);
+ tree return_stmt
+ = ctx->get_backend ()->return_statement (fndecl, return_value, locus);
+ ctx->add_statement (return_stmt);
}
}
tree
HIRCompileBase::compile_function (
- Context *ctx, const std::string &fn_name, HIR::SelfParam &self_param,
+ const std::string &fn_name, HIR::SelfParam &self_param,
std::vector<HIR::FunctionParam> &function_params,
const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility,
AST::AttrVec &outer_attrs, Location locus, HIR::BlockExpr *function_body,
- const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype,
- bool function_has_return)
+ const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype)
{
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
std::string ir_symbol_name
@@ -606,24 +615,19 @@ HIRCompileBase::compile_function (
ctx->push_block (code_block);
Bvariable *return_address = nullptr;
- if (function_has_return)
- {
- tree return_type = TyTyResolveCompile::compile (ctx, tyret);
-
- bool address_is_taken = false;
- tree ret_var_stmt = NULL_TREE;
+ tree return_type = TyTyResolveCompile::compile (ctx, tyret);
- return_address
- = ctx->get_backend ()->temporary_variable (fndecl, code_block,
- return_type, NULL,
- address_is_taken, locus,
- &ret_var_stmt);
+ bool address_is_taken = false;
+ tree ret_var_stmt = NULL_TREE;
+ return_address
+ = ctx->get_backend ()->temporary_variable (fndecl, code_block, return_type,
+ NULL, address_is_taken, locus,
+ &ret_var_stmt);
- ctx->add_statement (ret_var_stmt);
- }
+ ctx->add_statement (ret_var_stmt);
ctx->push_fn (fndecl, return_address);
- compile_function_body (ctx, fndecl, *function_body, function_has_return);
+ compile_function_body (fndecl, *function_body, tyret);
tree bind_tree = ctx->pop_block ();
gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
@@ -642,14 +646,13 @@ HIRCompileBase::compile_function (
tree
HIRCompileBase::compile_constant_item (
- Context *ctx, TyTy::BaseType *resolved_type,
- const Resolver::CanonicalPath *canonical_path, HIR::Expr *const_value_expr,
- Location locus)
+ TyTy::BaseType *resolved_type, const Resolver::CanonicalPath *canonical_path,
+ HIR::Expr *const_value_expr, Location locus)
{
const std::string &ident = canonical_path->get ();
+
tree type = TyTyResolveCompile::compile (ctx, resolved_type);
tree const_type = build_qualified_type (type, TYPE_QUAL_CONST);
-
bool is_block_expr
= const_value_expr->get_expression_type () == HIR::Expr::ExprType::Block;
@@ -661,7 +664,6 @@ HIRCompileBase::compile_constant_item (
tree compiled_fn_type = ctx->get_backend ()->function_type (
receiver, {}, {Backend::typed_identifier ("_", const_type, locus)}, NULL,
locus);
-
tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, locus);
TREE_READONLY (fndecl) = 1;
@@ -703,13 +705,14 @@ HIRCompileBase::compile_constant_item (
{
HIR::BlockExpr *function_body
= static_cast<HIR::BlockExpr *> (const_value_expr);
- compile_function_body (ctx, fndecl, *function_body, true);
+ compile_function_body (fndecl, *function_body, resolved_type);
}
else
{
tree value = CompileExpr::Compile (const_value_expr, ctx);
+
tree return_expr = ctx->get_backend ()->return_statement (
- fndecl, {value}, const_value_expr->get_locus ());
+ fndecl, value, const_value_expr->get_locus ());
ctx->add_statement (return_expr);
}
@@ -831,5 +834,13 @@ HIRCompileBase::resolve_method_address (
return CompileInherentImplItem::Compile (impl_item, ctx, monomorphized);
}
+tree
+HIRCompileBase::unit_expression (Context *ctx, Location locus)
+{
+ tree unit_type = TyTyResolveCompile::get_unit_type (ctx);
+ return ctx->get_backend ()->constructor_expression (unit_type, false, {}, -1,
+ locus);
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index 7a5c9cb..db47c0f 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -86,6 +86,23 @@ protected:
const Analysis::NodeMapping &expr_mappings,
Location expr_locus);
+ void compile_function_body (tree fndecl, HIR::BlockExpr &function_body,
+ TyTy::BaseType *fn_return_ty);
+
+ tree compile_constant_item (TyTy::BaseType *resolved_type,
+ const Resolver::CanonicalPath *canonical_path,
+ HIR::Expr *const_value_expr, Location locus);
+
+ tree compile_function (const std::string &fn_name, HIR::SelfParam &self_param,
+ std::vector<HIR::FunctionParam> &function_params,
+ const HIR::FunctionQualifiers &qualifiers,
+ HIR::Visibility &visibility, AST::AttrVec &outer_attrs,
+ Location locus, HIR::BlockExpr *function_body,
+ const Resolver::CanonicalPath *canonical_path,
+ TyTy::FnType *fntype);
+
+ static tree unit_expression (Context *ctx, Location locus);
+
static void setup_fndecl (tree fndecl, bool is_main_entry_point,
bool is_generic_fn, HIR::Visibility &visibility,
const HIR::FunctionQualifiers &qualifiers,
@@ -121,23 +138,6 @@ protected:
static std::vector<Bvariable *>
compile_locals_for_block (Context *ctx, Resolver::Rib &rib, tree fndecl);
- static void compile_function_body (Context *ctx, tree fndecl,
- HIR::BlockExpr &function_body,
- bool has_return_type);
-
- static tree compile_function (
- Context *ctx, const std::string &fn_name, HIR::SelfParam &self_param,
- std::vector<HIR::FunctionParam> &function_params,
- const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility,
- AST::AttrVec &outer_attrs, Location locus, HIR::BlockExpr *function_body,
- const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype,
- bool function_has_return);
-
- static tree
- compile_constant_item (Context *ctx, TyTy::BaseType *resolved_type,
- const Resolver::CanonicalPath *canonical_path,
- HIR::Expr *const_value_expr, Location locus);
-
static tree named_constant_expression (tree type_tree,
const std::string &name,
tree const_val, Location location);
diff --git a/gcc/rust/backend/rust-compile-block.cc b/gcc/rust/backend/rust-compile-block.cc
index 470ece2..5591d95 100644
--- a/gcc/rust/backend/rust-compile-block.cc
+++ b/gcc/rust/backend/rust-compile-block.cc
@@ -71,28 +71,33 @@ CompileBlock::visit (HIR::BlockExpr &expr)
if (expr.has_expr ())
{
- // the previous passes will ensure this is a valid return or
- // a valid trailing expression
tree compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
- if (compiled_expr != nullptr)
+ if (result != nullptr)
{
- if (result == nullptr)
- {
- ctx->add_statement (compiled_expr);
- }
- else
- {
- tree result_reference = ctx->get_backend ()->var_expression (
- result, expr.get_final_expr ()->get_locus ());
-
- tree assignment
- = ctx->get_backend ()->assignment_statement (result_reference,
- compiled_expr,
- expr.get_locus ());
- ctx->add_statement (assignment);
- }
+ Location locus = expr.get_final_expr ()->get_locus ();
+ tree result_reference
+ = ctx->get_backend ()->var_expression (result, locus);
+
+ tree assignment
+ = ctx->get_backend ()->assignment_statement (result_reference,
+ compiled_expr,
+ expr.get_locus ());
+ ctx->add_statement (assignment);
}
}
+ else if (result != nullptr)
+ {
+ Location locus = expr.get_locus ();
+ tree compiled_expr = unit_expression (ctx, expr.get_locus ());
+ tree result_reference
+ = ctx->get_backend ()->var_expression (result, locus);
+
+ tree assignment
+ = ctx->get_backend ()->assignment_statement (result_reference,
+ compiled_expr,
+ expr.get_locus ());
+ ctx->add_statement (assignment);
+ }
ctx->pop_block ();
translated = new_block;
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index e108704..07e5d79 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -76,7 +76,7 @@ CompileExpr::visit (HIR::TupleExpr &expr)
{
if (expr.is_unit ())
{
- translated = ctx->get_backend ()->unit_expression ();
+ translated = unit_expression (ctx, expr.get_locus ());
return;
}
@@ -110,18 +110,13 @@ CompileExpr::visit (HIR::ReturnExpr &expr)
{
auto fncontext = ctx->peek_fn ();
- std::vector<tree> retstmts;
- if (expr.has_return_expr ())
- {
- tree compiled_expr = CompileExpr::Compile (expr.return_expr.get (), ctx);
- rust_assert (compiled_expr != nullptr);
-
- retstmts.push_back (compiled_expr);
- }
-
- auto s = ctx->get_backend ()->return_statement (fncontext.fndecl, retstmts,
- expr.get_locus ());
- ctx->add_statement (s);
+ tree return_value = expr.has_return_expr ()
+ ? CompileExpr::Compile (expr.return_expr.get (), ctx)
+ : unit_expression (ctx, expr.get_locus ());
+ tree return_stmt
+ = ctx->get_backend ()->return_statement (fncontext.fndecl, return_value,
+ expr.get_locus ());
+ ctx->add_statement (return_stmt);
}
void
@@ -318,28 +313,23 @@ CompileExpr::visit (HIR::IfExprConseqElse &expr)
}
Bvariable *tmp = NULL;
- bool needs_temp = !if_type->is_unit ();
- if (needs_temp)
- {
- fncontext fnctx = ctx->peek_fn ();
- tree enclosing_scope = ctx->peek_enclosing_scope ();
- tree block_type = TyTyResolveCompile::compile (ctx, if_type);
+ fncontext fnctx = ctx->peek_fn ();
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, if_type);
- bool is_address_taken = false;
- tree ret_var_stmt = nullptr;
- tmp = ctx->get_backend ()->temporary_variable (
- fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
- expr.get_locus (), &ret_var_stmt);
- ctx->add_statement (ret_var_stmt);
- }
+ bool is_address_taken = false;
+ tree ret_var_stmt = nullptr;
+ tmp = ctx->get_backend ()->temporary_variable (fnctx.fndecl, enclosing_scope,
+ block_type, NULL,
+ is_address_taken,
+ expr.get_locus (),
+ &ret_var_stmt);
+ ctx->add_statement (ret_var_stmt);
auto stmt = CompileConditionalBlocks::compile (&expr, ctx, tmp);
ctx->add_statement (stmt);
- if (tmp != NULL)
- {
- translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
- }
+ translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
}
void
@@ -354,29 +344,24 @@ CompileExpr::visit (HIR::BlockExpr &expr)
}
Bvariable *tmp = NULL;
- bool needs_temp = !block_tyty->is_unit ();
- if (needs_temp)
- {
- fncontext fnctx = ctx->peek_fn ();
- tree enclosing_scope = ctx->peek_enclosing_scope ();
- tree block_type = TyTyResolveCompile::compile (ctx, block_tyty);
+ fncontext fnctx = ctx->peek_fn ();
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, block_tyty);
- bool is_address_taken = false;
- tree ret_var_stmt = nullptr;
- tmp = ctx->get_backend ()->temporary_variable (
- fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
- expr.get_locus (), &ret_var_stmt);
- ctx->add_statement (ret_var_stmt);
- }
+ bool is_address_taken = false;
+ tree ret_var_stmt = nullptr;
+ tmp = ctx->get_backend ()->temporary_variable (fnctx.fndecl, enclosing_scope,
+ block_type, NULL,
+ is_address_taken,
+ expr.get_locus (),
+ &ret_var_stmt);
+ ctx->add_statement (ret_var_stmt);
auto block_stmt = CompileBlock::compile (&expr, ctx, tmp);
rust_assert (TREE_CODE (block_stmt) == BIND_EXPR);
ctx->add_statement (block_stmt);
- if (tmp != NULL)
- {
- translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
- }
+ translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
}
void
@@ -397,7 +382,7 @@ CompileExpr::visit (HIR::StructExprStruct &struct_expr)
}
rust_assert (tyty->is_unit ());
- translated = ctx->get_backend ()->unit_expression ();
+ translated = unit_expression (ctx, struct_expr.get_locus ());
}
void
@@ -1318,19 +1303,17 @@ CompileExpr::visit (HIR::MatchExpr &expr)
fncontext fnctx = ctx->peek_fn ();
Bvariable *tmp = NULL;
- bool needs_temp = !expr_tyty->is_unit ();
- if (needs_temp)
- {
- tree enclosing_scope = ctx->peek_enclosing_scope ();
- tree block_type = TyTyResolveCompile::compile (ctx, expr_tyty);
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, expr_tyty);
- bool is_address_taken = false;
- tree ret_var_stmt = nullptr;
- tmp = ctx->get_backend ()->temporary_variable (
- fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
- expr.get_locus (), &ret_var_stmt);
- ctx->add_statement (ret_var_stmt);
- }
+ bool is_address_taken = false;
+ tree ret_var_stmt = nullptr;
+ tmp = ctx->get_backend ()->temporary_variable (fnctx.fndecl, enclosing_scope,
+ block_type, NULL,
+ is_address_taken,
+ expr.get_locus (),
+ &ret_var_stmt);
+ ctx->add_statement (ret_var_stmt);
// lets compile the scrutinee expression
tree match_scrutinee_expr
@@ -1450,7 +1433,6 @@ CompileExpr::visit (HIR::MatchExpr &expr)
// setup the switch-body-block
Location start_location; // FIXME
Location end_location; // FIXME
- tree enclosing_scope = ctx->peek_enclosing_scope ();
tree switch_body_block
= ctx->get_backend ()->block (fndecl, enclosing_scope, {}, start_location,
end_location);
@@ -1481,16 +1463,12 @@ CompileExpr::visit (HIR::MatchExpr &expr)
// compile the expr and setup the assignment if required when tmp != NULL
tree kase_expr_tree = CompileExpr::Compile (kase.get_expr ().get (), ctx);
- if (tmp != NULL)
- {
- tree result_reference
- = ctx->get_backend ()->var_expression (tmp, arm_locus);
- tree assignment
- = ctx->get_backend ()->assignment_statement (result_reference,
- kase_expr_tree,
- arm_locus);
- ctx->add_statement (assignment);
- }
+ tree result_reference
+ = ctx->get_backend ()->var_expression (tmp, arm_locus);
+ tree assignment
+ = ctx->get_backend ()->assignment_statement (result_reference,
+ kase_expr_tree, arm_locus);
+ ctx->add_statement (assignment);
// go to end label
tree goto_end_label = build1_loc (arm_locus.gcc_location (), GOTO_EXPR,
@@ -1507,10 +1485,7 @@ CompileExpr::visit (HIR::MatchExpr &expr)
ctx->add_statement (match_expr_stmt);
ctx->add_statement (end_label_decl_statement);
- if (tmp != NULL)
- {
- translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
- }
+ translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
}
void
@@ -2824,34 +2799,32 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,
ctx->push_block (code_block);
TyTy::BaseType *tyret = &closure_tyty.get_result_type ();
- bool function_has_return = !closure_tyty.get_result_type ().is_unit ();
Bvariable *return_address = nullptr;
- if (function_has_return)
- {
- tree return_type = TyTyResolveCompile::compile (ctx, tyret);
- bool address_is_taken = false;
- tree ret_var_stmt = NULL_TREE;
+ tree return_type = TyTyResolveCompile::compile (ctx, tyret);
+ bool address_is_taken = false;
+ tree ret_var_stmt = NULL_TREE;
- return_address = ctx->get_backend ()->temporary_variable (
- fndecl, code_block, return_type, NULL, address_is_taken,
- expr.get_locus (), &ret_var_stmt);
+ return_address
+ = ctx->get_backend ()->temporary_variable (fndecl, code_block, return_type,
+ NULL, address_is_taken,
+ expr.get_locus (),
+ &ret_var_stmt);
- ctx->add_statement (ret_var_stmt);
- }
+ ctx->add_statement (ret_var_stmt);
ctx->push_fn (fndecl, return_address);
if (is_block_expr)
{
HIR::BlockExpr *body = static_cast<HIR::BlockExpr *> (function_body);
- compile_function_body (ctx, fndecl, *body, true);
+ compile_function_body (fndecl, *body, tyret);
}
else
{
tree value = CompileExpr::Compile (function_body, ctx);
tree return_expr
- = ctx->get_backend ()->return_statement (fndecl, {value},
+ = ctx->get_backend ()->return_statement (fndecl, value,
function_body->get_locus ());
ctx->add_statement (return_expr);
}
diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc
index b207594..445a153 100644
--- a/gcc/rust/backend/rust-compile-implitem.cc
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -17,8 +17,6 @@
// <http://www.gnu.org/licenses/>.
#include "rust-compile-implitem.h"
-#include "rust-compile-expr.h"
-#include "rust-compile-fnparam.h"
namespace Rust {
namespace Compile {
@@ -36,8 +34,8 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
HIR::Expr *const_value_expr = constant.get_expr ().get ();
tree const_expr
- = compile_constant_item (ctx, resolved_type, canonical_path,
- const_value_expr, constant.get_locus ());
+ = compile_constant_item (resolved_type, canonical_path, const_value_expr,
+ constant.get_locus ());
ctx->push_const (const_expr);
ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
@@ -88,12 +86,11 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func)
auto vis = HIR::Visibility (HIR::Visibility::VisType::PUBLIC);
HIR::TraitFunctionDecl &function = func.get_decl ();
tree fndecl
- = compile_function (ctx, function.get_function_name (),
- function.get_self (), function.get_function_params (),
+ = compile_function (function.get_function_name (), function.get_self (),
+ function.get_function_params (),
function.get_qualifiers (), vis,
func.get_outer_attrs (), func.get_locus (),
- func.get_block_expr ().get (), canonical_path, fntype,
- function.has_return_type ());
+ func.get_block_expr ().get (), canonical_path, fntype);
reference = address_expression (fndecl, ref_locus);
}
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index d953e4b1..26f56c7 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -49,7 +49,7 @@ CompileItem::visit (HIR::StaticItem &var)
HIR::Expr *const_value_expr = var.get_expr ();
ctx->push_const_context ();
- tree value = compile_constant_item (ctx, resolved_type, canonical_path,
+ tree value = compile_constant_item (resolved_type, canonical_path,
const_value_expr, var.get_locus ());
ctx->pop_const_context ();
@@ -97,8 +97,8 @@ CompileItem::visit (HIR::ConstantItem &constant)
HIR::Expr *const_value_expr = constant.get_expr ();
ctx->push_const_context ();
tree const_expr
- = compile_constant_item (ctx, resolved_type, canonical_path,
- const_value_expr, constant.get_locus ());
+ = compile_constant_item (resolved_type, canonical_path, const_value_expr,
+ constant.get_locus ());
ctx->pop_const_context ();
ctx->push_const (const_expr);
@@ -161,13 +161,13 @@ CompileItem::visit (HIR::Function &function)
ctx->push_const_context ();
tree fndecl
- = compile_function (ctx, function.get_function_name (),
+ = compile_function (function.get_function_name (),
function.get_self_param (),
function.get_function_params (),
function.get_qualifiers (), function.get_visibility (),
function.get_outer_attrs (), function.get_locus (),
function.get_definition ().get (), canonical_path,
- fntype, function.has_function_return_type ());
+ fntype);
reference = address_expression (fndecl, ref_locus);
if (function.get_qualifiers ().is_const ())
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index a96b1b9..742dfa0 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -359,11 +359,7 @@ CompilePatternLet::visit (HIR::IdentifierPattern &pattern)
{
ctx->add_statement (init_expr);
- tree stmt_type = TyTyResolveCompile::compile (ctx, ty);
-
- auto unit_type_init_expr
- = ctx->get_backend ()->constructor_expression (stmt_type, false, {}, -1,
- rval_locus);
+ auto unit_type_init_expr = unit_expression (ctx, rval_locus);
auto s = ctx->get_backend ()->init_statement (fnctx.fndecl, var,
unit_type_init_expr);
ctx->add_statement (s);
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index cbe2f67..97cfe9c 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -65,12 +65,8 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
return error_mark_node;
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (lookup);
-
- // it might be a unit-struct
if (adt->is_unit ())
- {
- return ctx->get_backend ()->unit_expression ();
- }
+ return unit_expression (ctx, expr_locus);
if (!adt->is_enum ())
return error_mark_node;
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc
index f0c6547..fc58be9 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -86,6 +86,20 @@ TyTyResolveCompile::get_implicit_enumeral_node_type (Context *ctx)
return enum_node;
}
+tree
+TyTyResolveCompile::get_unit_type (Context *ctx)
+{
+ static tree unit_type;
+ if (unit_type == nullptr)
+ {
+ auto unit_type_node = ctx->get_backend ()->struct_type ({});
+ unit_type
+ = ctx->get_backend ()->named_type ("()", unit_type_node,
+ Linemap::predeclared_location ());
+ }
+ return unit_type;
+}
+
void
TyTyResolveCompile::visit (const TyTy::ErrorType &)
{
@@ -163,14 +177,11 @@ TyTyResolveCompile::visit (const TyTy::FnType &type)
std::vector<Backend::typed_identifier> parameters;
std::vector<Backend::typed_identifier> results;
- if (!type.get_return_type ()->is_unit ())
- {
- auto hir_type = type.get_return_type ();
- auto ret = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode);
- results.push_back (Backend::typed_identifier (
- "_", ret,
- ctx->get_mappings ()->lookup_location (hir_type->get_ref ())));
- }
+ auto hir_type = type.get_return_type ();
+ auto ret = TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode);
+ Location return_type_locus
+ = ctx->get_mappings ()->lookup_location (hir_type->get_ref ());
+ results.push_back (Backend::typed_identifier ("_", ret, return_type_locus));
for (auto &param_pair : type.get_params ())
{
@@ -362,7 +373,7 @@ TyTyResolveCompile::visit (const TyTy::TupleType &type)
{
if (type.num_fields () == 0)
{
- translated = ctx->get_backend ()->unit_type ();
+ translated = get_unit_type (ctx);
return;
}
@@ -651,7 +662,7 @@ TyTyResolveCompile::visit (const TyTy::StrType &type)
void
TyTyResolveCompile::visit (const TyTy::NeverType &)
{
- translated = ctx->get_backend ()->unit_type ();
+ translated = get_unit_type (ctx);
}
void
diff --git a/gcc/rust/backend/rust-compile-type.h b/gcc/rust/backend/rust-compile-type.h
index 3abf143..ce13795 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -32,6 +32,8 @@ public:
static tree get_implicit_enumeral_node_type (Context *ctx);
+ static tree get_unit_type (Context *ctx);
+
void visit (const TyTy::InferType &) override;
void visit (const TyTy::ADTType &) override;
void visit (const TyTy::TupleType &) override;
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index a7ae416..3fd1b96 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -2247,7 +2247,6 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval,
/* Don't VERIFY_CONSTANT here. */
if (*non_constant_p)
return t;
- gcc_checking_assert (TREE_CODE (op) != CONSTRUCTOR);
/* This function does more aggressive folding than fold itself. */
r = build_fold_addr_expr_with_type (op, TREE_TYPE (t));
if (TREE_CODE (r) == ADDR_EXPR && TREE_OPERAND (r, 0) == oldop)
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 3726f74..ad497e4 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -70,9 +70,6 @@ public:
// Types.
- // get unit-type
- virtual tree unit_type () = 0;
-
// Get the unnamed boolean type.
virtual tree bool_type () = 0;
@@ -173,8 +170,6 @@ public:
// converting nil to other types.
virtual tree zero_expression (tree) = 0;
- virtual tree unit_expression () = 0;
-
// Create a reference to a variable.
virtual tree var_expression (Bvariable *var, Location) = 0;
@@ -302,9 +297,9 @@ public:
// Create an assignment statement within the specified function.
virtual tree assignment_statement (tree lhs, tree rhs, Location) = 0;
- // Create a return statement, passing the representation of the
- // function and the list of values to return.
- virtual tree return_statement (tree, const std::vector<tree> &, Location) = 0;
+ // Create return statement for an decl for a value (can be NULL_TREE) at a
+ // location
+ virtual tree return_statement (tree fndecl, tree val, Location) = 0;
// Create an if statement within a function. ELSE_BLOCK may be NULL.
virtual tree if_statement (tree, tree condition, tree then_block,
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index d406b59..c86804e 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -98,19 +98,6 @@ public:
// Types.
- tree unit_type ()
- {
- static tree unit_type;
- if (unit_type == nullptr)
- {
- auto unit_type_node = struct_type ({});
- unit_type = named_type ("()", unit_type_node,
- ::Linemap::predeclared_location ());
- }
-
- return unit_type;
- }
-
tree bool_type () { return boolean_type_node; }
tree char_type () { return char_type_node; }
@@ -170,8 +157,6 @@ public:
tree zero_expression (tree);
- tree unit_expression () { return integer_zero_node; }
-
tree var_expression (Bvariable *var, Location);
tree integer_constant_expression (tree type, mpz_t val);
@@ -236,7 +221,7 @@ public:
tree assignment_statement (tree lhs, tree rhs, Location);
- tree return_statement (tree, const std::vector<tree> &, Location);
+ tree return_statement (tree fndecl, tree val, Location locus);
tree if_statement (tree, tree condition, tree then_block, tree else_block,
Location);
@@ -720,14 +705,6 @@ Gcc_backend::function_type (const typed_identifier &receiver,
if (result == error_mark_node)
return error_mark_node;
- // The libffi library cannot represent a zero-sized object. To
- // avoid causing confusion on 32-bit SPARC, we treat a function that
- // returns a zero-sized value as returning void. That should do no
- // harm since there is no actual value to be returned. See
- // https://gcc.gnu.org/PR72814 for details.
- if (result != void_type_node && int_size_in_bytes (result) == 0)
- result = void_type_node;
-
tree fntype = build_function_type (result, args);
if (fntype == error_mark_node)
return error_mark_node;
@@ -776,14 +753,6 @@ Gcc_backend::function_type_varadic (
if (result == error_mark_node)
return error_mark_node;
- // The libffi library cannot represent a zero-sized object. To
- // avoid causing confusion on 32-bit SPARC, we treat a function that
- // returns a zero-sized value as returning void. That should do no
- // harm since there is no actual value to be returned. See
- // https://gcc.gnu.org/PR72814 for details.
- if (result != void_type_node && int_size_in_bytes (result) == 0)
- result = void_type_node;
-
tree fntype = build_varargs_function_type_array (result, n, args);
if (fntype == error_mark_node)
return error_mark_node;
@@ -1988,90 +1957,21 @@ Gcc_backend::assignment_statement (tree lhs, tree rhs, Location location)
// Return.
tree
-Gcc_backend::return_statement (tree fntree, const std::vector<tree> &vals,
- Location location)
+Gcc_backend::return_statement (tree fntree, tree val, Location location)
{
if (fntree == error_mark_node)
return error_mark_node;
+
tree result = DECL_RESULT (fntree);
if (result == error_mark_node)
return error_mark_node;
- // If the result size is zero bytes, we have set the function type
- // to have a result type of void, so don't return anything.
- // See the function_type method.
- tree res_type = TREE_TYPE (result);
- if (res_type == void_type_node || int_size_in_bytes (res_type) == 0)
- {
- tree stmt_list = NULL_TREE;
- for (std::vector<tree>::const_iterator p = vals.begin ();
- p != vals.end (); p++)
- {
- tree val = (*p);
- if (val == error_mark_node)
- return error_mark_node;
- append_to_statement_list (val, &stmt_list);
- }
- tree ret = fold_build1_loc (location.gcc_location (), RETURN_EXPR,
- void_type_node, NULL_TREE);
- append_to_statement_list (ret, &stmt_list);
- return stmt_list;
- }
-
- tree ret;
- if (vals.empty ())
- ret = fold_build1_loc (location.gcc_location (), RETURN_EXPR,
- void_type_node, NULL_TREE);
- else if (vals.size () == 1)
- {
- tree val = vals.front ();
- if (val == error_mark_node)
- return error_mark_node;
- tree set = fold_build2_loc (location.gcc_location (), MODIFY_EXPR,
- void_type_node, result, vals.front ());
- ret = fold_build1_loc (location.gcc_location (), RETURN_EXPR,
- void_type_node, set);
- }
- else
- {
- // To return multiple values, copy the values into a temporary
- // variable of the right structure type, and then assign the
- // temporary variable to the DECL_RESULT in the return
- // statement.
- tree stmt_list = NULL_TREE;
- tree rettype = TREE_TYPE (result);
-
- if (DECL_STRUCT_FUNCTION (fntree) == NULL)
- push_struct_function (fntree);
- else
- push_cfun (DECL_STRUCT_FUNCTION (fntree));
- tree rettmp = create_tmp_var (rettype, "RESULT");
- pop_cfun ();
+ if (val == error_mark_node)
+ return error_mark_node;
- tree field = TYPE_FIELDS (rettype);
- for (std::vector<tree>::const_iterator p = vals.begin ();
- p != vals.end (); p++, field = DECL_CHAIN (field))
- {
- gcc_assert (field != NULL_TREE);
- tree ref
- = fold_build3_loc (location.gcc_location (), COMPONENT_REF,
- TREE_TYPE (field), rettmp, field, NULL_TREE);
- tree val = (*p);
- if (val == error_mark_node)
- return error_mark_node;
- tree set = fold_build2_loc (location.gcc_location (), MODIFY_EXPR,
- void_type_node, ref, (*p));
- append_to_statement_list (set, &stmt_list);
- }
- gcc_assert (field == NULL_TREE);
- tree set = fold_build2_loc (location.gcc_location (), MODIFY_EXPR,
- void_type_node, result, rettmp);
- tree ret_expr = fold_build1_loc (location.gcc_location (), RETURN_EXPR,
- void_type_node, set);
- append_to_statement_list (ret_expr, &stmt_list);
- ret = stmt_list;
- }
- return ret;
+ auto locus = location.gcc_location ();
+ tree set = fold_build2_loc (locus, MODIFY_EXPR, void_type_node, result, val);
+ return fold_build1_loc (locus, RETURN_EXPR, void_type_node, set);
}
// Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if an
diff --git a/gcc/testsuite/rust/compile/issue-2188.rs b/gcc/testsuite/rust/compile/issue-2188.rs
new file mode 100644
index 0000000..5f6ac85
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2188.rs
@@ -0,0 +1 @@
+static _V: () = {};