summaryrefslogtreecommitdiff
path: root/glib
diff options
context:
space:
mode:
authorAllison Ryan Lortie <desrt@desrt.ca>2015-10-28 11:14:15 +0000
committerAllison Ryan Lortie <desrt@desrt.ca>2015-10-30 11:58:49 +0100
commit7dd9ffbcfff3561d2d1bcd247c052e4c4399623f (patch)
tree2d8f0fc655e810ffdc146919524982bea89958c5 /glib
parentd0219f25970c740ac1a8965754868d54bcd90eeb (diff)
downloadglib-7dd9ffbcfff3561d2d1bcd247c052e4c4399623f.tar.gz
tests: test bounds-checked int arithmetic
Add some simple testcases for the new bounds-checked integer arithmetic helpers. Include a second build of the testcase to make sure we test the fallback code even if we are on a compiler that supports the intrinsics. https://bugzilla.gnome.org/show_bug.cgi?id=503096
Diffstat (limited to 'glib')
-rw-r--r--glib/tests/Makefile.am5
-rw-r--r--glib/tests/overflow.c199
2 files changed, 204 insertions, 0 deletions
diff --git a/glib/tests/Makefile.am b/glib/tests/Makefile.am
index 23f29401e..4bdbf5868 100644
--- a/glib/tests/Makefile.am
+++ b/glib/tests/Makefile.am
@@ -69,6 +69,8 @@ test_programs = \
once \
option-context \
option-argv0 \
+ overflow \
+ overflow-fallback \
pattern \
private \
protocol \
@@ -165,6 +167,9 @@ if HAVE_GCC
atomic_CFLAGS += -Wstrict-aliasing=2
endif
+overflow_fallback_SOURCES = overflow.c
+overflow_fallback_FALGS = $(AM_CFLAGS) -D_GLIB_TEST_OVERFLOW_FALLBACK
+
test_programs += 642026-ec
642026_ec_SOURCES = 642026.c
642026_ec_CFLAGS = -DG_ERRORCHECK_MUTEXES
diff --git a/glib/tests/overflow.c b/glib/tests/overflow.c
new file mode 100644
index 000000000..f241abd92
--- /dev/null
+++ b/glib/tests/overflow.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2015 Canonical Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ *
+ * Author: Allison Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include <glib.h>
+
+typedef struct
+{
+ gboolean success;
+ gsize c, a, b;
+} Case;
+
+static void
+test_checked_guint_add (void)
+{
+ static const Case cases[] = {
+ /* success c = a + b */
+ { TRUE, 0, 0, 0 },
+ { TRUE, G_MAXINT, G_MAXINT, 0 },
+ { TRUE, G_MAXINT, 0, G_MAXINT },
+ { TRUE, G_MAXUINT, G_MAXUINT, 0 },
+ { TRUE, G_MAXUINT, 0, G_MAXUINT },
+ { TRUE, G_MAXUINT - 1, G_MAXINT, G_MAXINT },
+ { FALSE, 0, G_MAXUINT, 1 },
+ { FALSE, 0, 1, G_MAXUINT },
+ { FALSE, 0, G_MAXUINT, G_MAXUINT }
+ };
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ guint result;
+
+ g_assert_cmpuint (cases[i].success, ==, g_uint_checked_add (&result, cases[i].a, cases[i].b));
+ if (cases[i].success)
+ g_assert_cmpuint (cases[i].c, ==, result);
+ }
+}
+
+static void
+test_checked_guint_mul (void)
+{
+ static const Case cases[] = {
+ /* success c = a * b */
+ { TRUE, 0, 0, 0 },
+ { TRUE, 0, G_MAXINT, 0 },
+ { TRUE, G_MAXINT, G_MAXINT, 1 },
+ { TRUE, 0, G_MAXUINT, 0 },
+ { TRUE, G_MAXUINT, G_MAXUINT, 1 },
+ { TRUE, 2 * (guint) G_MAXINT, 2, G_MAXINT },
+ { TRUE, 2 * (guint) G_MAXINT, G_MAXINT, 2 },
+ { FALSE, 0, 3, G_MAXINT },
+ { FALSE, 0, G_MAXINT, 3 }
+ };
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ guint result;
+
+ g_assert_cmpuint (cases[i].success, ==, g_uint_checked_mul (&result, cases[i].a, cases[i].b));
+ if (cases[i].success)
+ g_assert_cmpuint (cases[i].c, ==, result);
+ }
+}
+
+
+static void
+test_checked_guint64_add (void)
+{
+ static const Case cases[] = {
+ /* success c = a + b */
+ { TRUE, 0, 0, 0 },
+ { TRUE, G_MAXINT64, G_MAXINT64, 0 },
+ { TRUE, G_MAXINT64, 0, G_MAXINT64 },
+ { TRUE, G_MAXUINT64, G_MAXUINT64, 0 },
+ { TRUE, G_MAXUINT64, 0, G_MAXUINT64 },
+ { TRUE, G_MAXUINT64 - 1, G_MAXINT64, G_MAXINT64 },
+ { FALSE, 0, G_MAXUINT64, 1 },
+ { FALSE, 0, 1, G_MAXUINT64 },
+ { FALSE, 0, G_MAXUINT64, G_MAXUINT64 }
+ };
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ guint64 result;
+
+ g_assert_cmpuint (cases[i].success, ==, g_uint64_checked_add (&result, cases[i].a, cases[i].b));
+ if (cases[i].success)
+ g_assert_cmpuint (cases[i].c, ==, result);
+ }
+}
+
+static void
+test_checked_guint64_mul (void)
+{
+ static const Case cases[] = {
+ /* success c = a * b */
+ { TRUE, 0, 0, 0 },
+ { TRUE, 0, G_MAXINT64, 0 },
+ { TRUE, G_MAXINT64, G_MAXINT64, 1 },
+ { TRUE, 0, G_MAXUINT64, 0 },
+ { TRUE, G_MAXUINT64, G_MAXUINT64, 1 },
+ { TRUE, 2 * (guint64) G_MAXINT64, 2, G_MAXINT64 },
+ { TRUE, 2 * (guint64) G_MAXINT64, G_MAXINT64, 2 },
+ { FALSE, 0, 3, G_MAXINT64 },
+ { FALSE, 0, G_MAXINT64, 3 }
+ };
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ guint64 result;
+
+ g_assert_cmpuint (cases[i].success, ==, g_uint64_checked_mul (&result, cases[i].a, cases[i].b));
+ if (cases[i].success)
+ g_assert_cmpuint (cases[i].c, ==, result);
+ }
+}
+
+
+static void
+test_checked_gsize_add (void)
+{
+ static const Case cases[] = {
+ /* success c = a + b */
+ { TRUE, 0, 0, 0 },
+ { TRUE, G_MAXSSIZE, G_MAXSSIZE, 0 },
+ { TRUE, G_MAXSSIZE, 0, G_MAXSSIZE },
+ { TRUE, G_MAXSIZE, G_MAXSIZE, 0 },
+ { TRUE, G_MAXSIZE, 0, G_MAXSIZE },
+ { TRUE, G_MAXSIZE - 1, G_MAXSSIZE, G_MAXSSIZE },
+ { FALSE, 0, G_MAXSIZE, 1 },
+ { FALSE, 0, 1, G_MAXSIZE },
+ { FALSE, 0, G_MAXSIZE, G_MAXSIZE }
+ };
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ gsize result;
+
+ g_assert_cmpuint (cases[i].success, ==, g_size_checked_add (&result, cases[i].a, cases[i].b));
+ if (cases[i].success)
+ g_assert_cmpuint (cases[i].c, ==, result);
+ }
+}
+
+static void
+test_checked_gsize_mul (void)
+{
+ static const Case cases[] = {
+ /* success c = a * b */
+ { TRUE, 0, 0, 0 },
+ { TRUE, 0, G_MAXSSIZE, 0 },
+ { TRUE, G_MAXSSIZE, G_MAXSSIZE, 1 },
+ { TRUE, 0, G_MAXSIZE, 0 },
+ { TRUE, G_MAXSIZE, G_MAXSIZE, 1 },
+ { TRUE, 2 * (gsize) G_MAXSSIZE, 2, G_MAXSSIZE },
+ { TRUE, 2 * (gsize) G_MAXSSIZE, G_MAXSSIZE, 2 },
+ { FALSE, 0, 3, G_MAXSSIZE },
+ { FALSE, 0, G_MAXSSIZE, 3 }
+ };
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (cases); i++)
+ {
+ gsize result;
+
+ g_assert_cmpuint (cases[i].success, ==, g_size_checked_mul (&result, cases[i].a, cases[i].b));
+ if (cases[i].success)
+ g_assert_cmpuint (cases[i].c, ==, result);
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/glib/checked-math/guint-add", test_checked_guint_add);
+ g_test_add_func ("/glib/checked-math/guint-mul", test_checked_guint_mul);
+ g_test_add_func ("/glib/checked-math/guint64-add", test_checked_guint64_add);
+ g_test_add_func ("/glib/checked-math/guint64-mul", test_checked_guint64_mul);
+ g_test_add_func ("/glib/checked-math/gsize-add", test_checked_gsize_add);
+ g_test_add_func ("/glib/checked-math/gsize-mul", test_checked_gsize_mul);
+
+ return g_test_run ();
+}