]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Improve integer literal checks
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 21 Nov 2022 09:55:44 +0000 (10:55 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Thu, 8 Dec 2022 14:37:08 +0000 (15:37 +0100)
tests/Makefile.am
tests/basic-types/integer-literals.c-expected
tests/basic-types/integer-literals.vala
tests/basic-types/integer-signed-erange.test [new file with mode: 0644]
tests/basic-types/integer-unsigned-erange.test [new file with mode: 0644]
tests/basic-types/integer-unsigned-invalid.test [new file with mode: 0644]
vala/valaintegerliteral.vala

index 4536dcb3b1cf6cd4298ad5c6cdc5dc01ad5ac37e..458e56bd17df14927a5b55c4a152ae2a5de8e87d 100644 (file)
@@ -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 \
index c534fbe7f03b193444ec163e7574f10bafebb4b1..3a162e1b7cab885682669299b0cba90f14cba946 100644 (file)
@@ -44,6 +44,12 @@ _vala_main (void)
                foo = 23LL;
                bar = 42LL;
        }
+       {
+               guint64 foo = 0ULL;
+               gint64 bar = 0LL;
+               foo = 18446744073709551615ULL;
+               bar = -9223372036854775808LL;
+       }
 }
 
 int
index 60deedbd854c960053ba71dc820103a2a728e260..0f9d4106b9639d93f1a7cfe8c67192673a0b9370 100644 (file)
@@ -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 (file)
index 0000000..2e40420
--- /dev/null
@@ -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 (file)
index 0000000..64ada00
--- /dev/null
@@ -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 (file)
index 0000000..c8b3d96
--- /dev/null
@@ -0,0 +1,5 @@
+Invalid Code
+
+void main () {
+       uint foo = -23U;
+}
index e289601262e879fd566b8e722c53fc71f7089c85..ec6146bc27295411568d38bb81ef1b2a2352949a 100644 (file)
@@ -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;