[clang] clang: add test for C2y n3605 (PR #178479)
Henry Kleynhans via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 30 01:25:39 PST 2026
https://github.com/hkleynhans updated https://github.com/llvm/llvm-project/pull/178479
>From 722ec904999f402cf15f695ab1c3c65573542530 Mon Sep 17 00:00:00 2001
From: Henry Kleynhans <henry.kleynhans at gmail.com>
Date: Wed, 28 Jan 2026 18:17:04 +0000
Subject: [PATCH 1/3] [clang] add test for ISO-C n3605
Add a test for N3605: Generic replacement (v. 2 of quasi-literals)
The paper clarifies existing behavior of _Generic selection and
parenthesis. This PR adds tests along the same lines and mark the
feature as supported.
---
clang/test/C/C2y/n3605.c | 50 ++++++++++++++++++++++++++++++++++++++
clang/test/C/C2y/n3605_1.c | 3 +++
clang/www/c_status.html | 2 +-
3 files changed, 54 insertions(+), 1 deletion(-)
create mode 100644 clang/test/C/C2y/n3605.c
create mode 100644 clang/test/C/C2y/n3605_1.c
diff --git a/clang/test/C/C2y/n3605.c b/clang/test/C/C2y/n3605.c
new file mode 100644
index 0000000000000..a8eaf34a37d3a
--- /dev/null
+++ b/clang/test/C/C2y/n3605.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s
+// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c2y %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
+
+enum A{ a=(int)(_Generic(0, int: (2.5))) };
+enum B{ b=(int)(_Generic(0, int: (2 + 1))) };
+
+constexpr int c = _Generic((float*)0, default: 0);
+
+constexpr int d = _Generic((float*)0, default: (sizeof(c)));
+
+char s[] = _Generic(0, default: ("word"));
+
+// static_assert(1, _Generic(1, default: "Error Message"));
+
+int value_of_a() {
+ // CHECK: ret i32 2
+ return a;
+}
+
+int value_of_b() {
+ // CHECK: ret i32 3
+ return b;
+}
+
+int value_of_c() {
+ // CHECK: ret i32 0
+ return c;
+}
+
+int value_of_d() {
+ // CHECK: ret i32 4
+ return d;
+}
+
+char *value_of_s() {
+ // CHECK: ret ptr @s
+ return s;
+}
+
+float value_of_float() {
+ // CHECK: %f = alloca ptr, align 8
+ // CHECK: store ptr null, ptr %f, align 8
+ // CHECK: %0 = load ptr, ptr %f, align 8
+ // CHECK: %call = call float %0()
+ // CHECK: ret float %call
+
+ float (*f)(void) = _Generic(1, default: (void*)0);
+ return f();
+}
\ No newline at end of file
diff --git a/clang/test/C/C2y/n3605_1.c b/clang/test/C/C2y/n3605_1.c
new file mode 100644
index 0000000000000..3e0975d338c6f
--- /dev/null
+++ b/clang/test/C/C2y/n3605_1.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s
+
+static_assert(1, _Generic(1, default: "Error Message")); // expected-error{{expected string literal for diagnostic message in static_assert}}
diff --git a/clang/www/c_status.html b/clang/www/c_status.html
index ccf19ea86957a..6c920773aba61 100644
--- a/clang/www/c_status.html
+++ b/clang/www/c_status.html
@@ -354,7 +354,7 @@ <h2 id="c2y">C2y implementation status</h2>
<tr>
<td>Generic replacement (v. 2 of quasi-literals)</td>
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3605.pdf">N3605</a></td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="full" align="center">Yes</td>
</tr>
<tr>
<td>Member access of an incomplete object</td>
>From d7a4743fcf16d5cfb5615512a8f6bced69055f19 Mon Sep 17 00:00:00 2001
From: Henry Kleynhans <henry.kleynhans at gmail.com>
Date: Thu, 29 Jan 2026 18:47:43 +0000
Subject: [PATCH 2/3] Test C versions from C11
---
clang/test/C/C2y/n3605.c | 26 +++++++++++--------
clang/test/C/C2y/n3605_1.c | 52 ++++++++++++++++++++++++++++++++++++--
clang/test/C/C2y/n3605_2.c | 4 +++
3 files changed, 69 insertions(+), 13 deletions(-)
create mode 100644 clang/test/C/C2y/n3605_2.c
diff --git a/clang/test/C/C2y/n3605.c b/clang/test/C/C2y/n3605.c
index a8eaf34a37d3a..0a8b21ab0ad58 100644
--- a/clang/test/C/C2y/n3605.c
+++ b/clang/test/C/C2y/n3605.c
@@ -1,44 +1,48 @@
// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s
+// RUN: %clang_cc1 -verify -std=c23 -Wall -pedantic %s
// expected-no-diagnostics
// RUN: %clang_cc1 -std=c2y %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c23 %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
enum A{ a=(int)(_Generic(0, int: (2.5))) };
enum B{ b=(int)(_Generic(0, int: (2 + 1))) };
-constexpr int c = _Generic((float*)0, default: 0);
-
+#if (__STDC_VERSION__ >= 202311L)
+constexpr int c = _Generic((float*)0, default: 0);
constexpr int d = _Generic((float*)0, default: (sizeof(c)));
+#else
+int c = _Generic((float*)0, default: 0);
+int d = _Generic((float*)0, default: (sizeof(c)));
+#endif
char s[] = _Generic(0, default: ("word"));
-// static_assert(1, _Generic(1, default: "Error Message"));
-
-int value_of_a() {
+int value_of_a(void) {
// CHECK: ret i32 2
return a;
}
-int value_of_b() {
+int value_of_b(void) {
// CHECK: ret i32 3
return b;
}
-int value_of_c() {
+int value_of_c(void) {
// CHECK: ret i32 0
return c;
}
-int value_of_d() {
+int value_of_d(void) {
// CHECK: ret i32 4
return d;
}
-char *value_of_s() {
+char *value_of_s(void) {
// CHECK: ret ptr @s
return s;
}
-float value_of_float() {
+float value_of_float(void) {
// CHECK: %f = alloca ptr, align 8
// CHECK: store ptr null, ptr %f, align 8
// CHECK: %0 = load ptr, ptr %f, align 8
@@ -47,4 +51,4 @@ float value_of_float() {
float (*f)(void) = _Generic(1, default: (void*)0);
return f();
-}
\ No newline at end of file
+}
diff --git a/clang/test/C/C2y/n3605_1.c b/clang/test/C/C2y/n3605_1.c
index 3e0975d338c6f..3478f74502132 100644
--- a/clang/test/C/C2y/n3605_1.c
+++ b/clang/test/C/C2y/n3605_1.c
@@ -1,3 +1,51 @@
-// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s
+// RUN: %clang_cc1 -verify -std=c17 -Wall -pedantic %s
+// RUN: %clang_cc1 -verify -std=c11 -Wall -pedantic %s
+// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c17 %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c11 %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
-static_assert(1, _Generic(1, default: "Error Message")); // expected-error{{expected string literal for diagnostic message in static_assert}}
+enum A{ a=(int)(_Generic(0, int: (2.5))) };
+enum B{ b=(int)(_Generic(0, int: (2 + 1))) };
+
+int c = _Generic((float*)0, default: 0);
+int d = _Generic((float*)0, default: (sizeof(c)));
+
+char s[] = _Generic(0, default: ("word"));
+
+int value_of_a(void) {
+ // CHECK: ret i32 2
+ return a;
+}
+
+int value_of_b(void) {
+ // CHECK: ret i32 3
+ return b;
+}
+
+int value_of_c(void) {
+ // CHECK: %0 = load i32, ptr @c, align 4
+ // CHECK: ret i32 %0
+ return c;
+}
+
+int value_of_d(void) {
+ // CHECK: %0 = load i32, ptr @d, align 4
+ // CHECK: ret i32 %0
+ return d;
+}
+
+char *value_of_s(void) {
+ // CHECK: ret ptr @s
+ return s;
+}
+
+float value_of_float(void) {
+ // CHECK: %f = alloca ptr, align 8
+ // CHECK: store ptr null, ptr %f, align 8
+ // CHECK: %0 = load ptr, ptr %f, align 8
+ // CHECK: %call = call float %0()
+ // CHECK: ret float %call
+
+ float (*f)(void) = _Generic(1, default: (void*)0);
+ return f();
+}
diff --git a/clang/test/C/C2y/n3605_2.c b/clang/test/C/C2y/n3605_2.c
new file mode 100644
index 0000000000000..cb336ab9af7fa
--- /dev/null
+++ b/clang/test/C/C2y/n3605_2.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s
+// RUN: %clang_cc1 -verify -std=c23 -Wall -pedantic %s
+
+static_assert(1, _Generic(1, default: "Error Message")); // expected-error{{expected string literal for diagnostic message in static_assert}}
>From 028f50cd7765208afaa6344ecd3b498b4ad2b7e8 Mon Sep 17 00:00:00 2001
From: Henry Kleynhans <henry.kleynhans at gmail.com>
Date: Fri, 30 Jan 2026 09:25:19 +0000
Subject: [PATCH 3/3] Remove duplication
---
clang/test/C/C2y/n3605.c | 17 ++++++++------
clang/test/C/C2y/n3605_1.c | 48 +++++++-------------------------------
2 files changed, 18 insertions(+), 47 deletions(-)
diff --git a/clang/test/C/C2y/n3605.c b/clang/test/C/C2y/n3605.c
index 0a8b21ab0ad58..f04ec557ddc11 100644
--- a/clang/test/C/C2y/n3605.c
+++ b/clang/test/C/C2y/n3605.c
@@ -1,19 +1,18 @@
// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s
// RUN: %clang_cc1 -verify -std=c23 -Wall -pedantic %s
+// RUN: %clang_cc1 -verify -std=c17 -Wall -pedantic %s
+// RUN: %clang_cc1 -verify -std=c11 -Wall -pedantic %s
// expected-no-diagnostics
// RUN: %clang_cc1 -std=c2y %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -std=c23 %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c17 %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c11 %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
enum A{ a=(int)(_Generic(0, int: (2.5))) };
enum B{ b=(int)(_Generic(0, int: (2 + 1))) };
-#if (__STDC_VERSION__ >= 202311L)
-constexpr int c = _Generic((float*)0, default: 0);
-constexpr int d = _Generic((float*)0, default: (sizeof(c)));
-#else
int c = _Generic((float*)0, default: 0);
int d = _Generic((float*)0, default: (sizeof(c)));
-#endif
char s[] = _Generic(0, default: ("word"));
@@ -28,12 +27,14 @@ int value_of_b(void) {
}
int value_of_c(void) {
- // CHECK: ret i32 0
+ // CHECK: %0 = load i32, ptr @c, align 4
+ // CHECK: ret i32 %0
return c;
}
int value_of_d(void) {
- // CHECK: ret i32 4
+ // CHECK: %0 = load i32, ptr @d, align 4
+ // CHECK: ret i32 %0
return d;
}
@@ -52,3 +53,5 @@ float value_of_float(void) {
float (*f)(void) = _Generic(1, default: (void*)0);
return f();
}
+
+
diff --git a/clang/test/C/C2y/n3605_1.c b/clang/test/C/C2y/n3605_1.c
index 3478f74502132..ee33beadeaadd 100644
--- a/clang/test/C/C2y/n3605_1.c
+++ b/clang/test/C/C2y/n3605_1.c
@@ -1,51 +1,19 @@
-// RUN: %clang_cc1 -verify -std=c17 -Wall -pedantic %s
-// RUN: %clang_cc1 -verify -std=c11 -Wall -pedantic %s
+// RUN: %clang_cc1 -verify -std=c2y -Wall -pedantic %s
+// RUN: %clang_cc1 -verify -std=c23 -Wall -pedantic %s
// expected-no-diagnostics
-// RUN: %clang_cc1 -std=c17 %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -std=c11 %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c2y %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c23 %s -triple x86_64 --embed-dir=%S/Inputs -emit-llvm -o - | FileCheck %s
-enum A{ a=(int)(_Generic(0, int: (2.5))) };
-enum B{ b=(int)(_Generic(0, int: (2 + 1))) };
-
-int c = _Generic((float*)0, default: 0);
-int d = _Generic((float*)0, default: (sizeof(c)));
-
-char s[] = _Generic(0, default: ("word"));
+constexpr int a = _Generic((float*)0, default: 0);
+constexpr int b = _Generic((float*)0, default: (sizeof(a)));
int value_of_a(void) {
- // CHECK: ret i32 2
+ // CHECK: ret i32 0
return a;
}
int value_of_b(void) {
- // CHECK: ret i32 3
+ // CHECK: ret i32 4
return b;
}
-int value_of_c(void) {
- // CHECK: %0 = load i32, ptr @c, align 4
- // CHECK: ret i32 %0
- return c;
-}
-
-int value_of_d(void) {
- // CHECK: %0 = load i32, ptr @d, align 4
- // CHECK: ret i32 %0
- return d;
-}
-
-char *value_of_s(void) {
- // CHECK: ret ptr @s
- return s;
-}
-
-float value_of_float(void) {
- // CHECK: %f = alloca ptr, align 8
- // CHECK: store ptr null, ptr %f, align 8
- // CHECK: %0 = load ptr, ptr %f, align 8
- // CHECK: %call = call float %0()
- // CHECK: ret float %call
-
- float (*f)(void) = _Generic(1, default: (void*)0);
- return f();
-}
More information about the cfe-commits
mailing list