aboutsummaryrefslogtreecommitdiff
path: root/clang/test/C
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/C')
-rw-r--r--clang/test/C/C2y/n3457.c38
-rw-r--r--clang/test/C/C2y/n3457_1.c20
-rw-r--r--clang/test/C/C2y/n3457_2.c10
3 files changed, 68 insertions, 0 deletions
diff --git a/clang/test/C/C2y/n3457.c b/clang/test/C/C2y/n3457.c
new file mode 100644
index 0000000..d71a3f3
--- /dev/null
+++ b/clang/test/C/C2y/n3457.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -verify=ext -std=c23 -pedantic %s
+// RUN: %clang_cc1 -verify=ext -pedantic -x c++ %s
+// RUN: %clang_cc1 -verify=pre -std=c2y -pedantic -Wpre-c2y-compat %s
+
+/* WG14 N3457: Clang 22
+ * The __COUNTER__ predefined macro
+ *
+ * This predefined macro was supported as an extension in earlier versions of
+ * Clang, but the required diagnostics for the limits were not added until 22.
+ */
+
+// Ensure that __COUNTER__ starts from 0.
+static_assert(__COUNTER__ == 0); /* ext-warning {{'__COUNTER__' is a C2y extension}}
+ pre-warning {{'__COUNTER__' is incompatible with standards before C2y}}
+ */
+
+// Ensure that the produced value can be used with token concatenation.
+#define CAT_IMPL(a, b) a ## b
+#define CAT(a, b) CAT_IMPL(a, b)
+#define NAME_WITH_COUNTER(a) CAT(a, __COUNTER__)
+void test() {
+ // Because this is the 2nd expansion, this defines test1.
+ int NAME_WITH_COUNTER(test); /* ext-warning {{'__COUNTER__' is a C2y extension}}
+ pre-warning {{'__COUNTER__' is incompatible with standards before C2y}}
+ */
+ int other_test = test1; // Ok
+}
+
+// Ensure that __COUNTER__ increments each time you mention it.
+static_assert(__COUNTER__ == 2); /* ext-warning {{'__COUNTER__' is a C2y extension}}
+ pre-warning {{'__COUNTER__' is incompatible with standards before C2y}}
+ */
+static_assert(__COUNTER__ == 3); /* ext-warning {{'__COUNTER__' is a C2y extension}}
+ pre-warning {{'__COUNTER__' is incompatible with standards before C2y}}
+ */
+static_assert(__COUNTER__ == 4); /* ext-warning {{'__COUNTER__' is a C2y extension}}
+ pre-warning {{'__COUNTER__' is incompatible with standards before C2y}}
+ */
diff --git a/clang/test/C/C2y/n3457_1.c b/clang/test/C/C2y/n3457_1.c
new file mode 100644
index 0000000..76c5a0b
--- /dev/null
+++ b/clang/test/C/C2y/n3457_1.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -std=c2y -finitial-counter-value=2147483646 %s
+
+// The value produced needs to be a type that's representable with a signed
+// long. However, the actual type it expands to does *not* need to be forced to
+// be signed long because that would generally mean suffixing the value with L,
+// which would be very surprising for folks using this to generate unique ids.
+// We'll test this by ensuring the largest value can be expanded properly and
+// an assertion that signed long is always at least four bytes wide (which is
+// what's required to represent that maximal value).
+//
+// So we set the initial counter value to 2147483646, we'll validate that,
+// increment it once to get to the maximal value and ensure there's no
+// diagnostic, then increment again to ensure we get the constraint violation.
+
+static_assert(__COUNTER__ == 2147483646); // Test and increment
+static_assert(__COUNTER__ == 2147483647); // Test and increment
+
+// This one should fail.
+signed long i = __COUNTER__; // expected-error {{'__COUNTER__' value cannot exceed 2'147'483'647}}
+
diff --git a/clang/test/C/C2y/n3457_2.c b/clang/test/C/C2y/n3457_2.c
new file mode 100644
index 0000000..018c8f4
--- /dev/null
+++ b/clang/test/C/C2y/n3457_2.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -verify=good -std=c2y -finitial-counter-value=2147483648 %s
+// RUN: %clang_cc1 -verify -std=c2y -finitial-counter-value=2147483648 -DEXPAND_IT %s
+// good-no-diagnostics
+
+// This sets the intial __COUNTER__ value to something that's too big. Setting
+// the value too large is fine. Expanding to a too-large value is not.
+#ifdef EXPAND_IT
+ // This one should fail.
+ signed long i = __COUNTER__; // expected-error {{'__COUNTER__' value cannot exceed 2'147'483'647}}
+#endif