[clang] 514dd3c - Update the status for more C DRs

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 12 11:06:51 PDT 2022


Author: Aaron Ballman
Date: 2022-07-12T14:06:39-04:00
New Revision: 514dd3c3c334251e573cf2201273ab3c38982e94

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

LOG: Update the status for more C DRs

This mostly finishes the DRs in the 200s. There are a few DRs left
which will require more thought and work to test.

Added: 
    clang/test/C/drs/dr268.c

Modified: 
    clang/test/C/drs/dr2xx.c
    clang/www/c_dr_status.html

Removed: 
    


################################################################################
diff  --git a/clang/test/C/drs/dr268.c b/clang/test/C/drs/dr268.c
new file mode 100644
index 000000000000..5ee0a0eb0a24
--- /dev/null
+++ b/clang/test/C/drs/dr268.c
@@ -0,0 +1,63 @@
+/* RUN: %clang_cc1 -std=c89 -pedantic -verify -emit-llvm -o -  %s | FileCheck %s
+   RUN: %clang_cc1 -std=c99 -pedantic -verify -emit-llvm -o -  %s | FileCheck %s
+   RUN: %clang_cc1 -std=c11 -pedantic -verify -emit-llvm -o -  %s | FileCheck %s
+   RUN: %clang_cc1 -std=c17 -pedantic -verify -emit-llvm -o -  %s | FileCheck %s
+   RUN: %clang_cc1 -std=c2x -pedantic -verify -emit-llvm -o -  %s | FileCheck %s
+ */
+
+/* expected-no-diagnostics */
+
+/* WG14 DR268: yes
+ * Jumps into iteration statements
+ */
+void foo(void);
+void dr268(void) {
+  int i = 5;
+  goto goto_target;
+
+  for (i = 0; i < 10; ++i) {
+    if (i > 2) ++i;
+goto_target:
+    foo();
+  }
+
+  /* Ensure that the goto jumps into the middle of the for loop body, and that
+   * the initialization and controlling expression are not evaluated on the
+   * first pass through.
+   */
+  /* Get us to the right function.
+     CHECK-LABEL: define {{.*}} void @dr268() {{.*}} {
+
+     First is the initialization and goto.
+     CHECK: store i32 5
+     CHECK-NEXT: br label %[[GOTO_TARGET:.+]]
+
+     Then comes the initialization of the for loop variable.
+     CHECK: store i32 0
+     CHECK-NEXT: br label %[[FOR_COND:.+]]
+
+     Then comes the for loop condition check label followed eventually by the
+     for loop body label.
+     CHECK: [[FOR_COND]]:
+     CHECK: {{.+}} = icmp slt i32 {{.+}}, 10
+     CHECK: [[FOR_BODY:.+]]:
+     CHECK: {{.+}} = icmp sgt i32 {{.+}}, 2
+
+     Then comes the then branch of the if statement.
+     CHECK: %[[I:.+]] = load i32,
+     CHECK-NEXT: %[[INC:.+]] = add nsw i32 %[[I]], 1
+     CHECK-NEXT: store i32 %[[INC]],
+
+     Eventually, we get to the goto label and its call
+     CHECK: [[GOTO_TARGET]]:
+     CHECK-NEXT: call void @foo()
+     CHECK-NEXT: br label %[[FOR_INC:.+]]
+
+     CHECK: [[FOR_INC]]:
+     CHECK-NEXT: %[[I2:.+]] = load i32,
+     CHECK-NEXT: %[[INC2:.+]] = add nsw i32 %[[I2]], 1
+     CHECK-NEXT: store i32 %[[INC2]],
+     CHECK-NEXT: br label %[[FOR_COND]]
+   */
+}
+

diff  --git a/clang/test/C/drs/dr2xx.c b/clang/test/C/drs/dr2xx.c
index 0d5a564ba101..af2f81266fdc 100644
--- a/clang/test/C/drs/dr2xx.c
+++ b/clang/test/C/drs/dr2xx.c
@@ -44,6 +44,24 @@
  *
  * WG14 DR255: yes
  * Non-prototyped function calls and argument mismatches
+ *
+ * WG14 DR267: yes
+ * Typos in 5.1.2.3, 7.24.4.4.5, 7.24.6.1, 7.24.6.1
+ *
+ * WG14 DR273: yes
+ * Meaning of __STDC_ISO_10646__
+ *
+ * WG14 DR278: yes
+ * Lacuna in character encodings
+ *
+ * WG14 DR279: yes
+ * Wide character code values for members of the basic character set
+ *
+ * WG14 DR282: yes
+ * Flexible array members & struct padding
+ *
+ * WG14 DR292: yes
+ * Use of the word variable
  */
 
 
