aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/backend/rust-compile-base.cc81
-rw-r--r--gcc/rust/backend/rust-compile-base.h4
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc17
-rw-r--r--gcc/rust/backend/rust-compile-expr.h8
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.h19
-rw-r--r--gcc/rust/backend/rust-compile-var-decl.h17
-rw-r--r--gcc/rust/backend/rust-compile.cc3
-rw-r--r--gcc/rust/rust-backend.h3
-rw-r--r--gcc/rust/rust-gcc.cc13
-rw-r--r--gcc/rust/typecheck/rust-hir-address-taken.cc65
-rw-r--r--gcc/rust/typecheck/rust-hir-address-taken.h159
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h12
13 files changed, 109 insertions, 293 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 2d74595..660ed23 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -88,7 +88,6 @@ GRS_OBJS = \
rust/rust-hir-trait-resolve.o \
rust/rust-hir-type-check-type.o \
rust/rust-hir-type-check-struct.o \
- rust/rust-hir-address-taken.o \
rust/rust-hir-type-check-pattern.o \
rust/rust-autoderef.o \
rust/rust-substitution-mapper.o \
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 82a38e7..81598c4 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-compile-base.h"
+#include "fold-const.h"
#include "stringpool.h"
namespace Rust {
@@ -88,5 +89,85 @@ HIRCompileBase::setup_abi_options (tree fndecl, ABI abi)
}
}
+// ported from gcc/c/c-typecheck.c
+//
+// Mark EXP saying that we need to be able to take the
+// address of it; it should not be allocated in a register.
+// Returns true if successful. ARRAY_REF_P is true if this
+// is for ARRAY_REF construction - in that case we don't want
+// to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE,
+// it is fine to use ARRAY_REFs for vector subscripts on vector
+// register variables.
+bool
+HIRCompileBase::mark_addressable (tree exp, Location locus)
+{
+ tree x = exp;
+
+ while (1)
+ switch (TREE_CODE (x))
+ {
+ case VIEW_CONVERT_EXPR:
+ if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
+ && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))))
+ return true;
+ x = TREE_OPERAND (x, 0);
+ break;
+
+ case COMPONENT_REF:
+ // TODO
+ // if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
+ // {
+ // error ("cannot take address of bit-field %qD", TREE_OPERAND (x,
+ // 1)); return false;
+ // }
+
+ /* FALLTHRU */
+ case ADDR_EXPR:
+ case ARRAY_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ x = TREE_OPERAND (x, 0);
+ break;
+
+ case COMPOUND_LITERAL_EXPR:
+ TREE_ADDRESSABLE (x) = 1;
+ TREE_ADDRESSABLE (COMPOUND_LITERAL_EXPR_DECL (x)) = 1;
+ return true;
+
+ case CONSTRUCTOR:
+ TREE_ADDRESSABLE (x) = 1;
+ return true;
+
+ case VAR_DECL:
+ case CONST_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ // (we don't have a concept of a "register" declaration)
+ // fallthrough */
+
+ /* FALLTHRU */
+ case FUNCTION_DECL:
+ TREE_ADDRESSABLE (x) = 1;
+
+ /* FALLTHRU */
+ default:
+ return true;
+ }
+
+ return false;
+}
+
+tree
+HIRCompileBase::address_expression (tree expr, Location location)
+{
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ if (!mark_addressable (expr, location))
+ return error_mark_node;
+
+ return build_fold_addr_expr_loc (location.gcc_location (), expr);
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index f318e81..ec75356 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -77,6 +77,10 @@ protected:
const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs);
static void setup_abi_options (tree fndecl, ABI abi);
+
+ static tree address_expression (tree, Location);
+
+ static bool mark_addressable (tree, Location);
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index d49a6dc..f65e1fd 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -124,6 +124,13 @@ CompileExpr::visit (HIR::NegationExpr &expr)
}
void
+CompileExpr::visit (HIR::BorrowExpr &expr)
+{
+ tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+ translated = address_expression (main_expr, expr.get_locus ());
+}
+
+void
CompileExpr::visit (HIR::DereferenceExpr &expr)
{
TyTy::BaseType *tyty = nullptr;
@@ -973,7 +980,7 @@ CompileExpr::compile_string_literal (const HIR::LiteralExpr &expr,
auto base = ctx->get_backend ()->string_constant_expression (
literal_value.as_string ());
- return ctx->get_backend ()->address_expression (base, expr.get_locus ());
+ return address_expression (base, expr.get_locus ());
}
tree
@@ -1006,8 +1013,7 @@ CompileExpr::compile_byte_string_literal (const HIR::LiteralExpr &expr,
vals,
expr.get_locus ());
- return ctx->get_backend ()->address_expression (constructed,
- expr.get_locus ());
+ return address_expression (constructed, expr.get_locus ());
}
tree
@@ -1190,7 +1196,7 @@ HIRCompileBase::resolve_adjustements (
case Resolver::Adjustment::AdjustmentType::IMM_REF:
case Resolver::Adjustment::AdjustmentType::MUT_REF:
- e = ctx->get_backend ()->address_expression (e, locus);
+ e = address_expression (e, locus);
break;
case Resolver::Adjustment::AdjustmentType::DEREF_REF:
@@ -1235,8 +1241,7 @@ HIRCompileBase::resolve_deref_adjustment (Resolver::Adjustment &adjustment,
!= Resolver::Adjustment::AdjustmentType::ERROR;
if (needs_borrow)
{
- adjusted_argument
- = ctx->get_backend ()->address_expression (expression, locus);
+ adjusted_argument = address_expression (expression, locus);
}
// make the call
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 43eff72..592d280 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -797,13 +797,7 @@ public:
ctx->add_statement (goto_label);
}
- void visit (HIR::BorrowExpr &expr) override
- {
- tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
-
- translated
- = ctx->get_backend ()->address_expression (main_expr, expr.get_locus ());
- }
+ void visit (HIR::BorrowExpr &expr) override;
void visit (HIR::DereferenceExpr &expr) override;
diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h
index d8b63b6..137bcad 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -20,7 +20,6 @@
#define RUST_COMPILE_FNPARAM
#include "rust-compile-base.h"
-#include "rust-hir-address-taken.h"
namespace Rust {
namespace Compile {
@@ -34,7 +33,7 @@ public:
HIR::FunctionParam *param, tree decl_type,
Location locus)
{
- CompileFnParam compiler (ctx, fndecl, decl_type, locus, *param);
+ CompileFnParam compiler (ctx, fndecl, decl_type, locus);
param->get_param_name ()->accept_vis (compiler);
return compiler.compiled_param;
}
@@ -45,9 +44,6 @@ public:
decl_type = ctx->get_backend ()->immutable_type (decl_type);
bool address_taken = false;
- address_taken_context->lookup_addess_taken (
- param.get_mappings ().get_hirid (), &address_taken);
-
compiled_param = ctx->get_backend ()->parameter_variable (
fndecl, pattern.get_identifier (), decl_type, address_taken, locus);
}
@@ -63,20 +59,15 @@ public:
}
private:
- CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus,
- const HIR::FunctionParam &param)
+ CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus)
: HIRCompileBase (ctx), fndecl (fndecl), decl_type (decl_type),
- locus (locus), param (param),
- compiled_param (ctx->get_backend ()->error_variable ()),
- address_taken_context (Resolver::AddressTakenContext::get ())
+ locus (locus), compiled_param (ctx->get_backend ()->error_variable ())
{}
tree fndecl;
tree decl_type;
Location locus;
- const HIR::FunctionParam &param;
Bvariable *compiled_param;
- const Resolver::AddressTakenContext *address_taken_context;
};
class CompileSelfParam : public HIRCompileBase
@@ -91,11 +82,7 @@ public:
if (is_immutable)
decl_type = ctx->get_backend ()->immutable_type (decl_type);
- const auto &address_taken_context = Resolver::AddressTakenContext::get ();
bool address_taken = false;
- address_taken_context->lookup_addess_taken (
- self.get_mappings ().get_hirid (), &address_taken);
-
return ctx->get_backend ()->parameter_variable (fndecl, "self", decl_type,
address_taken, locus);
}
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
index 48becfa..1da6cd4 100644
--- a/gcc/rust/backend/rust-compile-var-decl.h
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -20,7 +20,6 @@
#define RUST_COMPILE_VAR_DECL
#include "rust-compile-base.h"
-#include "rust-hir-address-taken.h"
namespace Rust {
namespace Compile {
@@ -47,9 +46,6 @@ public:
&resolved_type);
rust_assert (ok);
- address_taken_context->lookup_addess_taken (
- stmt.get_mappings ().get_hirid (), &address_taken);
-
translated_type = TyTyResolveCompile::compile (ctx, resolved_type);
stmt.get_pattern ()->accept_vis (*this);
}
@@ -59,6 +55,9 @@ public:
if (!pattern.is_mut ())
translated_type = ctx->get_backend ()->immutable_type (translated_type);
+ // this gets updated when the compilation _actually_ wants to take an
+ // address
+ bool address_taken = false;
compiled_variable
= ctx->get_backend ()->local_variable (fndecl, pattern.get_identifier (),
translated_type, NULL /*decl_var*/,
@@ -68,6 +67,10 @@ public:
void visit (HIR::WildcardPattern &pattern) override
{
translated_type = ctx->get_backend ()->immutable_type (translated_type);
+
+ // this gets updated when the compilation _actually_ wants to take an
+ // address
+ bool address_taken = false;
compiled_variable
= ctx->get_backend ()->local_variable (fndecl, "_", translated_type,
NULL /*decl_var*/, address_taken,
@@ -78,17 +81,13 @@ private:
CompileVarDecl (Context *ctx, tree fndecl)
: HIRCompileBase (ctx), fndecl (fndecl),
translated_type (ctx->get_backend ()->error_type ()),
- compiled_variable (ctx->get_backend ()->error_variable ()),
- address_taken (false),
- address_taken_context (Resolver::AddressTakenContext::get ())
+ compiled_variable (ctx->get_backend ()->error_variable ())
{}
tree fndecl;
tree translated_type;
Location locus;
Bvariable *compiled_variable;
- bool address_taken;
- const Resolver::AddressTakenContext *address_taken_context;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index b0447af..2299ddb 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -387,8 +387,7 @@ HIRCompileBase::coerce_to_dyn_object (tree compiled_ref,
rust_assert (ok);
resulting_dyn_object_ref
- = ctx->get_backend ()->address_expression (resulting_dyn_object_ref,
- locus);
+ = address_expression (resulting_dyn_object_ref, locus);
}
return resulting_dyn_object_ref;
}
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 2a7691c..7d28892 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -255,9 +255,6 @@ public:
// get the address of the code for a function.
virtual tree function_code_expression (tree, Location) = 0;
- // Create an expression that takes the address of an expression.
- virtual tree address_expression (tree, Location) = 0;
-
// Return an expression for the field at INDEX in BSTRUCT.
virtual tree struct_field_expression (tree bstruct, size_t index, Location)
= 0;
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 62c9d80..d83dd4d 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -231,8 +231,6 @@ public:
tree function_code_expression (tree, Location);
- tree address_expression (tree, Location);
-
tree struct_field_expression (tree, size_t, Location);
tree compound_expression (tree, tree, Location);
@@ -1338,17 +1336,6 @@ Gcc_backend::function_code_expression (tree func, Location location)
return ret;
}
-// Get the address of an expression.
-
-tree
-Gcc_backend::address_expression (tree expr, Location location)
-{
- if (expr == error_mark_node)
- return this->error_expression ();
-
- return build_fold_addr_expr_loc (location.gcc_location (), expr);
-}
-
// Return an expression for the field at INDEX in BSTRUCT.
tree
diff --git a/gcc/rust/typecheck/rust-hir-address-taken.cc b/gcc/rust/typecheck/rust-hir-address-taken.cc
deleted file mode 100644
index 8fcbb37..0000000
--- a/gcc/rust/typecheck/rust-hir-address-taken.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (C) 2020-2022 Free Software Foundation, Inc.
-
-// This file is part of GCC.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-#include "rust-hir-address-taken.h"
-#include "rust-hir-full.h"
-
-namespace Rust {
-namespace Resolver {
-
-AddressTakenContext *
-AddressTakenContext::get ()
-{
- static AddressTakenContext *instance;
- if (instance == nullptr)
- instance = new AddressTakenContext ();
-
- return instance;
-}
-
-AddressTakenContext::~AddressTakenContext () {}
-
-bool
-AddressTakenContext::lookup_addess_taken (HirId id, bool *address_taken) const
-{
- const auto &it = ctx.find (id);
- if (it == ctx.end ())
- return false;
-
- *address_taken = it->second;
- return true;
-}
-
-void
-AddressTakenContext::insert_address_taken (HirId id, bool address_taken)
-{
- const auto &it = ctx.find (id);
- if (it != ctx.end ())
- {
- // assert that we never change a true result to a negative
- if (it->second == true)
- {
- rust_assert (address_taken != false);
- }
- }
-
- ctx[id] = address_taken;
-}
-
-} // namespace Resolver
-} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-address-taken.h b/gcc/rust/typecheck/rust-hir-address-taken.h
deleted file mode 100644
index 32a1445..0000000
--- a/gcc/rust/typecheck/rust-hir-address-taken.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (C) 2020-2022 Free Software Foundation, Inc.
-
-// This file is part of GCC.
-
-// GCC is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3, or (at your option) any later
-// version.
-
-// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with GCC; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-#ifndef RUST_HIR_ADDRESS_TAKEN
-#define RUST_HIR_ADDRESS_TAKEN
-
-#include "rust-hir-type-check-base.h"
-
-namespace Rust {
-namespace Resolver {
-
-class AddressTakenContext
-{
-public:
- static AddressTakenContext *get ();
-
- ~AddressTakenContext ();
-
- bool lookup_addess_taken (HirId id, bool *address_taken) const;
-
- void insert_address_taken (HirId id, bool address_taken);
-
-private:
- std::map<HirId, bool> ctx;
-};
-
-class AddressTakenResolver : public TypeCheckBase
-{
- using Rust::Resolver::TypeCheckBase::visit;
-
-public:
- static void SetAddressTaken (HIR::Expr &expr)
- {
- AddressTakenResolver resolver;
- expr.accept_vis (resolver);
- }
-
- void visit (HIR::IdentifierExpr &expr) override
- {
- NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
- Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr.get_locus (),
- "unknown reference for resolved name");
- return;
- }
- ref_node_id = def.parent;
- }
-
- if (ref_node_id == UNKNOWN_NODEID)
- return;
-
- // node back to HIR
- HirId ref = UNKNOWN_HIRID;
- bool reverse_lookup
- = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
- ref_node_id, &ref);
- rust_assert (reverse_lookup);
- context->insert_address_taken (ref, true);
- }
-
- void visit (HIR::PathInExpression &expr) override
- {
- NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
- Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr.get_locus (),
- "unknown reference for resolved name");
- return;
- }
- ref_node_id = def.parent;
- }
-
- if (ref_node_id == UNKNOWN_NODEID)
- return;
-
- // node back to HIR
- HirId ref = UNKNOWN_HIRID;
- bool reverse_lookup
- = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
- ref_node_id, &ref);
- rust_assert (reverse_lookup);
- context->insert_address_taken (ref, true);
- }
-
- void visit (HIR::QualifiedPathInExpression &expr) override
- {
- NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
- Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr.get_locus (),
- "unknown reference for resolved name");
- return;
- }
- ref_node_id = def.parent;
- }
-
- if (ref_node_id == UNKNOWN_NODEID)
- return;
-
- // node back to HIR
- HirId ref = UNKNOWN_HIRID;
- bool reverse_lookup
- = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
- ref_node_id, &ref);
- rust_assert (reverse_lookup);
- context->insert_address_taken (ref, true);
- }
-
- void visit (HIR::DereferenceExpr &expr) override
- {
- expr.get_expr ()->accept_vis (*this);
- }
-
-private:
- AddressTakenResolver ()
- : TypeCheckBase (), context (AddressTakenContext::get ())
- {}
-
- AddressTakenContext *context;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_HIR_ADDRESS_TAKEN
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 150eb1a..2cb4461 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -30,7 +30,6 @@
#include "rust-hir-trait-resolve.h"
#include "rust-hir-type-bounds.h"
#include "rust-hir-dot-operator.h"
-#include "rust-hir-address-taken.h"
#include "rust-hir-type-check-pattern.h"
namespace Rust {
@@ -260,10 +259,6 @@ public:
Adjuster adj (receiver_tyty);
TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments);
- // mark the required tree addressable
- if (Adjuster::needs_address (candidate.adjustments))
- AddressTakenResolver::SetAddressTaken (*expr.get_receiver ().get ());
-
// store the adjustments for code-generation to know what to do
context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (),
std::move (candidate.adjustments));
@@ -1177,9 +1172,6 @@ public:
infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
TyTy::TyVar (resolved_base->get_ref ()),
expr.get_mut ());
-
- // mark the borrowed as address_taken
- AddressTakenResolver::SetAddressTaken (*expr.get_expr ().get ());
}
void visit (HIR::DereferenceExpr &expr) override
@@ -1350,10 +1342,6 @@ protected:
}
}
- // mark the required tree addressable
- if (Adjuster::needs_address (candidate.adjustments))
- AddressTakenResolver::SetAddressTaken (*expr.get_expr ().get ());
-
// store the adjustments for code-generation to know what to do
context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (),
std::move (candidate.adjustments));