From: Owen Avery <[email protected]>
This should make it easier for us to move away from leaking pointers to
Bvariable everywhere. Since LocalVariable has a single field of type
tree, it should be the same size as a pointer to Bvariable, making the
switch to LocalVariable wherever possible strictly an improvement.
gcc/rust/ChangeLog:
* backend/rust-compile-expr.cc (CompileExpr::visit): Implicitly
convert LocalVariable to pointer to Bvariable.
* rust-backend.h (local_variable): Return LocalVariable.
(parameter_variable): Likewise.
(static_chain_variable): Likewise.
(temporary_variable): Likewise.
* rust-gcc.cc (local_variable): Likewise.
(parameter_variable): Likewise.
(static_chain_variable): Likewise.
(temporary_variable): Likewise.
(LocalVariable::get_tree): New function.
(LocalVariable::error_variable): Likewise.
* rust-gcc.h (class LocalVariable): New class.
Signed-off-by: Owen Avery <[email protected]>
---
gcc/rust/backend/rust-compile-expr.cc | 4 +--
gcc/rust/rust-backend.h | 18 ++++++------
gcc/rust/rust-gcc.cc | 41 +++++++++++++++++++--------
gcc/rust/rust-gcc.h | 24 ++++++++++++++++
4 files changed, 64 insertions(+), 23 deletions(-)
diff --git a/gcc/rust/backend/rust-compile-expr.cc
b/gcc/rust/backend/rust-compile-expr.cc
index 0a627f35352..6404825b02f 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -175,7 +175,7 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
}
auto receiver_tmp = NULL_TREE;
- auto receiver
+ Bvariable *receiver
= Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
TREE_TYPE (lhs), lhs, true,
expr.get_locus (), &receiver_tmp);
@@ -214,7 +214,7 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
if (ctx->in_fn () && !ctx->const_context_p ())
{
auto tmp = NULL_TREE;
- auto receiver
+ Bvariable *receiver
= Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
TREE_TYPE (lhs), lhs, true,
expr.get_locus (), &tmp);
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 95ca7a9fe46..99496e69d5f 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -349,18 +349,18 @@ void global_variable_set_init (Bvariable *, tree);
// the function, as otherwise the variable would be on the heap).
// LOCATION is where the variable is defined. For each local variable
// the frontend will call init_statement to set the initial value.
-Bvariable *local_variable (tree function, GGC::Ident name, tree type,
- Bvariable *decl_var, location_t location);
+LocalVariable local_variable (tree function, GGC::Ident name, tree type,
+ Bvariable *decl_var, location_t location);
// Create a function parameter. This is an incoming parameter, not
// a result parameter (result parameters are treated as local
// variables). The arguments are as for local_variable.
-Bvariable *parameter_variable (tree function, GGC::Ident name, tree type,
- location_t location);
+LocalVariable parameter_variable (tree function, GGC::Ident name, tree type,
+ location_t location);
// Create a static chain parameter. This is the closure parameter.
-Bvariable *static_chain_variable (tree function, GGC::Ident name, tree type,
- location_t location);
+LocalVariable static_chain_variable (tree function, GGC::Ident name, tree type,
+ location_t location);
// Create a temporary variable. A temporary variable has no name,
// just a type. We pass in FUNCTION and BLOCK in case they are
@@ -373,9 +373,9 @@ Bvariable *static_chain_variable (tree function, GGC::Ident
name, tree type,
// variable, and may not be very useful. This function should
// return a variable which can be referenced later and should set
// *PSTATEMENT to a statement which initializes the variable.
-Bvariable *temporary_variable (tree fndecl, tree bind_tree, tree type,
- tree init, bool address_is_taken,
- location_t location, tree *pstatement);
+LocalVariable temporary_variable (tree fndecl, tree bind_tree, tree type,
+ tree init, bool address_is_taken,
+ location_t location, tree *pstatement);
// Labels.
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 8f950d176f2..750c392e592 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -83,6 +83,23 @@ Bvariable::error_variable ()
return new Bvariable (error_mark_node);
}
+// Get the tree of a variable for use as an expression
+tree
+LocalVariable::get_tree (location_t location) const
+{
+ if (error_operand_p (t))
+ return error_mark_node;
+
+ TREE_USED (t) = 1;
+ return t;
+}
+
+LocalVariable
+LocalVariable::error_variable ()
+{
+ return LocalVariable (error_mark_node);
+}
+
// This file implements the interface between the Rust frontend proper
// and the gcc IR. This implements specific instantiations of
// abstract classes defined by the Rust frontend proper. The Rust
@@ -2014,12 +2031,12 @@ global_variable_set_init (Bvariable *var, tree
expr_tree)
// Make a local variable.
-Bvariable *
+LocalVariable
local_variable (tree function, GGC::Ident name, tree type_tree,
Bvariable *decl_var, location_t location)
{
if (error_operand_p (type_tree))
- return Bvariable::error_variable ();
+ return LocalVariable::error_variable ();
tree decl = build_decl (location, VAR_DECL, name.as_tree (), type_tree);
DECL_CONTEXT (decl) = function;
@@ -2029,33 +2046,33 @@ local_variable (tree function, GGC::Ident name, tree
type_tree,
SET_DECL_VALUE_EXPR (decl, decl_var->get_decl ());
}
rust_preserve_from_gc (decl);
- return new Bvariable (decl);
+ return LocalVariable (decl);
}
// Make a function parameter variable.
-Bvariable *
+LocalVariable
parameter_variable (tree function, GGC::Ident name, tree type_tree,
location_t location)
{
if (error_operand_p (type_tree))
- return Bvariable::error_variable ();
+ return LocalVariable::error_variable ();
tree decl = build_decl (location, PARM_DECL, name.as_tree (), type_tree);
DECL_CONTEXT (decl) = function;
DECL_ARG_TYPE (decl) = type_tree;
rust_preserve_from_gc (decl);
- return new Bvariable (decl);
+ return LocalVariable (decl);
}
// Make a static chain variable.
-Bvariable *
+LocalVariable
static_chain_variable (tree fndecl, GGC::Ident name, tree type_tree,
location_t location)
{
if (error_operand_p (type_tree))
- return Bvariable::error_variable ();
+ return LocalVariable::error_variable ();
tree decl = build_decl (location, PARM_DECL, name.as_tree (), type_tree);
DECL_CONTEXT (decl) = fndecl;
DECL_ARG_TYPE (decl) = type_tree;
@@ -2076,12 +2093,12 @@ static_chain_variable (tree fndecl, GGC::Ident name,
tree type_tree,
DECL_STATIC_CHAIN (fndecl) = 1;
rust_preserve_from_gc (decl);
- return new Bvariable (decl);
+ return LocalVariable (decl);
}
// Make a temporary variable.
-Bvariable *
+LocalVariable
temporary_variable (tree fndecl, tree bind_tree, tree type_tree, tree
init_tree,
bool is_address_taken, location_t location,
tree *pstatement)
@@ -2091,7 +2108,7 @@ temporary_variable (tree fndecl, tree bind_tree, tree
type_tree, tree init_tree,
|| error_operand_p (fndecl))
{
*pstatement = error_mark_node;
- return Bvariable::error_variable ();
+ return LocalVariable::error_variable ();
}
tree var;
@@ -2141,7 +2158,7 @@ temporary_variable (tree fndecl, tree bind_tree, tree
type_tree, tree init_tree,
|| TREE_TYPE (init_tree) == void_type_node))
*pstatement = compound_statement (init_tree, *pstatement);
- return new Bvariable (var);
+ return LocalVariable (var);
}
// Make a label.
diff --git a/gcc/rust/rust-gcc.h b/gcc/rust/rust-gcc.h
index b3f03252700..1ff7c5b4f2a 100644
--- a/gcc/rust/rust-gcc.h
+++ b/gcc/rust/rust-gcc.h
@@ -59,4 +59,28 @@ private:
tree orig_type_;
};
+// like Bvariable, but orig_type_ == nullptr always holds
+// could be any variable which isn't a zero-sized global
+class LocalVariable
+{
+public:
+ LocalVariable (tree t) : t (t) {}
+
+ // Get the tree for use as an expression.
+ tree get_tree (location_t) const;
+
+ // Get the actual decl;
+ tree get_decl () const { return t; }
+
+ // Create an error variable. This is used for cases which should
+ // not occur in a correct program, in order to keep the compilation
+ // going without crashing.
+ static LocalVariable error_variable ();
+
+ operator Bvariable * () const { return new Bvariable (t); }
+
+private:
+ tree t;
+};
+
#endif // RUST_GCC
--
2.50.1