@@ -252,3 +270,187 @@ void dr258(void) {
 #undef repeat
 #undef forget
 }
+
+/* WG14 DR261: yes
+ * Constant expressions
+ */
+void dr261(void) {
+  /* This is still an integer constant expression despite the overflow. */
+  enum e1 {
+    ex1 = __INT_MAX__ + 1  /* expected-warning {{overflow in expression; result is -2147483648 with type 'int'}} */
+  };
+
+  /* This is not an integer constant expression, because of the comma operator,
+   * but we fold it as a constant expression anyway as a GNU extension.
+   */
+  enum e2 {
+    ex2 = __INT_MAX__ + (0, 1) /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
+                                  expected-note {{value 2147483648 is outside the range of representable values of type 'int'}}
+                                  expected-warning {{left operand of comma operator has no effect}}
+                                */
+  };
+
+  /* It's a bit weird that we issue a "congratulations, you did the thing"
+   * diagnostic, but the diagnostic does help demonstrate that we correctly
+   * treat it as a null pointer constant value.
+   */
+  char *p1 = (1 - 1); /* expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'char *'}} */
+
+  /* This is an invalid initialization/assignment because the right-hand side
+   * does not have pointer to void or pointer to char type and is not the null
+   * pointer constant. */
+  char *p2 = (42, 1 - 1); /* expected-warning {{incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int'}}
+                             expected-warning {{left operand of comma operator has no effect}}
+                           */
+  p1 = (42, 1 - 1);       /* expected-warning {{incompatible integer to pointer conversion assigning to 'char *' from 'int'}}
+                             expected-warning {{left operand of comma operator has no effect}}
+                           */
+
+  /* These are both valid. The initialization doesn't require an integer
+   * constant expression, nor does the assignment.
+   */
+  short s1 = 42 + (0, 1); /* c89only-warning {{mixing declarations and code is a C99 extension}}
+                             expected-warning {{left operand of comma operator has no effect}}
+                           */
+  s1 = (42, 69); /* expected-warning {{left operand of comma operator has no effect}} */
+
+  /* These are both valid because they are constant expressions and the value
+   * is the null pointer constant.
+   */
+  p2 = 0;
+  p2 = 1 - 1; /* expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'char *'}} */
+}
+
+/* WG14 DR262: yes
+ * Maximum size of bit fields
+ */
+void dr262(void) {
+  _Static_assert(sizeof(short) == 2, "short is not two chars?");
+  struct S {
+    short field : __CHAR_BIT__ * 2; /* ok */
+    short other_field : __CHAR_BIT__ * 2 + 1; /* expected-error-re {{width of bit-field 'other_field' ({{[0-9]+}} bits) exceeds the width of its type ({{[0-9]+}} bits)}} */
+  };
+}
+
+/* WG14 DR263: yes
+ * All-zero bits representations
+ *
+ * This tests that the integer value 0 is not comprised of any non-zero bits,
+ * which demonstrates that a value with all zero bits will be treated as the
+ * integer value zero.
+ */
+_Static_assert(__builtin_popcount(0) < 1, "zero is not all zero bits");
+
+
+/* WG14 DR265: yes
+ * Preprocessor arithmetic
+ */
+#if __UINT_MAX__ == 0xFFFFFFFF
+/* Ensure that the literal is interpreted as intptr_t instead of uintptr_t,
+ * despite that being the phase 7 behavior being that the literal is unsigned.
+ */
+#if -0xFFFFFFFF >= 0
+#error "Interpreting the literal incorrectly in the preprocessor"
+#endif
+#endif /* __UINT_MAX__ == 0xFFFFFFFF */
+
+
+/* WG14 DR266: yes
+ * Overflow of sizeof
+ */
+void dr266(void) {
+  /* Some targets support a maximum size which cannot be represented by an
+   * unsigned long, and so unsigned long long is used instead. However, C89
+   * doesn't have the long long type, so we issue a pedantic warning about it.
+   * Disable the warning momentarily so we don't have to add target triples to
+   * the RUN lines pinning the targets down concretely.
+   */
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wlong-long"
+  (void)sizeof(int[__SIZE_MAX__ / 2][__SIZE_MAX__ / 2]); /* expected-error-re 2 {{array is too large ({{[0-9]+}} elements)}} */
+#pragma clang diagnostic pop
+}
+
+/* WG14 DR272: yes
+ * Type category
+ */
+void dr272(void) {
+  /* The crux of this DR is to confirm that lvalue conversion of the rhs on an
+   * assignment expression strips top-level qualifiers, and not all qualifiers,
+   * from the resulting expression type.
+   */
+  const int * volatile ptr;
+  (void)_Generic(ptr = 0, const int * : 1); /* expected-warning {{expression with side effects has no effect in an unevaluated context}} */
+}
+
+/* WG14 DR277: no
+ * Declarations within iteration statements
+ */
+void dr277(void) {
+  /* FIXME: it's a bit silly to issue both of these warnings at the same time
+   * in pedantic mode given that they're both effectively the same root cause.
+   *
+   * C99 6.8.5p3: The declaration part of a for statement shall only declare
+   * identifiers for objects having storage class auto or register.
+   *
+   * FIXME: we don't issue a pedantic warning below for the declaration of E,
+   * and its enumerators, none of which declare an object with auto or register
+   * storage classes.
+   */
+  for (enum E { one, two } i = one; i < two; ++i) /* c89only-warning {{variable declaration in for loop is a C99-specific feature}}
+                                                     c89only-warning {{GCC does not allow variable declarations in for loop initializers before C99}}
+                                                   */
+    ;
+}
+
+#if __STDC_VERSION__ >= 199901L
+/* WG14 DR289: yes
+ * Function prototype with [restrict]
+ *
+ * Ensure that we support [restrict] array syntax as an abstract declarator and
+ * not just as a direct declarator.
+ */
+void dr289(int * restrict const [restrict]);
+#endif /* __STDC_VERSION__ >= 199901L */
+
+/* WG14 DR295: yes
+ * Incomplete types for function parameters
+ */
+struct NotCompleted;                    /* expected-note {{forward declaration of 'struct NotCompleted'}} */
+void dr295_1(struct NotCompleted);
+void dr295_1(struct NotCompleted Val) { /* expected-error {{variable has incomplete type 'struct NotCompleted'}} */
+}
+
+/* There's no reason to reject this code, but it's technically undefined
+ * behavior, so diagnosing it is reasonable.
+ *
+ * FIXME: either downgrade this error into a warning or remove it entirely; it
+ * doesn't add a whole lot of value as an error.
+ */
+void dr295_2(void param); /* expected-error {{argument may not have 'void' type}} */
+
+/* WG14 DR298: partial
+ * Validity of constant in unsigned long long range
+ *
+ * I'm giving this one a partial because we fail to pedantically diagnose the
+ * use of 'long long' through a constant value. We correctly warn about the
+ * type when spelled out and when using an explicit suffix, but we fail to warn
+ * otherwise.
+ */
+#if __LLONG_WIDTH__ >= 64 && __LONG_WIDTH__ < 64
+/* This test requires that long long be at least 64-bits and long be smaller
+ * because the test is whether the integer literal which is too large to fit in
+ * a constant of type long long. This is undefined behavior in C, which means
+ * we're free to pick a 
diff erent type so long as we diagnose the extension
+ * appropriately.
+ */
+void dr298(void) {
+  /* FIXME: These uses of the constants need a pedantic warning in C89 mode;
+   * we've picked a type that does not exist in C89.
+   */
+  (void)_Generic(9223372036854775808,     /* expected-warning {{integer literal is too large to be represented in a signed integer type, interpreting as unsigned}} */
+                 unsigned long long : 1); /* c89only-warning {{'long long' is an extension when C99 mode is not enabled}} */
+  (void)_Generic(9223372036854775807,
+                 long long : 1);          /* c89only-warning {{'long long' is an extension when C99 mode is not enabled}} */
+}
+#endif /* __LLONG_WIDTH__ == 64 && __LONG_WIDTH__ < 64 */

