diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2015-09-02 00:46:23 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2015-09-02 00:46:23 +0000 |
commit | 3d32e50634885e71fb89770452d2e505cc5ed646 (patch) | |
tree | d35f1fc3146eb671bd7ecf797b5b7d6484018c0c | |
parent | ad47aff5c541cffd3ad733688945f9d1c05ae633 (diff) | |
download | gcc-3d32e50634885e71fb89770452d2e505cc5ed646.zip gcc-3d32e50634885e71fb89770452d2e505cc5ed646.tar.gz gcc-3d32e50634885e71fb89770452d2e505cc5ed646.tar.bz2 |
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
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 19 |
2 files changed, 20 insertions, 1 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 87ef518..5fcf1bd 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 c18ae4a..1df9f32 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(); |