public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] rust constexpr: port over cxx_eval_builtin_function_call().
@ 2022-08-29 15:35 Thomas Schwinge
0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-08-29 15:35 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:533effe0f3f49c144df3e1a918f422d2982d21bf
commit 533effe0f3f49c144df3e1a918f422d2982d21bf
Author: Faisal Abbas <90.abbasfaisal@gmail.com>
Date: Fri Aug 12 18:58:04 2022 +0100
rust constexpr: port over cxx_eval_builtin_function_call().
It still needs potential_constant_expression_1() which will be continued
to be ported over.
Signed-off-by: Faisal Abbas <90.abbasfaisal@gmail.com>
Diff:
---
gcc/rust/backend/rust-constexpr.cc | 318 +++++++++++++++++++++++++++++++++++++
gcc/rust/backend/rust-tree.cc | 96 +++++++++++
gcc/rust/backend/rust-tree.h | 105 ++++++++++++
3 files changed, 519 insertions(+)
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index e41d184cf71..190abc96070 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -1084,6 +1084,7 @@ init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx, tree index,
/* There's no well-defined subobject for this index. */
new_ctx.object = NULL_TREE;
else
+ // Faisal: commenting this out as not sure if it's needed and it's huge
// new_ctx.object = build_ctor_subob_ref (index, type, ctx->object);
;
}
@@ -2761,6 +2762,217 @@ rs_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
return binds;
}
+// forked from gcc/cp/constexpr.cc cxx_eval_builtin_function_call
+
+/* Attempt to evaluate T which represents a call to a builtin function.
+ We assume here that all builtin functions evaluate to scalar types
+ represented by _CST nodes. */
+
+static tree
+eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
+ bool lval, bool *non_constant_p, bool *overflow_p)
+{
+ const int nargs = call_expr_nargs (t);
+ tree *args = (tree *) alloca (nargs * sizeof (tree));
+ tree new_call;
+ int i;
+
+ /* Don't fold __builtin_constant_p within a constexpr function. */
+ bool bi_const_p = DECL_IS_BUILTIN_CONSTANT_P (fun);
+
+ /* If we aren't requiring a constant expression, defer __builtin_constant_p
+ in a constexpr function until we have values for the parameters. */
+ if (bi_const_p && !ctx->manifestly_const_eval && current_function_decl
+ && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
+ {
+ *non_constant_p = true;
+ return t;
+ }
+
+ /* For __builtin_is_constant_evaluated, defer it if not
+ ctx->manifestly_const_eval (as sometimes we try to constant evaluate
+ without manifestly_const_eval even expressions or parts thereof which
+ will later be manifestly const_eval evaluated), otherwise fold it to
+ true. */
+ if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
+ BUILT_IN_FRONTEND))
+ {
+ if (!ctx->manifestly_const_eval)
+ {
+ *non_constant_p = true;
+ return t;
+ }
+ return boolean_true_node;
+ }
+
+ if (fndecl_built_in_p (fun, CP_BUILT_IN_SOURCE_LOCATION, BUILT_IN_FRONTEND))
+ {
+ temp_override<tree> ovr (current_function_decl);
+ if (ctx->call && ctx->call->fundef)
+ current_function_decl = ctx->call->fundef->decl;
+ return fold_builtin_source_location (EXPR_LOCATION (t));
+ }
+
+ int strops = 0;
+ int strret = 0;
+ if (fndecl_built_in_p (fun, BUILT_IN_NORMAL))
+ switch (DECL_FUNCTION_CODE (fun))
+ {
+ case BUILT_IN_STRLEN:
+ case BUILT_IN_STRNLEN:
+ strops = 1;
+ break;
+ case BUILT_IN_MEMCHR:
+ case BUILT_IN_STRCHR:
+ case BUILT_IN_STRRCHR:
+ strops = 1;
+ strret = 1;
+ break;
+ case BUILT_IN_MEMCMP:
+ case BUILT_IN_STRCMP:
+ strops = 2;
+ break;
+ case BUILT_IN_STRSTR:
+ strops = 2;
+ strret = 1;
+ break;
+ case BUILT_IN_ASAN_POINTER_COMPARE:
+ case BUILT_IN_ASAN_POINTER_SUBTRACT:
+ /* These builtins shall be ignored during constant expression
+ evaluation. */
+ return void_node;
+ default:
+ break;
+ }
+
+ /* Be permissive for arguments to built-ins; __builtin_constant_p should
+ return constant false for a non-constant argument. */
+ constexpr_ctx new_ctx = *ctx;
+ new_ctx.quiet = true;
+ for (i = 0; i < nargs; ++i)
+ {
+ tree arg = CALL_EXPR_ARG (t, i);
+ tree oarg = arg;
+
+ /* To handle string built-ins we need to pass ADDR_EXPR<STRING_CST> since
+ expand_builtin doesn't know how to look in the values table. */
+ bool strop = i < strops;
+ if (strop)
+ {
+ STRIP_NOPS (arg);
+ if (TREE_CODE (arg) == ADDR_EXPR)
+ arg = TREE_OPERAND (arg, 0);
+ else
+ strop = false;
+ }
+
+ /* If builtin_valid_in_constant_expr_p is true,
+ potential_constant_expression_1 has not recursed into the arguments
+ of the builtin, verify it here. */
+ if (!builtin_valid_in_constant_expr_p (fun)
+ || potential_constant_expression (arg))
+ {
+ bool dummy1 = false, dummy2 = false;
+ arg
+ = eval_constant_expression (&new_ctx, arg, false, &dummy1, &dummy2);
+ }
+
+ if (bi_const_p)
+ /* For __builtin_constant_p, fold all expressions with constant values
+ even if they aren't C++ constant-expressions. */
+ arg = cp_fold_rvalue (arg);
+ else if (strop)
+ {
+ if (TREE_CODE (arg) == CONSTRUCTOR)
+ arg = braced_lists_to_strings (TREE_TYPE (arg), arg);
+ if (TREE_CODE (arg) == STRING_CST)
+ arg = build_address (arg);
+ else
+ arg = oarg;
+ }
+
+ args[i] = arg;
+ }
+
+ bool save_ffbcp = force_folding_builtin_constant_p;
+ force_folding_builtin_constant_p |= ctx->manifestly_const_eval;
+ tree save_cur_fn = current_function_decl;
+ /* Return name of ctx->call->fundef->decl for __builtin_FUNCTION (). */
+ if (fndecl_built_in_p (fun, BUILT_IN_FUNCTION) && ctx->call
+ && ctx->call->fundef)
+ current_function_decl = ctx->call->fundef->decl;
+ if (fndecl_built_in_p (fun,
+ CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,
+ BUILT_IN_FRONTEND))
+ {
+ location_t loc = EXPR_LOCATION (t);
+ if (nargs >= 1)
+ VERIFY_CONSTANT (args[0]);
+ new_call
+ = fold_builtin_is_pointer_inverconvertible_with_class (loc, nargs,
+ args);
+ }
+ else if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CORRESPONDING_MEMBER,
+ BUILT_IN_FRONTEND))
+ {
+ location_t loc = EXPR_LOCATION (t);
+ if (nargs >= 2)
+ {
+ VERIFY_CONSTANT (args[0]);
+ VERIFY_CONSTANT (args[1]);
+ }
+ new_call = fold_builtin_is_corresponding_member (loc, nargs, args);
+ }
+ else
+ new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
+ CALL_EXPR_FN (t), nargs, args);
+ current_function_decl = save_cur_fn;
+ force_folding_builtin_constant_p = save_ffbcp;
+ if (new_call == NULL)
+ {
+ if (!*non_constant_p && !ctx->quiet)
+ {
+ /* Do not allow__builtin_unreachable in constexpr function.
+ The __builtin_unreachable call with BUILTINS_LOCATION
+ comes from cp_maybe_instrument_return. */
+ if (fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE)
+ && EXPR_LOCATION (t) == BUILTINS_LOCATION)
+ error ("%<constexpr%> call flows off the end of the function");
+ else
+ {
+ new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
+ CALL_EXPR_FN (t), nargs, args);
+ error ("%q+E is not a constant expression", new_call);
+ }
+ }
+ *non_constant_p = true;
+ return t;
+ }
+
+ if (!potential_constant_expression (new_call))
+ {
+ if (!*non_constant_p && !ctx->quiet)
+ error ("%q+E is not a constant expression", new_call);
+ *non_constant_p = true;
+ return t;
+ }
+
+ if (strret)
+ {
+ /* memchr returns a pointer into the first argument, but we replaced the
+ argument above with a STRING_CST; put it back it now. */
+ tree op = CALL_EXPR_ARG (t, strret - 1);
+ STRIP_NOPS (new_call);
+ if (TREE_CODE (new_call) == POINTER_PLUS_EXPR)
+ TREE_OPERAND (new_call, 0) = op;
+ else if (TREE_CODE (new_call) == ADDR_EXPR)
+ new_call = op;
+ }
+
+ return eval_constant_expression (&new_ctx, new_call, lval, non_constant_p,
+ overflow_p);
+}
+
// Subroutine of cxx_eval_constant_expression.
// Evaluate the call expression tree T in the context of OLD_CALL expression
// evaluation.
@@ -2792,6 +3004,10 @@ eval_call_expression (const constexpr_ctx *ctx, tree t, bool lval,
return t;
}
+ if (fndecl_built_in_p (fun))
+ return eval_builtin_function_call (ctx, t, fun, lval, non_constant_p,
+ overflow_p);
+
bool non_constant_args = false;
new_call.bindings
= rs_bind_parameters_in_call (ctx, t, fun, non_constant_p, overflow_p,
@@ -4443,6 +4659,20 @@ is_static_init_expression (tree t)
// faisal: just return false for now to make it compile
}
+/* Like potential_constant_expression, but don't consider possible constexpr
+ substitution of the current function. That is, PARM_DECL qualifies under
+ potential_constant_expression, but not here.
+
+ This is basically what you can check when any actual constant values might
+ be value-dependent. */
+
+bool
+is_constant_expression (tree t)
+{
+ // return potential_constant_expression_1 (t, false, true, true, tf_none);
+ // faisal: just return false for now to make it compile
+}
+
/* Returns true if T is a potential static initializer expression that is not
instantiation-dependent. */
@@ -4497,6 +4727,94 @@ maybe_constant_init (tree t, tree decl, bool manifestly_const_eval)
return maybe_constant_init_1 (t, decl, true, manifestly_const_eval);
}
+/* Returns true if T is a potential constant expression that is not
+ instantiation-dependent, and therefore a candidate for constant folding even
+ in a template. */
+
+bool
+is_nondependent_constant_expression (tree t)
+{
+ return (!type_unknown_p (t) && is_constant_expression (t)
+ && !instantiation_dependent_expression_p (t));
+}
+
+// forked from gcc/cp/parser.cc cp_unevaluated_operand
+
+/* Nonzero if we are parsing an unevaluated operand: an operand to
+ sizeof, typeof, or alignof. */
+int cp_unevaluated_operand;
+
+// forked from gcc/cp/constexpr.cc cv_cache
+
+/* If T is a constant expression, returns its reduced value.
+ Otherwise, if T does not have TREE_CONSTANT set, returns T.
+ Otherwise, returns a version of T without TREE_CONSTANT.
+ MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated
+ as per P0595. */
+
+static GTY ((deletable)) hash_map<tree, tree> *cv_cache;
+
+// forked from gcc/cp/constexpr.cc maybe_constant_value
+
+tree
+maybe_constant_value (tree t, tree decl, bool manifestly_const_eval)
+{
+ tree r;
+
+ if (!is_nondependent_constant_expression (t))
+ {
+ if (TREE_OVERFLOW_P (t))
+ {
+ t = build_nop (TREE_TYPE (t), t);
+ TREE_CONSTANT (t) = false;
+ }
+ return t;
+ }
+ else if (CONSTANT_CLASS_P (t))
+ /* No caching or evaluation needed. */
+ return t;
+
+ if (manifestly_const_eval)
+ return cxx_eval_outermost_constant_expr (t, true, true, true, false, decl);
+
+ if (cv_cache == NULL)
+ cv_cache = hash_map<tree, tree>::create_ggc (101);
+ if (tree *cached = cv_cache->get (t))
+ {
+ r = *cached;
+ if (r != t)
+ {
+ // Faisal: commenting this out as not sure if it's needed and it's
+ // huge r = break_out_target_exprs (r, /*clear_loc*/true);
+ protected_set_expr_location (r, EXPR_LOCATION (t));
+ }
+ return r;
+ }
+
+ /* Don't evaluate an unevaluated operand. */
+ if (cp_unevaluated_operand)
+ return t;
+
+ uid_sensitive_constexpr_evaluation_checker c;
+ r = cxx_eval_outermost_constant_expr (t, true, true, false, false, decl);
+ gcc_checking_assert (
+ r == t || CONVERT_EXPR_P (t) || TREE_CODE (t) == VIEW_CONVERT_EXPR
+ || (TREE_CONSTANT (t) && !TREE_CONSTANT (r)) || !rs_tree_equal (r, t));
+ if (!c.evaluation_restricted_p ())
+ cv_cache->put (t, r);
+ return r;
+}
+
+// forked from gcc/cp/constexpr.cc
+
+bool
+potential_constant_expression (tree t)
+{
+ // return potential_constant_expression_1 (t, false, true, false, tf_none);
+ // Faisal: return false until we port above call to make the code compile
+ return false;
+}
+
// #include "gt-rust-rust-constexpr.h"
} // namespace Compile
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index e1e56fc8336..beb4711493d 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -5257,6 +5257,8 @@ fold_builtin_is_pointer_inverconvertible_with_class (location_t loc, int nargs,
build_zero_cst (TREE_TYPE (arg)));
}
+// forked from gcc/c-family/c-common.cc registered_builtin_types
+
/* Used for communication between c_common_type_for_mode and
c_register_builtin_type. */
tree registered_builtin_types;
@@ -5267,6 +5269,8 @@ tree registered_builtin_types;
If the mode is a fixed-point mode,
then UNSIGNEDP selects between saturating and nonsaturating types. */
+// forked from gcc/c-family/c-common.cc c_common_type_for_mode
+
tree
c_common_type_for_mode (machine_mode mode, int unsignedp)
{
@@ -5487,6 +5491,8 @@ c_common_type_for_mode (machine_mode mode, int unsignedp)
return NULL_TREE;
}
+// forked from gcc/cp/semantics.cc finish_underlying_type
+
/* Implement the __underlying_type keyword: Return the underlying
type of TYPE, suitable for use as a type-specifier. */
@@ -5516,6 +5522,8 @@ finish_underlying_type (tree type)
return underlying_type;
}
+// forked from gcc/cp/typeck.cc layout_compatible_type_p
+
/* Return true if TYPE1 and TYPE2 are layout-compatible types. */
bool
@@ -5619,6 +5627,8 @@ layout_compatible_type_p (tree type1, tree type2)
return same_type_p (type1, type2);
}
+// forked from gcc/cp/semnatics.cc is_corresponding_member_union
+
/* Helper function for is_corresponding_member_aggr. Return true if
MEMBERTYPE pointer-to-data-member ARG can be found in anonymous
union or structure BASETYPE. */
@@ -5648,6 +5658,8 @@ is_corresponding_member_union (tree basetype, tree membertype, tree arg)
return false;
}
+// forked from gcc/cp/typeck.cc next_common_initial_seqence
+
/* Helper function for layout_compatible_type_p and
is_corresponding_member_aggr. Advance to next members (NULL if
no further ones) and return true if those members are still part of
@@ -5713,6 +5725,8 @@ next_common_initial_seqence (tree &memb1, tree &memb2)
return true;
}
+// forked from gcc/cp/semantics.cc is_corresponding_member_aggr
+
/* Helper function for fold_builtin_is_corresponding_member call.
Return boolean_false_node if MEMBERTYPE1 BASETYPE1::*ARG1 and
MEMBERTYPE2 BASETYPE2::*ARG2 aren't corresponding members,
@@ -5833,6 +5847,8 @@ is_corresponding_member_aggr (location_t loc, tree basetype1, tree membertype1,
return ret;
}
+// forked from gcc/cp/call.cc null_member_pointer_value_p
+
/* Returns true iff T is a null member pointer value (4.11). */
bool
@@ -5850,6 +5866,8 @@ null_member_pointer_value_p (tree t)
return false;
}
+// forked from gcc/cp/semantics.cc fold_builtin_is_corresponding_member
+
/* Fold __builtin_is_corresponding_member call. */
tree
@@ -5937,4 +5955,82 @@ fold_builtin_is_corresponding_member (location_t loc, int nargs, tree *args)
fold_convert (TREE_TYPE (arg1), arg2)));
}
+// forked from gcc/cp/tree.cc lvalue_type
+
+/* The type of ARG when used as an lvalue. */
+
+tree
+lvalue_type (tree arg)
+{
+ tree type = TREE_TYPE (arg);
+ return type;
+}
+
+// forked from gcc/c-family/c-warn.cc lvalue_error
+
+/* Print an error message for an invalid lvalue. USE says
+ how the lvalue is being used and so selects the error message. LOC
+ is the location for the error. */
+
+void
+lvalue_error (location_t loc, enum lvalue_use use)
+{
+ switch (use)
+ {
+ case lv_assign:
+ error_at (loc, "lvalue required as left operand of assignment");
+ break;
+ case lv_increment:
+ error_at (loc, "lvalue required as increment operand");
+ break;
+ case lv_decrement:
+ error_at (loc, "lvalue required as decrement operand");
+ break;
+ case lv_addressof:
+ error_at (loc, "lvalue required as unary %<&%> operand");
+ break;
+ case lv_asm:
+ error_at (loc, "lvalue required in %<asm%> statement");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+// forked from gcc/cp/cp--gimplify.cc cp_fold_maybe_rvalue
+
+/* Fold expression X which is used as an rvalue if RVAL is true. */
+
+tree
+cp_fold_maybe_rvalue (tree x, bool rval)
+{
+ while (true)
+ {
+ x = fold (x);
+ if (rval)
+ x = mark_rvalue_use (x);
+ if (rval && DECL_P (x) && !TYPE_REF_P (TREE_TYPE (x)))
+ {
+ tree v = decl_constant_value (x);
+ if (v != x && v != error_mark_node)
+ {
+ x = v;
+ continue;
+ }
+ }
+ break;
+ }
+ return x;
+}
+
+// forked from gcc/cp/cp--gimplify.cc cp_fold_rvalue
+
+/* Fold expression X which is used as an rvalue. */
+
+tree
+cp_fold_rvalue (tree x)
+{
+ return cp_fold_maybe_rvalue (x, true);
+}
+
} // namespace Rust
diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h
index 57440af632d..524569a985e 100644
--- a/gcc/rust/backend/rust-tree.h
+++ b/gcc/rust/backend/rust-tree.h
@@ -1346,6 +1346,26 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
of the enumeration is completed by finish_enum. */
#define ENUM_UNDERLYING_TYPE(TYPE) TREE_TYPE (ENUMERAL_TYPE_CHECK (TYPE))
+/* Nonzero if this type is volatile-qualified. */
+#define CP_TYPE_VOLATILE_P(NODE) \
+ ((rs_type_quals (NODE) & TYPE_QUAL_VOLATILE) != 0)
+
+/* Nonzero means that this type is either complete or being defined, so we
+ can do lookup in it. */
+#define COMPLETE_OR_OPEN_TYPE_P(NODE) \
+ (COMPLETE_TYPE_P (NODE) || (CLASS_TYPE_P (NODE) && TYPE_BEING_DEFINED (NODE)))
+
+/* Indicates when overload resolution may resolve to a pointer to
+ member function. [expr.unary.op]/3 */
+#define PTRMEM_OK_P(NODE) \
+ TREE_LANG_FLAG_0 (TREE_CHECK3 ((NODE), ADDR_EXPR, OFFSET_REF, SCOPE_REF))
+
+/* Returns nonzero iff NODE is a declaration for the global function
+ `main'. */
+#define DECL_MAIN_P(NODE) \
+ (DECL_NAME (NODE) != NULL_TREE && MAIN_NAME_P (DECL_NAME (NODE)) \
+ && flag_hosted)
+
#if defined ENABLE_TREE_CHECKING
#define LANG_DECL_MIN_CHECK(NODE) \
@@ -1512,6 +1532,77 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX];
// Above macros are copied from gcc/cp/name-lookup.cc
+/* Places where an lvalue, or modifiable lvalue, may be required.
+ Used to select diagnostic messages in lvalue_error and
+ readonly_error. */
+enum lvalue_use
+{
+ lv_assign,
+ lv_increment,
+ lv_decrement,
+ lv_addressof,
+ lv_asm
+};
+
+/* A class for recording information about access failures (e.g. private
+ fields), so that we can potentially supply a fix-it hint about
+ an accessor (from a context in which the constness of the object
+ is known). */
+
+class access_failure_info
+{
+public:
+ access_failure_info ()
+ : m_was_inaccessible (false), m_basetype_path (NULL_TREE),
+ m_decl (NULL_TREE), m_diag_decl (NULL_TREE)
+ {}
+
+ void record_access_failure (tree basetype_path, tree decl, tree diag_decl);
+
+ bool was_inaccessible_p () const { return m_was_inaccessible; }
+ tree get_decl () const { return m_decl; }
+ tree get_diag_decl () const { return m_diag_decl; }
+ tree get_any_accessor (bool const_p) const;
+ void maybe_suggest_accessor (bool const_p) const;
+ static void add_fixit_hint (rich_location *richloc, tree accessor);
+
+private:
+ bool m_was_inaccessible;
+ tree m_basetype_path;
+ tree m_decl;
+ tree m_diag_decl;
+};
+
+/* The various kinds of access check during parsing. */
+enum deferring_kind
+{
+ dk_no_deferred = 0, /* Check access immediately */
+ dk_deferred = 1, /* Deferred check */
+ dk_no_check = 2 /* No access check */
+};
+
+/* The representation of a deferred access check. */
+
+struct GTY (()) deferred_access_check
+{
+ /* The base class in which the declaration is referenced. */
+ tree binfo;
+ /* The declaration whose access must be checked. */
+ tree decl;
+ /* The declaration that should be used in the error message. */
+ tree diag_decl;
+ /* The location of this access. */
+ location_t loc;
+};
+
+struct GTY (()) tree_template_info
+{
+ struct tree_base base;
+ tree tmpl;
+ tree args;
+ vec<deferred_access_check, va_gc> *deferred_access_checks;
+};
+
/* The various kinds of lvalues we distinguish. */
enum cp_lvalue_kind_flags
{
@@ -2819,6 +2910,18 @@ extern bool null_member_pointer_value_p (tree);
extern tree
fold_builtin_is_corresponding_member (location_t, int, tree *);
+extern tree cp_fold_rvalue (tree);
+
+extern tree
+maybe_constant_value (tree, tree = NULL_TREE, bool = false);
+
+extern tree lvalue_type (tree);
+
+extern void lvalue_error (location_t, enum lvalue_use);
+
+extern tree
+cp_fold_maybe_rvalue (tree, bool);
+
// forked from gcc/cp/cp-tree.h
enum
@@ -3043,6 +3146,8 @@ set_implicit_rvalue_p (tree ot)
namespace Compile {
extern tree
maybe_constant_init (tree, tree = NULL_TREE, bool = false);
+
+extern bool potential_constant_expression (tree);
}
} // namespace Rust
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-08-29 15:35 UTC | newest]
Thread overview: (only message) (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: port over cxx_eval_builtin_function_call() 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).