diff  --git a/clang/www/c_dr_status.html b/clang/www/c_dr_status.html
index 132eadd6d6f6..59ed6defa44c 100644
--- a/clang/www/c_dr_status.html
+++ b/clang/www/c_dr_status.html
@@ -1500,19 +1500,19 @@ <h2 id="cdr">C defect report implementation status</h2>
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_261.htm">261</a></td>
     <td>NAD</td>
     <td>Constant expressions</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="262">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_262.htm">262</a></td>
     <td>C99</td>
     <td>Maximum size of bit fields</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="263">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_263.htm">263</a></td>
     <td>C99</td>
     <td>All-zero bits representations</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="264">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_264.htm">264</a></td>
@@ -1524,25 +1524,25 @@ <h2 id="cdr">C defect report implementation status</h2>
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_265.htm">265</a></td>
     <td>C99</td>
     <td>Preprocessor arithmetic</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="266">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_266.htm">266</a></td>
     <td>NAD</td>
     <td>Overflow of sizeof</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="267">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_267.htm">267</a></td>
     <td>C99</td>
     <td>Typos in 5.1.2.3, 7.24.4.4.5, 7.24.6.1, 7.24.6.1</td>
-    <td class="na" align="center">N/A</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="268">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_268.htm">268</a></td>
     <td>C99</td>
     <td>Jumps into iteration statements</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="269">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_269.htm">269</a></td>
