[clang] ba79c2a - Update the implementation status of some C11 features

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 13 07:17:54 PDT 2022


Author: Aaron Ballman
Date: 2022-08-13T10:17:47-04:00
New Revision: ba79c2a25069f09728625982c424920452fa6b83

URL: https://github.com/llvm/llvm-project/commit/ba79c2a25069f09728625982c424920452fa6b83
DIFF: https://github.com/llvm/llvm-project/commit/ba79c2a25069f09728625982c424920452fa6b83.diff

LOG: Update the implementation status of some C11 features

This also starts to add some test coverage for specific papers to
validate conformance against.

Added: 
    clang/test/C/C11/n1316.c
    clang/test/C/C11/n1330.c
    clang/test/C/C11/n1356.c
    clang/test/C/C11/n1391.c
    clang/test/C/C11/n1460.c

Modified: 
    clang/www/c_status.html

Removed: 
    


################################################################################
diff  --git a/clang/test/C/C11/n1316.c b/clang/test/C/C11/n1316.c
new file mode 100644
index 000000000000..ade895fc893f
--- /dev/null
+++ b/clang/test/C/C11/n1316.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -verify %s
+
+/* WG14 N1316: Yes
+ * Conversion between pointers and floating types
+ */
+
+void call_ptr(void *);  // expected-note {{passing argument to parameter here}}
+void call_float(float); // expected-note {{passing argument to parameter here}}
+
+void test(float in_f, void *in_vp) {
+  float f = in_vp; // expected-error {{initializing 'float' with an expression of incompatible type 'void *'}}
+  void *vp = in_f; // expected-error {{initializing 'void *' with an expression of incompatible type 'float'}}
+
+  call_ptr(f);    // expected-error {{passing 'float' to parameter of incompatible type 'void *'}}
+  call_float(vp); // expected-error {{passing 'void *' to parameter of incompatible type 'float'}}
+
+  vp = f; // expected-error {{assigning to 'void *' from incompatible type 'float'}}
+  f = vp; // expected-error {{assigning to 'float' from incompatible type 'void *'}}
+
+  struct S {
+    void *ptr;
+    float flt;
+  } s = { f, vp }; // expected-error {{initializing 'void *' with an expression of incompatible type 'float'}} \
+                      expected-error {{initializing 'float' with an expression of incompatible type 'void *'}}
+}
+

diff  --git a/clang/test/C/C11/n1330.c b/clang/test/C/C11/n1330.c
new file mode 100644
index 000000000000..4208464610b6
--- /dev/null
+++ b/clang/test/C/C11/n1330.c
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -verify %s
+
+/* WG14 N1330: Yes
+ * Static assertions
+ */
+
+// Test syntactic requirements: first argument must be a constant expression,
+// and the second argument must be a string literal. We support the C2x
+// extension that allows you to elide the second argument.
+int a;
+_Static_assert(a, ""); // expected-error {{static assertion expression is not an integral constant expression}}
+_Static_assert(1);     // expected-warning {{'_Static_assert' with no message is a C2x extension}}
+
+// Test functional requirements
+_Static_assert(1, "this works");
+_Static_assert(0, "this fails"); // expected-error {{static assertion failed: this fails}}
+_Static_assert(0); // expected-error {{static assertion failed}} \
+                      expected-warning {{'_Static_assert' with no message is a C2x extension}}
+
+// Test declaration contexts. We've already demonstrated that file scope works.
+struct S {
+  _Static_assert(1, "this works");
+  union U {
+    long l;
+    _Static_assert(1, "this works");
+  } u;
+  enum E {
+    _Static_assert(1, "this should not compile"); // expected-error {{expected identifier}}
+    One
+  } e;
+};
+
+void func(                                     // expected-note {{to match this '('}}
+  _Static_assert(1, "this should not compile") // expected-error {{expected parameter declarator}} \
+                                                  expected-error {{expected ')'}}
+);
+void func(                                     // expected-note {{to match this '('}}
+  _Static_assert(1, "this should not compile") // expected-error {{expected parameter declarator}} \
+                                                  expected-error {{expected ')'}}
+) {}
+
+void test(void) {
+  _Static_assert(1, "this works");
+  _Static_assert(0, "this fails"); // expected-error {{static assertion failed: this fails}}
+
+  // The use of a _Static_assert in a for loop declaration is prohibited per
+  // 6.8.5p3 requiring the declaration to only declare identifiers for objects
+  // having auto or register storage class; a static assertion does not declare
+  // an identifier nor an object.
+  // FIXME: this diagnostic is pretty terrible.
+  int i = 0;
+  for (_Static_assert(1, "this should not compile"); i < 10; ++i) // expected-error {{expected identifier or '('}} \
+                                                                     expected-error {{expected ';' in 'for' statement specifier}}
+    ;
+
+  // Ensure that only an integer constant expression can be used as the
+  // controlling expression.
+  _Static_assert(1.0f, "this should not compile"); // expected-error {{static assertion expression is not an integral constant expression}}
+}
+
+// FIXME: This is using the placeholder date Clang produces for the macro in
+// C2x mode; switch to the correct value once it's been published.
+#if __STDC_VERSION__ < 202000L
+// The use of a _Static_assert in a K&R C function definition is prohibited per
+// 6.9.1p6 requiring each declaration to have a declarator (which a static
+// assertion does not have) and only declare identifiers from the identifier
+// list.
+// The error about expecting a ';' is due to the static assertion confusing the
+// compiler. It'd be nice if we improved the diagnostics here, but because this
+// involves a K&R C declaration, it's low priority.
+void knr(a, b, c) // expected-warning {{a function definition without a prototype is deprecated in all versions of C and is not supported in C2x}}
+  int a, b; // expected-error {{expected ';' at end of declaration}}
+  _Static_assert(1, "this should not compile"); // expected-error {{expected identifier or '('}} \
+                                                   expected-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+  float c;
+{
+}
+#endif // __STDC_VERSION__

