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> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits