summaryrefslogtreecommitdiff
path: root/qa/src/wrap_int.c
diff options
context:
space:
mode:
Diffstat (limited to 'qa/src/wrap_int.c')
-rw-r--r--qa/src/wrap_int.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/qa/src/wrap_int.c b/qa/src/wrap_int.c
new file mode 100644
index 0000000..f91746b
--- /dev/null
+++ b/qa/src/wrap_int.c
@@ -0,0 +1,120 @@
+/*
+ * Generate sequences of values with wrapping for testing how
+ * tools deal with this. Note: wrapping of *signed* integers
+ * is undefined (according to gcc folks) and they take that as
+ * meaning "anything can happen". For some compilers, that's
+ * taken literally at higher optimisation levels, resulting in
+ * crashes, infinite loops, early exit; so *anything goes* for
+ * this test program. Do not rely on its output when signed
+ * integers are being used (the default, without -u).
+ *
+ * http://thiemonagel.de/2010/01/signed-integer-overflow/
+ * https://patchwork.kernel.org/patch/34925/
+ */
+#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define NUM_SAMPLES 20
+
+#ifndef LONGLONG_MAX
+#define LONGLONG_MAX 9223372036854775807LL /* max "long long int" */
+#endif
+
+#ifndef ULONGLONG_MAX
+#define ULONGLONG_MAX 18446744073709551615LLU /* max "unsigned long long" */
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int use_longlong = 0;
+ int num_samples = NUM_SAMPLES;
+ int notsigned = 0;
+ int c;
+ extern char *optarg;
+
+ while ((c = getopt(argc, argv, "ln:u")) != EOF) {
+ switch (c) {
+ case 'l':
+ /* use long long */
+ use_longlong = 1;
+ break;
+
+ case 'n':
+ num_samples = atoi(optarg);
+ break;
+
+ case 'u':
+ notsigned = 1;
+ break;
+ }
+ }
+
+ if (! notsigned ) {
+ if (! use_longlong) {
+ int x = 0;
+ int prev = 0;
+ int i;
+ double a;
+
+ for (i=0;i<=num_samples;i++) {
+ x += INT_MAX/2 - 1;
+ a = (double)x - (double)prev;
+ prev = x;
+ if (i > 0)
+ printf("%.4g\n", a);
+ }
+ }
+ else {
+ long long x = 0;
+ long long prev = 0;
+ int i;
+ double a;
+
+ for (i=0;i<=num_samples;i++) {
+ x += LONGLONG_MAX/2 - 1;
+ a = (double)x - (double)prev;
+ prev = x;
+ if (i > 0)
+ printf("%.4g\n", a);
+ }
+
+ }
+ }
+ else {
+ if (! use_longlong) {
+ unsigned int x = 0;
+ unsigned int prev = 0;
+ int i;
+ double a;
+
+ for (i=0;i<=num_samples;i++) {
+ x += UINT_MAX/2 - 1;
+ a = (double)x - (double)prev;
+ prev = x;
+ if (i > 0)
+ printf("%.4g\n", a);
+ }
+ }
+ else {
+ unsigned long long x = 0;
+ unsigned long long prev = 0;
+ int i;
+ double a;
+
+ for (i=0;i<=num_samples;i++) {
+ x += ULONGLONG_MAX/2 - 1;
+ a = (double)x - (double)prev;
+ prev = x;
+ if (i > 0)
+ printf("%.4g\n", a);
+ }
+
+ }
+ }
+
+ exit(0);
+
+}