diff --git a/clang/test/C/drs/dr335.c b/clang/test/C/drs/dr335.c new file mode 100644 index 000000000000..72e8a8911215 --- /dev/null +++ b/clang/test/C/drs/dr335.c @@ -0,0 +1,45 @@ +/* RUN: %clang_cc1 -std=c89 -emit-llvm -o - %s | FileCheck %s + RUN: %clang_cc1 -std=c99 -emit-llvm -o - %s | FileCheck %s + RUN: %clang_cc1 -std=c11 -emit-llvm -o - %s | FileCheck %s + RUN: %clang_cc1 -std=c17 -emit-llvm -o - %s | FileCheck %s + RUN: %clang_cc1 -std=c2x -emit-llvm -o - %s | FileCheck %s + */ + +/* WG14 DR335: yes + * _Bool bit-fields + * + * This validates the runtime behavior from the DR, see dr3xx.c for the compile + * time enforcement portion. + */ +void dr335(void) { + struct bits_ { + _Bool bbf1 : 1; + } bits = { 1 }; + + bits.bbf1 = ~bits.bbf1; + + // First, load the value from bits.bbf1 and truncate it down to one-bit. + + // CHECK: %[[LOAD1:.+]] = load i8, ptr {{.+}}, align 1 + // CHECK-NEXT: %[[CLEAR1:.+]] = and i8 %[[LOAD1]], 1 + // CHECK-NEXT: %[[CAST:.+]] = trunc i8 %[[CLEAR1]] to i1 + // CHECK-NEXT: %[[CONV:.+]] = zext i1 %[[CAST]] to i32 + + // Second, perform the unary complement. + + // CHECK-NEXT: %[[NOT:.+]] = xor i32 %[[CONV]], -1 + + // Finally, test the new value against 0. If it's nonzero, then assign one + // into the bit-field, otherwise assign zero into the bit-field. Note, this + // does not perform the operation on the promoted value, so this matches the + // requirements in C99 6.3.1.2, so a bit-field of type _Bool behaves like a + // _Bool and not like an [unsigned] int. + // CHECK-NEXT: %[[TOBOOL:.+]] = icmp ne i32 %[[NOT]], 0 + // CHECK-NEXT: %[[ZERO:.+]] = zext i1 %[[TOBOOL]] to i8 + // CHECK-NEXT: %[[LOAD2:.+]] = load i8, ptr {{.+}}, align 1 + // CHECK-NEXT: %[[CLEAR2:.+]] = and i8 %[[LOAD2]], -2 + // CHECK-NEXT: %[[SET:.+]] = or i8 %[[CLEAR2]], %[[ZERO]] + // CHECK-NEXT: store i8 %[[SET]], ptr {{.+}}, align 1 + // CHECK-NEXT: {{.+}} = trunc i8 %[[ZERO]] to i1 +} + diff --git a/clang/test/C/drs/dr338.c b/clang/test/C/drs/dr338.c new file mode 100644 index 000000000000..60e1c1e257c9 --- /dev/null +++ b/clang/test/C/drs/dr338.c @@ -0,0 +1,17 @@ +/* RUN: %clang_cc1 -std=c89 -fsyntax-only -Wuninitialized -verify %s + RUN: %clang_cc1 -std=c99 -fsyntax-only -Wuninitialized -verify %s + RUN: %clang_cc1 -std=c11 -fsyntax-only -Wuninitialized -verify %s + RUN: %clang_cc1 -std=c17 -fsyntax-only -Wuninitialized -verify %s + RUN: %clang_cc1 -std=c2x -fsyntax-only -Wuninitialized -verify %s + */ + +/* WG14 DR338: yes + * C99 seems to exclude indeterminate value from being an uninitialized register + * + * Note, because we're relying on -Wuninitialized, this test has to live in its + * own file. That analysis will not run if the file has other errors in it. + */ +int dr338(void) { + unsigned char uc; /* expected-note {{initialize the variable 'uc' to silence this warning}} */ + return uc + 1 >= 0; /* expected-warning {{variable 'uc' is uninitialized when used here}} */ +} diff --git a/clang/test/C/drs/dr3xx.c b/clang/test/C/drs/dr3xx.c index 0f06118ca6e5..5d7b104d8fcb 100644 --- a/clang/test/C/drs/dr3xx.c +++ b/clang/test/C/drs/dr3xx.c @@ -28,6 +28,9 @@ * * WG14 DR312: yes * Meaning of "known constant size" + * + * WG14 DR333: yes + * Missing Predefined Macro Name */ @@ -189,10 +192,39 @@ _Static_assert(!DR321, "__STDC_MB_MIGHT_NEQ_WC__ but all basic source characters _Static_assert(DR321, "!__STDC_MB_MIGHT_NEQ_WC__ but some character differs"); #endif -/* WG14 DR328: yes +/* WG14 DR328: partial * String literals in compound literal initialization + * + * DR328 is implemented properly in terms of allowing string literals, but is + * not implemented. See DR339 (marked as a duplicate of this one) for details. */ const char *dr328_v = (const char *){"this is a string literal"}; /* c89only-warning {{compound literals are a C99-specific feature}} */ void dr328(void) { const char *val = (const char *){"also a string literal"}; /* c89only-warning {{compound literals are a C99-specific feature}} */ } + +/* WG14 DR335: yes + * _Bool bit-fields + * + * See dr335.c also, which tests the runtime behavior of the part of the DR + * which will compile. + */ +void dr335(void) { + struct bits_ { + _Bool bbf3 : 3; /* expected-error {{width of bit-field 'bbf3' (3 bits) exceeds the width of its type (1 bit)}} + c89only-warning {{'_Bool' is a C99 extension}} + */ + }; +} + +/* WG14 DR339: partial + * Variably modified compound literals + * + * This DR is marked as a duplicate of DR328, see that DR for further + * details. + * + * FIXME: we should be diagnosing this compound literal as creating a variably- + * modified type at file scope, as we would do for a file scope variable. + */ +extern int dr339_v; +void *dr339 = &(int (*)[dr339_v]){ 0 }; diff --git a/clang/www/c_dr_status.html b/clang/www/c_dr_status.html index 52966d705e76..a889e30f5bf4 100644 --- a/clang/www/c_dr_status.html +++ b/clang/www/c_dr_status.html @@ -1921,7 +1921,14 @@

C defect report implementation status

328 C99 String literals in compound literal initialization - Yes + +
Partial + Clang properly implements the use of string literals in a compound + literal initializer, but fails to diagnose use of a variably-modified + type at file scope. DR339 (about variably-modified types) is marked as + a duplicate of DR328. +
+ 329 @@ -1951,7 +1958,7 @@

C defect report implementation status

333 C99 Missing Predefined Macro Name - Unknown + Yes 334 @@ -1963,7 +1970,7 @@

C defect report implementation status

335 NAD _Bool bit-fields - Unknown + Yes 336 @@ -1979,15 +1986,15 @@

C defect report implementation status

338 - C11 + C99 C99 seems to exclude indeterminate value from being an uninitialized register - Unknown + Yes 339 Dup Variably modified compound literal - Duplicate of 328 + Duplicate of 328 340