compiler: handle int-to-string conversion with large integer constant
Currently, Type_conversion_expression::do_is_constant thinks the
int-to-string conversion is constant if the integer operand is
constant, but Type_conversion_expression::do_get_backend actually
generates a call to runtime.intstring if the integer does not fit
in a "ushort", which makes it not suitable in constant context,
such as static initializer.
This CL makes it handle all constant integer input as constant,
generating constant string.
Fixes golang/go#32347.
Change-Id: I64502e2fec034d5081be395ee7636791e5601215
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/179777
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/go/expressions.cc b/go/expressions.cc
index e3a6627..f0c12f4 100644
--- a/go/expressions.cc
+++ b/go/expressions.cc
@@ -3842,11 +3842,20 @@
mpz_t intval;
Numeric_constant nc;
if (this->expr_->numeric_constant_value(&nc)
- && nc.to_int(&intval)
- && mpz_fits_ushort_p(intval))
+ && nc.to_int(&intval))
{
std::string s;
- Lex::append_char(mpz_get_ui(intval), true, &s, loc);
+ unsigned int x;
+ if (mpz_fits_uint_p(intval))
+ x = mpz_get_ui(intval);
+ else
+ {
+ char* s = mpz_get_str(NULL, 16, intval);
+ go_warning_at(loc, 0,
+ "unicode code point 0x%s out of range in string", s);
+ x = 0xfffd;
+ }
+ Lex::append_char(x, true, &s, loc);
mpz_clear(intval);
Expression* se = Expression::make_string(s, loc);
return se->get_backend(context);