public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] rust constexpr: conttinue porting cxx_eval_builtin_function_call
@ 2022-08-29 15:35 Thomas Schwinge
0 siblings, 0 replies; 2+ messages in thread
From: Thomas Schwinge @ 2022-08-29 15:35 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:1c53bc4fc8f687bc44f26b1dfd51a6e4745ef09c
commit 1c53bc4fc8f687bc44f26b1dfd51a6e4745ef09c
Author: Faisal Abbas <90.abbasfaisal@gmail.com>
Date: Mon Aug 8 18:42:33 2022 +0100
rust constexpr: conttinue porting cxx_eval_builtin_function_call
Signed-off-by: Faisal Abbas <90.abbasfaisal@gmail.com>
Diff:
---
gcc/rust/backend/rust-tree.cc | 168 ++++++++++++++++++++++++++++++++++++++++++
gcc/rust/backend/rust-tree.h | 2 +
2 files changed, 170 insertions(+)
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 8c6543271aa..f4a8383b19d 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -4883,4 +4883,172 @@ fold_builtin_source_location (location_t loc)
return build_fold_addr_expr_with_type_loc (loc, var, const_ptr_type_node);
}
+// forked from gcc/c-family.c-common.cc braced_lists_to_strings
+
+/* Attempt to convert a braced array initializer list CTOR for array
+ TYPE into a STRING_CST for convenience and efficiency. Return
+ the converted string on success or the original ctor on failure. */
+
+static tree
+braced_list_to_string (tree type, tree ctor, bool member)
+{
+ /* Ignore non-members with unknown size like arrays with unspecified
+ bound. */
+ tree typesize = TYPE_SIZE_UNIT (type);
+ if (!member && !tree_fits_uhwi_p (typesize))
+ return ctor;
+
+ /* If the target char size differes from the host char size, we'd risk
+ loosing data and getting object sizes wrong by converting to
+ host chars. */
+ if (TYPE_PRECISION (char_type_node) != CHAR_BIT)
+ return ctor;
+
+ /* If the array has an explicit bound, use it to constrain the size
+ of the string. If it doesn't, be sure to create a string that's
+ as long as implied by the index of the last zero specified via
+ a designator, as in:
+ const char a[] = { [7] = 0 }; */
+ unsigned HOST_WIDE_INT maxelts;
+ if (typesize)
+ {
+ maxelts = tree_to_uhwi (typesize);
+ maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
+ }
+ else
+ maxelts = HOST_WIDE_INT_M1U;
+
+ /* Avoid converting initializers for zero-length arrays (but do
+ create them for flexible array members). */
+ if (!maxelts)
+ return ctor;
+
+ unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (ctor);
+
+ auto_vec<char> str;
+ str.reserve (nelts + 1);
+
+ unsigned HOST_WIDE_INT i;
+ tree index, value;
+
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, index, value)
+ {
+ unsigned HOST_WIDE_INT idx = i;
+ if (index)
+ {
+ if (!tree_fits_uhwi_p (index))
+ return ctor;
+ idx = tree_to_uhwi (index);
+ }
+
+ /* auto_vec is limited to UINT_MAX elements. */
+ if (idx > UINT_MAX)
+ return ctor;
+
+ /* Avoid non-constant initializers. */
+ if (!tree_fits_shwi_p (value))
+ return ctor;
+
+ /* Skip over embedded nuls except the last one (initializer
+ elements are in ascending order of indices). */
+ HOST_WIDE_INT val = tree_to_shwi (value);
+ if (!val && i + 1 < nelts)
+ continue;
+
+ if (idx < str.length ())
+ return ctor;
+
+ /* Bail if the CTOR has a block of more than 256 embedded nuls
+ due to implicitly initialized elements. */
+ unsigned nchars = (idx - str.length ()) + 1;
+ if (nchars > 256)
+ return ctor;
+
+ if (nchars > 1)
+ {
+ str.reserve (idx);
+ str.quick_grow_cleared (idx);
+ }
+
+ if (idx >= maxelts)
+ return ctor;
+
+ str.safe_insert (idx, val);
+ }
+
+ /* Append a nul string termination. */
+ if (maxelts != HOST_WIDE_INT_M1U && str.length () < maxelts)
+ str.safe_push (0);
+
+ /* Build a STRING_CST with the same type as the array. */
+ tree res = build_string (str.length (), str.begin ());
+ TREE_TYPE (res) = type;
+ return res;
+}
+
+// forked from gcc/c-family.c-common.cc braced_lists_to_strings
+
+/* Implementation of the two-argument braced_lists_to_string withe
+ the same arguments plus MEMBER which is set for struct members
+ to allow initializers for flexible member arrays. */
+
+static tree
+braced_lists_to_strings (tree type, tree ctor, bool member)
+{
+ if (TREE_CODE (ctor) != CONSTRUCTOR)
+ return ctor;
+
+ tree_code code = TREE_CODE (type);
+
+ tree ttp;
+ if (code == ARRAY_TYPE)
+ ttp = TREE_TYPE (type);
+ else if (code == RECORD_TYPE)
+ {
+ ttp = TREE_TYPE (ctor);
+ if (TREE_CODE (ttp) == ARRAY_TYPE)
+ {
+ type = ttp;
+ ttp = TREE_TYPE (ttp);
+ }
+ }
+ else
+ return ctor;
+
+ if ((TREE_CODE (ttp) == ARRAY_TYPE || TREE_CODE (ttp) == INTEGER_TYPE)
+ && TYPE_STRING_FLAG (ttp))
+ return braced_list_to_string (type, ctor, member);
+
+ code = TREE_CODE (ttp);
+ if (code == ARRAY_TYPE || RECORD_OR_UNION_TYPE_P (ttp))
+ {
+ bool rec = RECORD_OR_UNION_TYPE_P (ttp);
+
+ /* Handle array of arrays or struct member initializers. */
+ tree val;
+ unsigned HOST_WIDE_INT idx;
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), idx, val)
+ {
+ val = braced_lists_to_strings (ttp, val, rec);
+ CONSTRUCTOR_ELT (ctor, idx)->value = val;
+ }
+ }
+
+ return ctor;
+}
+
+// forked from gcc/c-family.c-common.cc braced_lists_to_strings
+
+/* Attempt to convert a CTOR containing braced array initializer lists
+ for array TYPE into one containing STRING_CSTs, for convenience and
+ efficiency. Recurse for arrays of arrays and member initializers.
+ Return the converted CTOR or STRING_CST on success or the original
+ CTOR otherwise. */
+
+tree
+braced_lists_to_strings (tree type, tree ctor)
+{
+ return braced_lists_to_strings (type, ctor, false);
+}
+
} // namespace Rust
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index bb3b4304372..b79fa188652 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -2740,6 +2740,8 @@ extern tree lookup_enumerator (tree, tree);
extern int
is_class_type (tree, int);
+extern tree braced_lists_to_strings (tree, tree);
+
// forked from gcc/cp/cp-tree.h
enum
^ permalink raw reply [flat|nested] 2+ messages in thread
* [gcc/devel/rust/master] rust constexpr: conttinue porting cxx_eval_builtin_function_call
@ 2022-08-29 15:35 Thomas Schwinge
0 siblings, 0 replies; 2+ messages in thread
From: Thomas Schwinge @ 2022-08-29 15:35 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:9350b3733aef7c93ccd3b50d610e2831016db02b
commit 9350b3733aef7c93ccd3b50d610e2831016db02b
Author: Faisal Abbas <90.abbasfaisal@gmail.com>
Date: Tue Aug 9 12:39:34 2022 +0100
rust constexpr: conttinue porting cxx_eval_builtin_function_call
Signed-off-by: Faisal Abbas <90.abbasfaisal@gmail.com>
Diff:
---
gcc/rust/backend/rust-constexpr.cc | 1 +
gcc/rust/backend/rust-tree.cc | 212 ++++++++++++++++++++++++++++++++++++-
gcc/rust/backend/rust-tree.h | 22 ++++
3 files changed, 232 insertions(+), 3 deletions(-)
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index df4ceba4f7a..e41d184cf71 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -32,6 +32,7 @@
#include "vec.h"
#include "rust-target.h"
#include "function.h"
+#include "builtins.h"
#define VERIFY_CONSTANT(X) \
do \
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index f4a8383b19d..7f622cbbeb5 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -4883,7 +4883,7 @@ fold_builtin_source_location (location_t loc)
return build_fold_addr_expr_with_type_loc (loc, var, const_ptr_type_node);
}
-// forked from gcc/c-family.c-common.cc braced_lists_to_strings
+// forked from gcc/c-family/c-common.cc braced_lists_to_strings
/* Attempt to convert a braced array initializer list CTOR for array
TYPE into a STRING_CST for convenience and efficiency. Return
@@ -4986,7 +4986,7 @@ braced_list_to_string (tree type, tree ctor, bool member)
return res;
}
-// forked from gcc/c-family.c-common.cc braced_lists_to_strings
+// forked from gcc/c-family/c-common.cc braced_lists_to_strings
/* Implementation of the two-argument braced_lists_to_string withe
the same arguments plus MEMBER which is set for struct members
@@ -5037,7 +5037,7 @@ braced_lists_to_strings (tree type, tree ctor, bool member)
return ctor;
}
-// forked from gcc/c-family.c-common.cc braced_lists_to_strings
+// forked from gcc/c-family/c-common.cc braced_lists_to_strings
/* Attempt to convert a CTOR containing braced array initializer lists
for array TYPE into one containing STRING_CSTs, for convenience and
@@ -5051,4 +5051,210 @@ braced_lists_to_strings (tree type, tree ctor)
return braced_lists_to_strings (type, ctor, false);
}
+/*---------------------------------------------------------------------------
+ Constraint satisfaction
+---------------------------------------------------------------------------*/
+
+// forked from gcc/cp/constraint.cc satisfying_constraint
+
+/* True if we are currently satisfying a failed_type_completions. */
+
+static bool satisfying_constraint;
+
+// forked from gcc/cp/constraint.cc satisfying_constraint
+
+/* A vector of incomplete types (and of declarations with undeduced return
+ type), appended to by note_failed_type_completion_for_satisfaction. The
+ satisfaction caches use this in order to keep track of "potentially unstable"
+ satisfaction results.
+
+ Since references to entries in this vector are stored only in the
+ GC-deletable sat_cache, it's safe to make this deletable as well. */
+
+static GTY ((deletable)) vec<tree, va_gc> *failed_type_completions;
+
+// forked from gcc/cp/constraint.cc note_failed_type_completion_for_satisfaction
+
+/* Called whenever a type completion (or return type deduction) failure occurs
+ that definitely affects the meaning of the program, by e.g. inducing
+ substitution failure. */
+
+void
+note_failed_type_completion_for_satisfaction (tree t)
+{
+ if (satisfying_constraint)
+ {
+ gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t))
+ || (DECL_P (t) && undeduced_auto_decl (t)));
+ vec_safe_push (failed_type_completions, t);
+ }
+}
+
+// forked from gcc/cp/typeck.cc complete_type
+
+/* Try to complete TYPE, if it is incomplete. For example, if TYPE is
+ a template instantiation, do the instantiation. Returns TYPE,
+ whether or not it could be completed, unless something goes
+ horribly wrong, in which case the error_mark_node is returned. */
+
+tree
+complete_type (tree type)
+{
+ if (type == NULL_TREE)
+ /* Rather than crash, we return something sure to cause an error
+ at some point. */
+ return error_mark_node;
+
+ if (type == error_mark_node || COMPLETE_TYPE_P (type))
+ ;
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree t = complete_type (TREE_TYPE (type));
+ unsigned int needs_constructing, has_nontrivial_dtor;
+ if (COMPLETE_TYPE_P (t))
+ layout_type (type);
+ needs_constructing = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
+ has_nontrivial_dtor
+ = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ {
+ TYPE_NEEDS_CONSTRUCTING (t) = needs_constructing;
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = has_nontrivial_dtor;
+ }
+ }
+
+ return type;
+}
+
+// forked from gcc/cp/typeck.cc complete_type_or_maybe_complain
+
+/* Like complete_type, but issue an error if the TYPE cannot be completed.
+ VALUE is used for informative diagnostics.
+ Returns NULL_TREE if the type cannot be made complete. */
+
+tree
+complete_type_or_maybe_complain (tree type, tree value, tsubst_flags_t complain)
+{
+ type = complete_type (type);
+ if (type == error_mark_node)
+ /* We already issued an error. */
+ return NULL_TREE;
+ else if (!COMPLETE_TYPE_P (type))
+ {
+ if (complain & tf_error)
+ cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
+ note_failed_type_completion_for_satisfaction (type);
+ return NULL_TREE;
+ }
+ else
+ return type;
+}
+
+// forked from gcc/cp/typeck.cc complete_type_or_else
+
+tree
+complete_type_or_else (tree type, tree value)
+{
+ return complete_type_or_maybe_complain (type, value, tf_warning_or_error);
+}
+
+// forked from gcc/cp/tree.cc std_layout_type_p
+
+/* Returns true iff T is a standard-layout type, as defined in
+ [basic.types]. */
+
+bool
+std_layout_type_p (const_tree t)
+{
+ t = strip_array_types (CONST_CAST_TREE (t));
+
+ if (CLASS_TYPE_P (t))
+ return !CLASSTYPE_NON_STD_LAYOUT (t);
+ else
+ return scalarish_type_p (t);
+}
+
+// forked from /gcc/cp/semantics.cc first_nonstatic_data_member_p
+
+/* Helper function for fold_builtin_is_pointer_inverconvertible_with_class,
+ return true if MEMBERTYPE is the type of the first non-static data member
+ of TYPE or for unions of any members. */
+static bool
+first_nonstatic_data_member_p (tree type, tree membertype)
+{
+ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+ if (DECL_FIELD_IS_BASE (field) && is_empty_field (field))
+ continue;
+ if (DECL_FIELD_IS_BASE (field))
+ return first_nonstatic_data_member_p (TREE_TYPE (field), membertype);
+ if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+ {
+ if ((TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
+ || std_layout_type_p (TREE_TYPE (field)))
+ && first_nonstatic_data_member_p (TREE_TYPE (field), membertype))
+ return true;
+ }
+ else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
+ membertype))
+ return true;
+ if (TREE_CODE (type) != UNION_TYPE)
+ return false;
+ }
+ return false;
+}
+
+// forked from gcc/cp/semantics.cc
+// fold_builtin_is_pointer_inverconvertible_with_class
+
+/* Fold __builtin_is_pointer_interconvertible_with_class call. */
+
+tree
+fold_builtin_is_pointer_inverconvertible_with_class (location_t loc, int nargs,
+ tree *args)
+{
+ /* Unless users call the builtin directly, the following 3 checks should be
+ ensured from std::is_pointer_interconvertible_with_class function
+ template. */
+ if (nargs != 1)
+ {
+ error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
+ "needs a single argument");
+ return boolean_false_node;
+ }
+ tree arg = args[0];
+ if (error_operand_p (arg))
+ return boolean_false_node;
+ if (!TYPE_PTRMEM_P (TREE_TYPE (arg)))
+ {
+ error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
+ "argument is not pointer to member");
+ return boolean_false_node;
+ }
+
+ if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg)))
+ return boolean_false_node;
+
+ tree membertype = TREE_TYPE (TREE_TYPE (arg));
+ tree basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg));
+ if (!complete_type_or_else (basetype, NULL_TREE))
+ return boolean_false_node;
+
+ if (TREE_CODE (basetype) != UNION_TYPE && !std_layout_type_p (basetype))
+ return boolean_false_node;
+
+ if (!first_nonstatic_data_member_p (basetype, membertype))
+ return boolean_false_node;
+
+ if (integer_nonzerop (arg))
+ return boolean_false_node;
+ if (integer_zerop (arg))
+ return boolean_true_node;
+
+ return fold_build2 (EQ_EXPR, boolean_type_node, arg,
+ build_zero_cst (TREE_TYPE (arg)));
+}
+
} // namespace Rust
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index b79fa188652..3fd9484d47d 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -1297,6 +1297,28 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
if an initializer has been. */
#define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3 (NODE))
+/* Nonzero means that this class type is a non-standard-layout class. */
+#define CLASSTYPE_NON_STD_LAYOUT(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->non_std_layout)
+
+/* Nonzero for FIELD_DECL node means that this field is a base class
+ of the parent object, as opposed to a member field. */
+#define DECL_FIELD_IS_BASE(NODE) DECL_LANG_FLAG_6 (FIELD_DECL_CHECK (NODE))
+
+/* Nonzero if TYPE is an anonymous union type. */
+#define ANON_UNION_TYPE_P(NODE) \
+ (TREE_CODE (NODE) == UNION_TYPE && ANON_AGGR_TYPE_P (NODE))
+
+/* For an ANON_AGGR_TYPE_P the single FIELD_DECL it is used with. */
+#define ANON_AGGR_TYPE_FIELD(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->typeinfo_var)
+
+/* Nonzero if TYPE is an anonymous union or struct type. We have to use a
+ flag for this because "A union for which objects or pointers are
+ declared is not an anonymous union" [class.union]. */
+#define ANON_AGGR_TYPE_P(NODE) \
+ (CLASS_TYPE_P (NODE) && LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr)
+#define SET_ANON_AGGR_TYPE_P(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr = 1)
+
#if defined ENABLE_TREE_CHECKING
#define LANG_DECL_MIN_CHECK(NODE) \
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-08-29 15:35 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-29 15:35 [gcc/devel/rust/master] rust constexpr: conttinue porting cxx_eval_builtin_function_call Thomas Schwinge
2022-08-29 15:35 Thomas Schwinge
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).