Rewrite eval_exception__S_exception_cvt_{to,from}_utf8 into a single

eval_exception__S_exception_cvt_tofrom_utf8 with extra to_utf8 argument.
This commit is contained in:
Jakub Jelinek
2026-01-07 14:44:00 +01:00
committed by Marek Polacek
parent 967b4e8235
commit b6bd6249bd

View File

@@ -7054,37 +7054,45 @@ eval_has_inaccessible_subobjects (location_t loc, const constexpr_ctx *ctx,
jump_target, fun);
}
/* Implement std::meta::exception::_S_exception_cvt_to_utf8. This is
/* Implement std::meta::exception::_S_exception_cvt_to_utf8 and
std::meta::exception::_S_exception_cvt_from_utf8. This is
an implementation specific metafunction which translates string_view
into u8string_view for use in std::meta::exception constructors.
On translation failure returns an empty u8string_view. */
into u8string_view resp. u8string_view into string_view for use in
std::meta::exception constructors. On translation failure returns an empty
{u8,}string_view. TO_UTF8 is true for _S_exception_cvt_to_utf8 and false
for _S_exception_cvt_from_utf8. */
static tree
eval_exception__S_exception_cvt_to_utf8 (location_t loc,
const constexpr_ctx *ctx,
tree call, bool *non_constant_p,
bool *overflow_p, tree *jump_target,
tree fun)
eval_exception__S_exception_cvt_tofrom_utf8 (location_t loc,
const constexpr_ctx *ctx,
tree call, bool *non_constant_p,
bool *overflow_p,
tree *jump_target, tree fun,
bool to_utf8)
{
tree str = get_range_elts (loc, ctx, call, 0, non_constant_p, overflow_p,
jump_target, REFLECT_CONSTANT_STRING, fun);
if (*jump_target || *non_constant_p)
return NULL_TREE;
if (TREE_CODE (str) != STRING_CST
|| TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (str))) != char_type_node)
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (str)))
!= (to_utf8 ? char_type_node : char8_type_node)))
{
error_at (loc, "unexpected argument to %<_S_exception_cvt_to_utf8%>");
error_at (loc, "unexpected argument to %qs",
to_utf8 ? "_S_exception_cvt_to_utf8"
: "_S_exception_cvt_from_utf8");
*non_constant_p = true;
return call;
}
/* We need to translate the string twice for the theoretical case
of non-UTF8 SOURCE_CHARSET. First translate from exec charset to
of non-UTF8 SOURCE_CHARSET. First translate from {exec charset,UTF-8} to
SOURCE_CHARSET... */
cpp_string istr, ostr;
istr.len = TREE_STRING_LENGTH (str) + 1;
istr.text = (const unsigned char *) TREE_STRING_POINTER (str);
const char *name;
if (!cpp_translate_string (parse_in, &istr, &ostr, CPP_STRING, true))
if (!cpp_translate_string (parse_in, &istr, &ostr,
to_utf8 ? CPP_STRING : CPP_UTF8STRING, true))
{
ostr.text = NULL;
name = "";
@@ -7092,65 +7100,13 @@ eval_exception__S_exception_cvt_to_utf8 (location_t loc,
else
name = (const char *) ostr.text;
/* And then let get_string_literal translate from SOURCE_CHARSET to
UTF-8. */
str = get_string_literal (name, char8_type_node);
{UTF-8,exec charset}. */
tree dchar_type = to_utf8 ? char8_type_node : char_type_node;
str = get_string_literal (name, dchar_type);
free (const_cast <unsigned char *> (ostr.text));
if (str == NULL_TREE)
{
str = get_string_literal ("", char8_type_node);
gcc_assert (str);
}
releasing_vec args (make_tree_vector_single (str));
tree ret = build_special_member_call (NULL_TREE, complete_ctor_identifier,
&args, TREE_TYPE (call), LOOKUP_NORMAL,
tf_warning_or_error);
return build_cplus_new (TREE_TYPE (call), ret, tf_warning_or_error);
}
/* Implement std::meta::exception::_S_exception_cvt_from_utf8. This is
an implementation specific metafunction which translates u8string_view
into string_view for use in std::meta::exception constructors.
On translation failure returns an empty string_view. */
static tree
eval_exception__S_exception_cvt_from_utf8 (location_t loc,
const constexpr_ctx *ctx,
tree call, bool *non_constant_p,
bool *overflow_p, tree *jump_target,
tree fun)
{
tree str = get_range_elts (loc, ctx, call, 0, non_constant_p, overflow_p,
jump_target, REFLECT_CONSTANT_STRING, fun);
if (*jump_target || *non_constant_p)
return NULL_TREE;
if (TREE_CODE (str) != STRING_CST
|| TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (str))) != char8_type_node)
{
error_at (loc, "unexpected argument to %<_S_exception_cvt_from_utf8%>");
*non_constant_p = true;
return call;
}
/* We need to translate the string twice for the theoretical case
of non-UTF8 SOURCE_CHARSET. First translate from UTF-8 to
SOURCE_CHARSET... */
cpp_string istr, ostr;
istr.len = TREE_STRING_LENGTH (str) + 1;
istr.text = (const unsigned char *) TREE_STRING_POINTER (str);
const char *name;
if (!cpp_translate_string (parse_in, &istr, &ostr, CPP_UTF8STRING, true))
{
ostr.text = NULL;
name = "";
}
else
name = (const char *) ostr.text;
/* And then let get_string_literal translate from SOURCE_CHARSET to
exec charset. */
str = get_string_literal (name, char_type_node);
free (const_cast <unsigned char *> (ostr.text));
if (str == NULL_TREE)
{
str = get_string_literal ("", char_type_node);
str = get_string_literal ("", dchar_type);
gcc_assert (str);
}
releasing_vec args (make_tree_vector_single (str));
@@ -8043,17 +7999,13 @@ process_metafunction (const constexpr_ctx *ctx, tree fun, tree call,
&& id_equal (DECL_NAME (TYPE_NAME (DECL_CONTEXT (fun))),
"exception"))
{
if (minfo->code == METAFN_EXCEPTION__S_EXCEPTION_CVT_TO_UTF8)
return eval_exception__S_exception_cvt_to_utf8 (loc, ctx, call,
non_constant_p,
overflow_p,
jump_target, fun);
else
return eval_exception__S_exception_cvt_from_utf8 (loc, ctx, call,
bool to_utf8
= minfo->code == METAFN_EXCEPTION__S_EXCEPTION_CVT_TO_UTF8;
return eval_exception__S_exception_cvt_tofrom_utf8 (loc, ctx, call,
non_constant_p,
overflow_p,
jump_target,
fun);
fun, to_utf8);
}
goto not_found;
}