diff  --git a/clang/test/C/C11/n1356.c b/clang/test/C/C11/n1356.c
new file mode 100644
index 000000000000..104e197fc95b
--- /dev/null
+++ b/clang/test/C/C11/n1356.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify %s
+
+/* WG14 N1356: Yes
+ * _Bool bit-fields
+ */
+
+// C does not allow the bit-width of a bit-field to exceed the width of the
+// bit-field type, and _Bool is only required to be able to store 0 and 1
+// (and thus is implicitly unsigned), which only requires a single bit.
+#if __BOOL_WIDTH__ < __CHAR_BIT__
+struct S {
+  _Bool b : __CHAR_BIT__; // expected-error {{width of bit-field 'b' (8 bits) exceeds the width of its type (1 bit)}}
+};
+#else
+// expected-no-diagnostics
+#endif
+

diff  --git a/clang/test/C/C11/n1391.c b/clang/test/C/C11/n1391.c
new file mode 100644
index 000000000000..afe51250b452
--- /dev/null
+++ b/clang/test/C/C11/n1391.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+/* WG14 N1391: Yes
+ * Floating-point to int/_Bool conversions
+ */
+
+int neg_zero(void) {
+  // CHECK: define{{.*}} i32 @neg_zero()
+  return (_Bool)-0.0 ? -1 : 1; // Negative zero -> false
+  // CHECK: ret i32 1
+}
+
+int pos_inf(void) {
+  // CHECK: define{{.*}} i32 @pos_inf()
+  return (_Bool)(1.0f / 0.0f) ? 1 : -1; // Positive inf -> true
+  // CHECK: ret i32 1
+}
+
+int neg_inf(void) {
+  // CHECK: define{{.*}} i32 @neg_inf()
+  return (_Bool)(-1.0f / 0.0f) ? 1 : -1; // Negative inf -> true
+  // CHECK: ret i32 1
+}
+
+int nan(void) {
+  // CHECK: define{{.*}} i32 @nan()
+  return (_Bool)(0.0f / 0.0f) ? 1 : -1; // NaN -> true
+  // CHECK: ret i32 1
+}

diff  --git a/clang/test/C/C11/n1460.c b/clang/test/C/C11/n1460.c
new file mode 100644
index 000000000000..c52ea22d9927
--- /dev/null
+++ b/clang/test/C/C11/n1460.c
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -verify -Wno-vla %s
+
+/* WG14 N1460: Yes
+ * Subsetting the standard
+ */
+
+// If we claim to not support the feature then we expect diagnostics when
+// using that feature. Otherwise, we expect no diagnostics.
+#ifdef __STDC_NO_COMPLEX__
+  // We do not have any targets which do not support complex, so we don't
+  // expect to get into this block.
+  #error "it's unexpected that we don't support complex"
+  float _Complex fc;
+  double _Complex dc;
+  long double _Complex ldc;
+#else
+  #define HAS_COMPLEX
+  float _Complex fc;
+  double _Complex dc;
+  long double _Complex ldc;
+#endif
+
+#ifdef __STDC_NO_VLA__
+  // We do not have any targets which do not support VLAs, so we don't expect
+  // to get into this block.
+  #error "it's unexpected that we don't support VLAs"
+
+  void func(int n, int m[n]) {
+    int array[n];
+  }
+#else
+  #define HAS_VLA
+  void func(int n, int m[n]) {
+    int array[n];
+  }
+#endif
+
+// NB: it's not possible to test for __STDC_NO_THREADS__ because that is
+// specifically about whether <threads.h> exists and is supported, which is
+// outside the control of the compiler. It does not cover use of thread_local.
+
+#if defined(HAS_COMPLEX) && defined(HAS_VLA)
+// If we support all these optional features, we don't expect any other
+// diagnostics to have fired.
+
+// expected-no-diagnostics
+#endif
+

diff  --git a/clang/www/c_status.html b/clang/www/c_status.html
index 68e82773dee2..50509476c518 100644
--- a/clang/www/c_status.html
+++ b/clang/www/c_status.html
@@ -451,7 +451,7 @@ <h2 id="c11">C11 implementation status</h2>
     <tr>
       <td>_Bool bit-fields</td>
       <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1356.htm">N1356</a></td>
-      <td class="unknown" align="center">Unknown</td>
+      <td class="full" align="center">Yes</td>
     </tr>
     <tr>
       <td>Technical corrigendum for C1X</td>
@@ -486,7 +486,7 @@ <h2 id="c11">C11 implementation status</h2>
     <tr>
       <td>Floating-point to int/_Bool conversions</td>
       <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1391.htm">N1391</a></td>
-      <td class="unknown" align="center">Unknown</td>
+      <td class="full" align="center">Yes</td>
     </tr>
     <tr>
       <td>Analyzability (along the lines)</td>
@@ -517,7 +517,7 @@ <h2 id="c11">C11 implementation status</h2>
     <tr>
       <td>Completeness of types</td>
       <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1439.pdf">N1439</a></td>
-      <td class="unknown" align="center">Unknown</td>
+      <td class="full" align="center">Yes</td>
     </tr>
     <tr>
       <td>Generic macro facility</td>
@@ -532,7 +532,7 @@ <h2 id="c11">C11 implementation status</h2>
     <tr>
       <td>Subsetting the standard</td>
       <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1460.htm">N1460</a></td>
-      <td class="unknown" align="center">Unknown</td>
+      <td class="full" align="center">Yes</td>
     </tr>
     <tr>
       <td>Assumed types in F.9.2</td>


        


More information about the cfe-commits mailing list