@@ -1566,13 +1566,20 @@ <h2 id="cdr">C defect report implementation status</h2>
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_272.htm">272</a></td>
     <td>C99</td>
     <td>Type category</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="273">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_273.htm">273</a></td>
     <td>C99</td>
     <td>Meaning of __STDC_ISO_10646__</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">
+      <details><summary>Yes</summary>
+        The compiler portion of this DR is implemented in Clang, but the
+        <code>__STDC_ISO_10646__</code> macro is not defined by Clang; the
+        standard library behavior factors into whether this macro can or cannot
+        be defined.
+      </details>
+    </td>
   </tr>
   <tr id="274">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_274.htm">274</a></td>
@@ -1596,19 +1603,19 @@ <h2 id="cdr">C defect report implementation status</h2>
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_277.htm">277</a></td>
     <td>NAD</td>
     <td>Declarations within iteration statements</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
   <tr id="278">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_278.htm">278</a></td>
     <td>C99</td>
     <td>Lacuna in character encodings</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="279">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_279.htm">279</a></td>
     <td>C99</td>
     <td>Wide character code values for members of the basic character set</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="280">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_280.htm">280</a></td>
@@ -1626,7 +1633,7 @@ <h2 id="cdr">C defect report implementation status</h2>
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_282.htm">282</a></td>
     <td>C99</td>
     <td>Flexible array members & struct padding</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="283">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_283.htm">283</a></td>
@@ -1644,7 +1651,12 @@ <h2 id="cdr">C defect report implementation status</h2>
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_285.htm">285</a></td>
     <td>C99</td>
     <td>Conversion of an imaginary type to _Bool</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="partial" align="center">
+      <details><summary>Partial</summary>
+        Clang detects use of the _Imaginary keyword but does not otherwise
+        support the type yet.
+      </details>
+    </td>
   </tr>
   <tr id="286">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_286.htm">286</a></td>
@@ -1668,7 +1680,7 @@ <h2 id="cdr">C defect report implementation status</h2>
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_289.htm">289</a></td>
     <td>C99</td>
     <td>Function prototype with [restrict]</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="290">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_290.htm">290</a></td>
@@ -1686,7 +1698,7 @@ <h2 id="cdr">C defect report implementation status</h2>
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_292.htm">292</a></td>
     <td>C99</td>
     <td>Use of the word variable</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="293">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_293.htm">293</a></td>
@@ -1704,7 +1716,7 @@ <h2 id="cdr">C defect report implementation status</h2>
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_295.htm">295</a></td>
     <td>C99</td>
     <td>Incomplete types for function parameters</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
   <tr id="296">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_296.htm">296</a></td>
@@ -1722,7 +1734,14 @@ <h2 id="cdr">C defect report implementation status</h2>
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_298.htm">298</a></td>
     <td>C99</td>
     <td>Validity of constant in unsigned long long range</td>
-    <td class="unknown" align="center">Unknown</td>
+    <td class="partial" align="center">
+      <details><summary>Partial</summary>
+        Clang defines the behavior in this situation by automatically using
+        <code>long long</code> or <code>unsigned long long</code> as the
+        underlying type of the constant; however, Clang fails to diagnose the
+        extension in C89 mode with such constants.
+      </details>
+    </td>
   </tr>
   <tr id="299">
     <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_299.htm">299</a></td>


        


More information about the cfe-commits mailing list