summaryrefslogtreecommitdiff
path: root/support/regression/tests/vaargs.c
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /support/regression/tests/vaargs.c
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'support/regression/tests/vaargs.c')
-rw-r--r--support/regression/tests/vaargs.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/support/regression/tests/vaargs.c b/support/regression/tests/vaargs.c
new file mode 100644
index 0000000..baf166d
--- /dev/null
+++ b/support/regression/tests/vaargs.c
@@ -0,0 +1,109 @@
+/** Tests argument passing to functions via va_args.
+ Assumes that up to the first two arguments can be passed in registers.
+
+ type1: va_char, int
+ type2: va_char, int
+ type3: va_char, int
+ */
+#include <testfwk.h>
+#include <stdarg.h>
+
+/* gcc 3.3 throws a warning, if char is in '...' */
+#if defined(PORT_HOST) || defined (__SDCC_pdk13) || defined (__SDCC_pdk14) || defined (__SDCC_pdk15)
+# define va_char int
+#else
+# define va_char char
+#endif
+
+#ifndef __SDCC_pic16
+static {type1}
+returnFirstArg(int marker, ...)
+{
+ va_list ap;
+ {type1} i;
+
+ va_start(ap, marker);
+ i = va_arg(ap, {type1});
+
+ va_end(ap);
+
+ LOG(("Returning %d\n", i));
+ return i;
+}
+
+static {type2}
+returnSecondArg(int marker, ...)
+{
+ va_list ap;
+ {type2} i;
+
+ va_start(ap, marker);
+ UNUSED(va_arg(ap, {type1}));
+ i = va_arg(ap, {type2});
+
+ va_end(ap);
+
+ LOG(("Returning %d\n", i));
+ return i;
+}
+
+#ifndef __SDCC_pdk14 // Lack of memory
+static {type2}
+returnSecondArgCopy(int marker, ...)
+{
+ va_list ap1, ap2;
+ {type2} i;
+
+ va_start(ap1, marker);
+ UNUSED(va_arg(ap1, {type1}));
+ va_copy(ap2, ap1);
+ i = va_arg(ap2, {type2});
+
+ va_end(ap1);
+ va_end(ap2);
+
+ LOG(("Returning %d\n", i));
+ return i;
+}
+
+static {type3}
+returnThirdArg(int marker, ...)
+{
+ va_list ap;
+ {type3} i;
+
+ va_start(ap, marker);
+ UNUSED(va_arg(ap, {type1}));
+ UNUSED(va_arg(ap, {type2}));
+ i = va_arg(ap, {type3});
+
+ va_end(ap);
+
+ LOG(("Returning %d\n", i));
+ return i;
+}
+#endif
+#endif
+
+void
+testArgs(void)
+{
+#ifndef __SDCC_pic16
+ int marker = 12;
+
+ LOG(("First arg: %u\n", returnFirstArg(marker, ({type1})123, ({type2})45, ({type3})67)));
+ ASSERT(returnFirstArg(marker, ({type1})123, ({type2})45, ({type3})67) == ({type1})123);
+ ASSERT(returnFirstArg(marker, ({type1})-123, ({type2})45, ({type3})67) == ({type1})-123);
+#ifndef __SDCC_pdk14 // Lack of memory
+ ASSERT(returnSecondArg(marker, ({type1})1, ({type2})-23, ({type3})64) == ({type2})-23);
+ ASSERT(returnSecondArg(marker, ({type1})1, ({type2})8, ({type3})64) == ({type2})8);
+
+ ASSERT(returnSecondArgCopy(marker, ({type1})1, ({type2})-23, ({type3})64) == ({type2})-23);
+ ASSERT(returnSecondArgCopy(marker, ({type1})1, ({type2})8, ({type3})64) == ({type2})8);
+
+ ASSERT(returnThirdArg(marker, ({type1})-33, ({type2})-34, ({type3})-35) == ({type3})-35);
+ ASSERT(returnThirdArg(marker, ({type1})-33, ({type2})-34, ({type3})35) == ({type3})35);
+#endif
+#endif
+}
+