From: Rico Tzschichholz Date: Mon, 21 Nov 2022 09:55:44 +0000 (+0100) Subject: vala: Improve integer literal checks X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=865733142cad7f44f1c41a3e4bcd043048a3c756;p=thirdparty%2Fvala.git vala: Improve integer literal checks --- diff --git a/tests/Makefile.am b/tests/Makefile.am index 4536dcb3b..458e56bd1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,6 +42,9 @@ AM_TESTS_ENVIRONMENT = \ TESTS = \ basic-types/gassert.vala \ basic-types/integer-literals.vala \ + basic-types/integer-signed-erange.test \ + basic-types/integer-unsigned-erange.test \ + basic-types/integer-unsigned-invalid.test \ basic-types/integers.vala \ basic-types/integers-boxed-cast.vala \ basic-types/escape-chars.vala \ diff --git a/tests/basic-types/integer-literals.c-expected b/tests/basic-types/integer-literals.c-expected index c534fbe7f..3a162e1b7 100644 --- a/tests/basic-types/integer-literals.c-expected +++ b/tests/basic-types/integer-literals.c-expected @@ -44,6 +44,12 @@ _vala_main (void) foo = 23LL; bar = 42LL; } + { + guint64 foo = 0ULL; + gint64 bar = 0LL; + foo = 18446744073709551615ULL; + bar = -9223372036854775808LL; + } } int diff --git a/tests/basic-types/integer-literals.vala b/tests/basic-types/integer-literals.vala index 60deedbd8..0f9d4106b 100644 --- a/tests/basic-types/integer-literals.vala +++ b/tests/basic-types/integer-literals.vala @@ -23,4 +23,8 @@ void main () { int64 foo = 23LL; int64 bar = 42ll; } + { + uint64 foo = 18446744073709551615; + int64 bar = -9223372036854775808; + } } diff --git a/tests/basic-types/integer-signed-erange.test b/tests/basic-types/integer-signed-erange.test new file mode 100644 index 000000000..2e4042064 --- /dev/null +++ b/tests/basic-types/integer-signed-erange.test @@ -0,0 +1,5 @@ +Invalid Code + +void main () { + int64 foo = -9223372036854775809; +} diff --git a/tests/basic-types/integer-unsigned-erange.test b/tests/basic-types/integer-unsigned-erange.test new file mode 100644 index 000000000..64ada00ff --- /dev/null +++ b/tests/basic-types/integer-unsigned-erange.test @@ -0,0 +1,5 @@ +Invalid Code + +void main () { + uint64 foo = 18446744073709551616; +} diff --git a/tests/basic-types/integer-unsigned-invalid.test b/tests/basic-types/integer-unsigned-invalid.test new file mode 100644 index 000000000..c8b3d96bd --- /dev/null +++ b/tests/basic-types/integer-unsigned-invalid.test @@ -0,0 +1,5 @@ +Invalid Code + +void main () { + uint foo = -23U; +} diff --git a/vala/valaintegerliteral.vala b/vala/valaintegerliteral.vala index e28960126..ec6146bc2 100644 --- a/vala/valaintegerliteral.vala +++ b/vala/valaintegerliteral.vala @@ -78,7 +78,36 @@ public class Vala.IntegerLiteral : Literal { value = value.substring (0, value.length - 1); } - int64 n = int64.parse (value); + bool negative = value.has_prefix ("-"); + if (negative && u) { + Report.error (source_reference, "unsigned integer literal cannot be negative"); + error = true; + } + + int64 n = 0LL; + uint64 un = 0ULL; + + errno = 0; + if (negative) { + n = int64.parse (value); + } else { + un = uint64.parse (value); + } + if (errno == ERANGE) { + Report.error (source_reference, "integer literal is too large for its type"); + error = true; + } else if (errno == EINVAL) { + Report.error (source_reference, "invalid integer literal"); + error = true; + } + + if (un > int64.MAX) { + // value doesn't fit into signed 64-bit + u = true; + l = 2; + } else if (!negative) { + n = (int64) un; + } if (!u && (n > int.MAX || n < int.MIN)) { // value doesn't fit into signed 32-bit l = 2;