aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-constexpr.cc
diff options
context:
space:
mode:
authorFaisal Abbas <90.abbasfaisal@gmail.com>2022-07-18 16:07:22 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-08-25 12:40:24 +0100
commita00b61e6bfc4a79af55236db0e602e09cd8fda72 (patch)
tree372b21fad7406485934f78a8d48c682901a9d832 /gcc/rust/backend/rust-constexpr.cc
parent7c13a2e5873f5919c00b5f37b6db52af8d0f7300 (diff)
downloadgcc-a00b61e6bfc4a79af55236db0e602e09cd8fda72.zip
gcc-a00b61e6bfc4a79af55236db0e602e09cd8fda72.tar.gz
gcc-a00b61e6bfc4a79af55236db0e602e09cd8fda72.tar.bz2
gccrs const folding port: continue porting potential_constant_expression_1()
Following functions are ported in this changeset: - find_heap_var_refs - find_immediate_fndecl - instantiation_dependent_expression_p - cp_get_callee - build_nop - scalarish_type_p - type_has_nontrivial_copy_init - build_local_temp - is_normal_capture_proxy - reject_gcc_builtin - is_bitfield_expr_with_lowered_type - maybe_undo_parenthesized_ref - fold_offsetof - char_type_p - resolve_nondeduced_context - null_node_p Following structs, classes and enums are ported in this changeset: - c_tree_index - warning_sentinel - uid_sensitive_constexpr_evaluation_checker - iloc_sentinel - ptrmem_cst This changeset puts c_global_trees and cp_global_trees outside Rust and Compile namespaces because keeping them inside is causing build issues. This is possibly because rust-tree.cc contains only Rust namespace while rust-constexpr.cc is Rust+Compile namespace. This causes issues when trying to use them inside both files. Signed-off-by: Faisal Abbas <90.abbasfaisal@gmail.com>
Diffstat (limited to 'gcc/rust/backend/rust-constexpr.cc')
-rw-r--r--gcc/rust/backend/rust-constexpr.cc105
1 files changed, 97 insertions, 8 deletions
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index 8fb378f..189bada 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -25,7 +25,9 @@
#include "print-tree.h"
#include "gimplify.h"
#include "tree-iterator.h"
+#include "timevar.h"
#include "varasm.h"
+#include "cgraph.h"
#define VERIFY_CONSTANT(X) \
do \
@@ -50,6 +52,11 @@ struct constexpr_global_ctx
{
HOST_WIDE_INT constexpr_ops_count;
+ /* Cleanups that need to be evaluated at the end of CLEANUP_POINT_EXPR. */
+ vec<tree> *cleanups;
+ /* Heap VAR_DECLs created during the evaluation of the outermost constant
+ expression. */
+ auto_vec<tree, 16> heap_vars;
constexpr_global_ctx () : constexpr_ops_count (0) {}
};
@@ -481,6 +488,60 @@ var_in_maybe_constexpr_fn (tree t)
// forked from gcc/cp/constexpr.cc array_index_cmp
+/* Some of the expressions fed to the constexpr mechanism are calls to
+ constructors, which have type void. In that case, return the type being
+ initialized by the constructor. */
+
+static tree
+initialized_type (tree t)
+{
+ if (TYPE_P (t))
+ return t;
+ tree type = TREE_TYPE (t);
+ if (TREE_CODE (t) == CALL_EXPR)
+ {
+ /* A constructor call has void type, so we need to look deeper. */
+ tree fn = get_function_named_in_call (t);
+ if (fn && TREE_CODE (fn) == FUNCTION_DECL && DECL_CXX_CONSTRUCTOR_P (fn))
+ type = DECL_CONTEXT (fn);
+ }
+ else if (TREE_CODE (t) == COMPOUND_EXPR)
+ return initialized_type (TREE_OPERAND (t, 1));
+
+ return cv_unqualified (type);
+}
+
+/* P0859: A function is needed for constant evaluation if it is a constexpr
+ function that is named by an expression ([basic.def.odr]) that is
+ potentially constant evaluated.
+
+ So we need to instantiate any constexpr functions mentioned by the
+ expression even if the definition isn't needed for evaluating the
+ expression. */
+
+static tree
+instantiate_cx_fn_r (tree *tp, int *walk_subtrees, void * /*data*/)
+{
+ if (TREE_CODE (*tp) == CALL_EXPR)
+ {
+ if (EXPR_HAS_LOCATION (*tp))
+ input_location = EXPR_LOCATION (*tp);
+ }
+
+ if (!EXPR_P (*tp))
+ *walk_subtrees = 0;
+
+ return NULL_TREE;
+}
+
+static void
+instantiate_constexpr_fns (tree t)
+{
+ location_t loc = input_location;
+ rs_walk_tree_without_duplicates (&t, instantiate_cx_fn_r, NULL);
+ input_location = loc;
+}
+
/* Returns less than, equal to, or greater than zero if KEY is found to be
less than, to match, or to be greater than the constructor_elt's INDEX. */
@@ -508,8 +569,6 @@ array_index_cmp (tree key, tree index)
}
}
-// forked from gcc/cp/constexpr.cc unshare_constructor
-
/* If T is a CONSTRUCTOR, return an unshared copy of T and any
sub-CONSTRUCTORs. Otherwise return T.
@@ -540,8 +599,6 @@ unshare_constructor (tree t MEM_STAT_DECL)
return t;
}
-// forked from gcc/cp/constexpr.cc find_array_ctor_elt
-
/* Returns the index of the constructor_elt of ARY which matches DINDEX, or -1
if none. If INSERT is true, insert a matching element rather than fail. */
@@ -666,8 +723,6 @@ find_array_ctor_elt (tree ary, tree dindex, bool insert)
return -1;
}
-// forked from gcc/cp/constexpr.cc reduced_constant_expression_p
-
/* Return true if T is a valid constant initializer. If a CONSTRUCTOR
initializes all the members, the CONSTRUCTOR_NO_CLEARING flag will be
cleared.
@@ -758,8 +813,6 @@ reduced_constant_expression_p (tree t)
}
}
-// forked from gcc/cp/constexpr.cc verify_constant
-
/* Some expressions may have constant operands but are not constant
themselves, such as 1/0. Call this function to check for that
condition.
@@ -794,6 +847,42 @@ verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
return *non_constant_p;
}
+// forked from gcc/cp/constexpr.cc find_heap_var_refs
+
+/* Look for heap variables in the expression *TP. */
+
+static tree
+find_heap_var_refs (tree *tp, int *walk_subtrees, void * /*data*/)
+{
+ if (VAR_P (*tp)
+ && (DECL_NAME (*tp) == heap_uninit_identifier
+ || DECL_NAME (*tp) == heap_identifier
+ || DECL_NAME (*tp) == heap_vec_uninit_identifier
+ || DECL_NAME (*tp) == heap_vec_identifier
+ || DECL_NAME (*tp) == heap_deleted_identifier))
+ return *tp;
+
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ return NULL_TREE;
+}
+
+// forked from gcc/cp/constexpr.cc find_immediate_fndecl
+
+/* Find immediate function decls in *TP if any. */
+
+static tree
+find_immediate_fndecl (tree *tp, int * /*walk_subtrees*/, void * /*data*/)
+{
+ if (TREE_CODE (*tp) == FUNCTION_DECL && DECL_IMMEDIATE_FUNCTION_P (*tp))
+ return *tp;
+ if (TREE_CODE (*tp) == PTRMEM_CST
+ && TREE_CODE (PTRMEM_CST_MEMBER (*tp)) == FUNCTION_DECL
+ && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (*tp)))
+ return PTRMEM_CST_MEMBER (*tp);
+ return NULL_TREE;
+}
+
// forked in gcc/cp/constexpr.cc diag_array_subscript
/* Under the control of CTX, issue a detailed diagnostic for