summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2014-01-01 16:43:37 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2014-01-01 16:43:37 +0000
commit7e4e9417b6bfaf9f6a0f36e2fc040c12f8530889 (patch)
treeeccc49cef74eb53e0947cd4184d791620688fc37 /test
parentc67f5803d5cd84dae8bd78901f9056a1f2eff700 (diff)
Experimental support for <stdarg.h>, the GCC way. Works on IA32. To be tested on PowerPC and ARM.
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@2394 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'test')
-rw-r--r--test/regression/Makefile5
-rw-r--r--test/regression/Results/varargs11
-rw-r--r--test/regression/Results/varargs211
-rw-r--r--test/regression/varargs1.c7
-rw-r--r--test/regression/varargs2.c161
5 files changed, 183 insertions, 2 deletions
diff --git a/test/regression/Makefile b/test/regression/Makefile
index 8dc7678..c653a01 100644
--- a/test/regression/Makefile
+++ b/test/regression/Makefile
@@ -17,7 +17,8 @@ TESTS=int32 int64 floats floats-basics \
TESTS_COMP=attribs1 bitfields1 bitfields2 bitfields3 bitfields4 \
bitfields5 bitfields6 bitfields7 bitfields8 \
- builtins-$(ARCH) packedstruct1 packedstruct2 alignas
+ builtins-$(ARCH) packedstruct1 packedstruct2 alignas \
+ varargs1 varargs2
# Can run, both in compiled mode and in interpreter mode,
# but produce processor-dependent results, so no reference output in Results
@@ -31,7 +32,7 @@ EXTRAS=annot1 commaprec expr2 expr3 expr4 extern1 funct2 funptr1 init1 \
struct4 struct5 struct6 struct9 struct10 types1 seqops
# Test known to fail
-FAILURES=funct1 varargs1
+FAILURES=funct1
all: $(TESTS:%=%.compcert) $(TESTS_COMP:%=%.compcert) $(TESTS_DIFF:%=%.compcert) $(EXTRAS:%=%.s)
diff --git a/test/regression/Results/varargs1 b/test/regression/Results/varargs1
new file mode 100644
index 0000000..00c4b5d
--- /dev/null
+++ b/test/regression/Results/varargs1
@@ -0,0 +1 @@
+Sum is 55
diff --git a/test/regression/Results/varargs2 b/test/regression/Results/varargs2
new file mode 100644
index 0000000..35728be
--- /dev/null
+++ b/test/regression/Results/varargs2
@@ -0,0 +1,11 @@
+An int: 42
+A long long: 123456789012345
+A string: Hello world
+A double: 3.141592654
+A char: x and A string: Hello, world! and An int: 42 and A long: 123456789012345 and A double: 3.141592654 and A float: 2.718281746
+Twice: -1 1.23
+Twice: -1 1.23
+With va_copy: -1 1.23
+With va_copy: -1 1.23
+With extra args: A char: x and A string: Hello, world! and An int: 42 and A long: 123456789012345 and A double: 3.141592654 and A float: 2.718281746
+va_list compatibility: A char: x and A string: Hello, world! and An int: 42 and A long: 123456789012345 and A double: 3.141592654 and A float: 2.718281746
diff --git a/test/regression/varargs1.c b/test/regression/varargs1.c
index 99dba39..2e45d0f 100644
--- a/test/regression/varargs1.c
+++ b/test/regression/varargs1.c
@@ -1,4 +1,5 @@
#include <stdarg.h>
+#include <stdio.h>
int sum_v(int n, va_list ap)
{
@@ -16,3 +17,9 @@ int sum_l(int n, ...)
va_end(ap);
return s;
}
+
+int main()
+{
+ printf("Sum is %d\n", sum_l(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
+ return 0;
+}
diff --git a/test/regression/varargs2.c b/test/regression/varargs2.c
new file mode 100644
index 0000000..e2eefce
--- /dev/null
+++ b/test/regression/varargs2.c
@@ -0,0 +1,161 @@
+#include <stdarg.h>
+#include <stdio.h>
+
+void minivprintf(const char * fmt, va_list ap)
+{
+ char c;
+
+ while (1) {
+ switch(c = *fmt++) {
+ case 0:
+ return;
+ case '%':
+ switch (*fmt++) {
+ case '%':
+ putchar('%');
+ break;
+ case 'c':
+ printf("%c", (char) va_arg(ap, int));
+ break;
+ case 's':
+ printf("%s", va_arg(ap, char *));
+ break;
+ case 'd':
+ printf("%d", va_arg(ap, int));
+ break;
+ case 'l':
+ printf("%lld", va_arg(ap, long long));
+ break;
+ case 'e':
+ printf("%.10g", va_arg(ap, double));
+ break;
+ case 'f':
+ printf("%.10g", (float) va_arg(ap, double));
+ break;
+ default:
+ puts("<bad format>");
+ return;
+ }
+ break;
+ default:
+ putchar(c);
+ break;
+ }
+ }
+}
+
+void miniprintf(const char * fmt, ...)
+{
+ va_list va;
+ va_start(va, fmt);
+ minivprintf(fmt, va);
+ va_end(va);
+}
+
+/* Run va_start twice */
+
+void miniprintf2(const char * fmt, ...)
+{
+ va_list va;
+ va_start(va, fmt);
+ minivprintf(fmt, va);
+ va_end(va);
+ va_start(va, fmt);
+ minivprintf(fmt, va);
+ va_end(va);
+}
+
+/* Use va_copy */
+
+void miniprintf3(const char * fmt, ...)
+{
+ va_list va, va2;
+ va_start(va, fmt);
+ va_copy(va2, va);
+ minivprintf(fmt, va);
+ minivprintf(fmt, va2);
+ va_end(va);
+ va_end(va2);
+}
+
+/* Add some dummy arguments to force overflow into stack-passed params
+ (mostly relevant for ARM and PowerPC) */
+
+void miniprintf_extra(int i1, int i2, int i3, int i4,
+ int i5, int i6, int i7, int i8,
+ double f1, double f2, double f3, double f4,
+ float f5, float f6, float f7, float f8,
+ const char * fmt, ...)
+{
+ va_list va;
+ va_start(va, fmt);
+ minivprintf(fmt, va);
+ va_end(va);
+}
+
+/* Test va_list compatibility with the C library */
+
+void printf_compat(const char * fmt, ...)
+{
+ va_list va;
+ va_start(va, fmt);
+ vprintf(fmt, va);
+ va_end(va);
+}
+
+/* The test harness */
+
+int main()
+{
+ miniprintf("An int: %d\n", 42);
+ miniprintf("A long long: %l\n", 123456789012345LL);
+ miniprintf("A string: %s\n", "Hello world");
+ miniprintf("A double: %e\n", 3.141592654);
+ miniprintf("A char: %c and "
+ "A string: %s and "
+ "An int: %d and "
+ "A long: %l and "
+ "A double: %e and "
+ "A float: %f\n",
+ 'x',
+ "Hello, world!",
+ 42,
+ 123456789012345LL,
+ 3.141592654,
+ 2.71828182);
+ miniprintf2("Twice: %d %e\n", -1, 1.23);
+ miniprintf3("With va_copy: %d %e\n", -1, 1.23);
+ miniprintf_extra(0, 1, 2, 3, 4, 5, 6, 7,
+ 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7,
+ "With extra args: "
+ "A char: %c and "
+ "A string: %s and "
+ "An int: %d and "
+ "A long: %l and "
+ "A double: %e and "
+ "A float: %f\n",
+ 'x',
+ "Hello, world!",
+ 42,
+ 123456789012345LL,
+ 3.141592654,
+ 2.71828182);
+ printf_compat("va_list compatibility: "
+ "A char: %c and "
+ "A string: %s and "
+ "An int: %d and "
+ "A long: %lld and "
+ "A double: %.10g and "
+ "A float: %.10g\n",
+ 'x',
+ "Hello, world!",
+ 42,
+ 123456789012345LL,
+ 3.141592654,
+ (float) 2.71828182);
+ return 0;
+}
+
+
+
+