From 3d32e50634885e71fb89770452d2e505cc5ed646 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 2 Sep 2015 00:46:23 +0000 Subject: [PATCH] compiler: Accept out of range integer -> unicode conversions. When converting a signed or unsigned integer value into a constant string, if the integer does not fit into the Go "int" type, the string will become "\uFFFD." Fixes golang/go#11525. Reviewed-on: https://go-review.googlesource.com/13906 From-SVN: r227395 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 87ef51844f7..5fcf1bd7961 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -65672c16004c6d6d0247b6691881d282ffca89e3 +a63e173b20baa1a48470dd31a1fb1f2704b37011 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index c18ae4a3b48..1df9f326561 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -3039,6 +3039,25 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*, } } + // According to the language specification on string conversions + // (http://golang.org/ref/spec#Conversions_to_and_from_a_string_type): + // When converting an integer into a string, the string will be a UTF-8 + // representation of the integer and integers "outside the range of valid + // Unicode code points are converted to '\uFFFD'." + if (type->is_string_type()) + { + Numeric_constant nc; + if (val->numeric_constant_value(&nc) && nc.is_int()) + { + // An integer value doesn't fit in the Unicode code point range if it + // overflows the Go "int" type or is negative. + unsigned long ul; + if (!nc.set_type(Type::lookup_integer_type("int"), false, location) + || nc.to_unsigned_long(&ul) == Numeric_constant::NC_UL_NEGATIVE) + return Expression::make_string("\ufffd", location); + } + } + if (type->is_slice_type()) { Type* element_type = type->array_type()->element_type()->forwarded(); -- 2.30.2