aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@college-de-france.fr>2022-05-03 10:58:58 +0200
committerXavier Leroy <xavier.leroy@college-de-france.fr>2022-05-13 11:22:31 +0200
commitb4e339e81504f3fe1734a59b9950034bee46b415 (patch)
tree7533a962d147cbcd63f047b9584b33be66baba55
parente44143ad023400c7a8193b7e9fc3b62b9f9614e1 (diff)
downloadcompcert-b4e339e81504f3fe1734a59b9950034bee46b415.tar.gz
compcert-b4e339e81504f3fe1734a59b9950034bee46b415.zip
Some tests for _Generic
-rw-r--r--test/regression/Makefile2
-rw-r--r--test/regression/Results/generic7
-rw-r--r--test/regression/generic.c107
3 files changed, 115 insertions, 1 deletions
diff --git a/test/regression/Makefile b/test/regression/Makefile
index 33a9f993..daee05bc 100644
--- a/test/regression/Makefile
+++ b/test/regression/Makefile
@@ -16,7 +16,7 @@ TESTS=int32 int64 floats floats-basics floats-lit \
funct3 expr5 struct7 struct8 struct11 struct12 casts1 casts2 char1 \
sizeof1 sizeof2 binops bool for1 for2 switch switch2 compound \
decl1 bitfields9 ptrs3 \
- parsing krfun ifconv
+ parsing krfun ifconv generic
# Can run, but only in compiled mode, and have reference output in Results
diff --git a/test/regression/Results/generic b/test/regression/Results/generic
new file mode 100644
index 00000000..134ea40c
--- /dev/null
+++ b/test/regression/Results/generic
@@ -0,0 +1,7 @@
+1
+-2
+42
+1.23
+4.57
+other
+other
diff --git a/test/regression/generic.c b/test/regression/generic.c
new file mode 100644
index 00000000..5a149a8f
--- /dev/null
+++ b/test/regression/generic.c
@@ -0,0 +1,107 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Some tests from GCC, c11-generic-1.c */
+
+void check (int n)
+{
+ if (n) abort ();
+}
+
+void test1(void)
+{
+ int n = 0;
+
+ check (_Generic (n++, int: 0));
+ /* _Generic should not evaluate its argument. */
+ check (n);
+
+ check (_Generic (n, double: n++, default: 0));
+ check (n);
+
+ /* Qualifiers are removed for the purpose of type matching. */
+ const int cn = 0;
+ check (_Generic (cn, int: 0, default: n++));
+ check (n);
+ check (_Generic ((const int) n, int: 0, default: n++));
+ check (n);
+
+ /* Arrays decay to pointers. */
+ int a[1];
+ const int ca[1];
+ check (_Generic (a, int *: 0, const int *: n++));
+ check (n);
+ check (_Generic (ca, const int *: 0, int *: n++));
+ check (n);
+
+ /* Functions decay to pointers. */
+ extern void f (void);
+ check (_Generic (f, void (*) (void): 0, default: n++));
+ check (n);
+
+ /* _Noreturn is not part of the function type. */
+ check (_Generic (&abort, void (*) (void): 0, default: n++));
+ check (n);
+
+ /* Integer promotions do not occur. */
+ short s;
+ check (_Generic (s, short: 0, int: n++));
+ check (n);
+}
+
+
+/* Some tests from Clang, Sema/generic-selection.c */
+
+void test2(int n)
+{
+ int a1[_Generic(0, int: 1, short: 2, float: 3, default: 4) == 1 ? 1 : -1];
+ int a2[_Generic(0, default: 1, short: 2, float: 3, int: 4) == 4 ? 1 : -1];
+ int a3[_Generic(0L, int: 1, short: 2, float: 3, default: 4) == 4 ? 1 : -1];
+ int a4[_Generic(0L, default: 1, short: 2, float: 3, int: 4) == 1 ? 1 : -1];
+ int a5[_Generic(0, int: 1, short: 2, float: 3) == 1 ? 1 : -1];
+ int a6[_Generic(0, short: 1, float: 2, int: 3) == 3 ? 1 : -1];
+ int a7[_Generic("test", char *: 1, default: 2) == 1 ? 1 : -1];
+ int a8[_Generic(test1, void (*)(void): 1, default: 2) == 1 ? 1 : -1];
+ int b8[_Generic(test2, void (*)(void): 1, default: 2) == 2 ? 1 : -1];
+ int c8[_Generic(test2, void (*)(int): 1, default: 2) == 1 ? 1 : -1];
+ const int i = 12;
+ int a9[_Generic(i, int: 1, default: 2) == 1 ? 1 : -1];
+ (void)_Generic(*(int *)0, int: 1);
+}
+
+/* Misc tests */
+
+void print_int(long long x)
+{
+ printf("%lld\n", x);
+}
+
+void print_fp(double x)
+{
+ printf("%.2f\n", x);
+}
+
+void print_other(void * x)
+{
+ printf("other\n");
+}
+
+#define PRINT(x) \
+ _Generic((x), \
+ int: print_int, long: print_int, long long: print_int, \
+ float: print_fp, double: print_fp, \
+ default: print_other) (x)
+
+int main()
+{
+ test1();
+ test2(5);
+ PRINT(1);
+ PRINT(-2L);
+ PRINT(42LL);
+ PRINT(1.23f);
+ PRINT(4.56789);
+ PRINT("hello!");
+ PRINT(NULL);
+}
+