From: Aaron Ballman Date: Wed, 25 May 2022 12:17:10 +0000 (-0400) Subject: Test C DR conformance (part three of many) X-Git-Tag: upstream/15.0.7~6765 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f96aa834d7d77bb875d5bb727b89ab4af7940a0c;p=platform%2Fupstream%2Fllvm.git Test C DR conformance (part three of many) This adds more of the tests for the first 100 DRs in C and updates their status on the status page. --- diff --git a/clang/test/C/drs/dr094.c b/clang/test/C/drs/dr094.c new file mode 100644 index 0000000..132193b --- /dev/null +++ b/clang/test/C/drs/dr094.c @@ -0,0 +1,29 @@ +/* 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 DR094: yes + * Are constraints on function return the same as assignment? + */ + +float func(void) { return 1.0f; } +void other_func(void) { + int i; + float f; + + /* Test that there's been a conversion from float to int. */ + i = func(); + // CHECK: %call = call float @func() + // CHECK-NEXT: %conv = fptosi float %call to i32 + // CHECK-NEXT: store i32 %conv, ptr %i, align 4 + + /* Test that the conversion looks the same as an assignment. */ + i = f; + // CHECK: %0 = load float, ptr %f, align 4 + // CHECK-NEXT: %conv1 = fptosi float %0 to i32 + // CHECK-NEXT: store i32 %conv1, ptr %i, align 4 +} + diff --git a/clang/test/C/drs/dr0xx.c b/clang/test/C/drs/dr0xx.c index b0b57fa..22b38de 100644 --- a/clang/test/C/drs/dr0xx.c +++ b/clang/test/C/drs/dr0xx.c @@ -57,6 +57,27 @@ * * WG14 DR067: yes * Integer and integral type confusion + * + * WG14 DR069: yes + * Questions about the representation of integer types + * + * WG14 DR077: yes + * Stability of addresses + * + * WG14 DR080: yes + * Merging of string constants + * + * WG14 DR086: yes + * Object-like macros in system headers + * + * WG14 DR091: yes + * Multibyte encodings + * + * WG14 DR092: dup 060 + * Partial initialization of strings + * + * WG14 DR093: yes + * Reservation of identifiers */ @@ -238,6 +259,17 @@ _Static_assert(DR038(DR038_X + DR038_Y) == DR038_X + DR038_Y, "fail"); */ _Static_assert(sizeof('a') == sizeof(int), "fail"); +/* WG14 DR040: partial + * 9 unrelated questions about C89 + * + * Question 6 + */ +struct dr040 { /* expected-note {{definition of 'struct dr040' is not complete until the closing '}'}} */ + char c; + short s; + int i[__builtin_offsetof(struct dr040, s)]; /* expected-error {{offsetof of incomplete type 'struct dr040'}} */ +}; + /* WG14 DR043: yes * On the definition of the NULL macro */ @@ -345,3 +377,146 @@ void dr068(void) { _Static_assert('\xFF' == 0xFF, "fail"); #endif } + +#if __STDC_VERSION__ < 202000L +/* WG14: DR070: yes + * Interchangeability of function arguments + * + * Note: we could issue a pedantic warning in this case. We are claiming + * conformance not because we diagnose the UB when we could but because we're + * not obligated to do anything about it and we make it "just work" via the + * usual conversion rules. + * + * This behavior is specific to functions without prototypes. A function with + * a prototype causes implicit conversions rather than relying on default + * argument promotion and warm thoughts. + */ +void dr070_1(c) /* expected-warning {{a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x}} */ + int c; { +} + +void dr070_2(void) { + dr070_1(6); + dr070_1(6U); /* Pedantically UB */ +} +#endif /* __STDC_VERSION__ < 202000L */ + +/* WG14 DR071: yes + * Enumerated types + */ +enum dr071_t { foo_A = 0, foo_B = 1, foo_C = 8 }; +void dr071(void) { + /* Test that in-range values not present in the enumeration still round-trip + * to the original value. + */ + _Static_assert(100 == (int)(enum dr071_t)100, "fail"); +} + +/* WG14 DR081: yes + * Left shift operator + */ +void dr081(void) { + /* Demonstrate that we don't crash when left shifting a signed value; that's + * implementation defined behavior. + */ + _Static_assert(-1 << 1 == -2, "fail"); /* Didn't shift a zero into the "sign bit". */ + _Static_assert(1 << 3 == 1u << 3u, "fail"); /* Shift of a positive signed value does sensible things. */ +} + +/* WG14 DR084: yes + * Incomplete type in function declaration + * + * Note: because the situation is UB, we're free to do what we want. We elect + * to accept and require the incomplete type to be completed before the + * function definition. + */ +struct dr084_t; /* expected-note {{forward declaration of 'struct dr084_t'}} */ +extern void (*dr084_1)(struct dr084_t); +void dr084_2(struct dr084_t); +void dr084_2(struct dr084_t val) {} /* expected-error {{variable has incomplete type 'struct dr084_t'}} */ + +/* WG14 DR088: yes + * Compatibility of incomplete types + */ +struct dr088_t_1; + +void dr088_f(struct dr088_t_1 *); /* expected-note {{passing argument to parameter here}} */ +void dr088_1(void) { + /* Distinct type from the file scope forward declaration. */ + struct dr088_t_1; + /* FIXME: this diagnostic could be improved to not be utterly baffling. */ + dr088_f((struct dr088_t_1 *)0); /* expected-warning {{incompatible pointer types passing 'struct dr088_t_1 *' to parameter of type 'struct dr088_t_1 *'}} */ +} + +void dr088_2(struct dr088_t_1 *p) { /* Pointer to incomplete type. */ } +struct dr088_t_1 { int i; }; /* Type is completed. */ +void dr088_3(struct dr088_t_1 s) { + /* When passing a pointer to the completed type, is it the same type as the + * incomplete type used in the call declaration? + */ + dr088_2(&s); +} + +/* WG14 DR089: yes + * Multiple definitions of macros + */ +#define DR089 object_like /* expected-note {{previous definition is here}} */ +#define DR089(argument) function_like /* expected-warning {{'DR089' macro redefined}} */ + +/* WG14 DR095: yes + * Is initialization as constrained as assignment? + */ +void dr095(void) { + /* Ensure that type compatibility constraints on assignment are also honored + * for initializations. + */ + struct One { + int a; + } one; + struct Two { + float f; + } two = one; /* expected-error {{initializing 'struct Two' with an expression of incompatible type 'struct One'}} */ + + two = one; /* expected-error {{assigning to 'struct Two' from incompatible type 'struct One'}} */ +} + +/* WG14 DR096: yes + * Arrays of incomplete types + */ +void dr096(void) { + typedef void func_type(void); + func_type array_funcs[10]; /* expected-error {{'array_funcs' declared as array of functions of type 'func_type' (aka 'void (void)')}} */ + + void array_void[10]; /* expected-error {{array has incomplete element type 'void'}} */ + + struct S; /* expected-note {{forward declaration of 'struct S'}} */ + struct S s[10]; /* expected-error {{array has incomplete element type 'struct S'}} */ + + union U; /* expected-note {{forward declaration of 'union U'}} */ + union U u[10]; /* expected-error {{array has incomplete element type 'union U'}} */ + union U { int i; }; + + int never_completed_incomplete_array[][]; /* expected-error {{array has incomplete element type 'int[]'}} */ + + extern int completed_later[][]; /* expected-error {{array has incomplete element type 'int[]'}} */ + extern int completed_later[10][10]; +} + +/* WG14 DR098: yes + * Pre/post increment/decrement of function or incomplete types + */ +void dr098(void) { + typedef void func_type(void); + func_type fp; + struct incomplete *incomplete_ptr; + + ++fp; /* expected-error {{cannot increment value of type 'func_type' (aka 'void (void)')}} */ + fp++; /* expected-error {{cannot increment value of type 'func_type' (aka 'void (void)')}} */ + --fp; /* expected-error {{cannot decrement value of type 'func_type' (aka 'void (void)')}} */ + fp--; /* expected-error {{cannot decrement value of type 'func_type' (aka 'void (void)')}} */ + + (*incomplete_ptr)++; /* expected-error {{cannot increment value of type 'struct incomplete'}} */ + ++(*incomplete_ptr); /* expected-error {{cannot increment value of type 'struct incomplete'}} */ + (*incomplete_ptr)--; /* expected-error {{cannot decrement value of type 'struct incomplete'}} */ + --(*incomplete_ptr); /* expected-error {{cannot decrement value of type 'struct incomplete'}} */ +} diff --git a/clang/www/c_dr_status.html b/clang/www/c_dr_status.html index 49783ed..d0ae947 100644 --- a/clang/www/c_dr_status.html +++ b/clang/www/c_dr_status.html @@ -291,7 +291,11 @@ conformance.

40 NAD 9 unrelated questions about C89 - Unknown + +
Partial + Question 6 has full support, the rest of the questions are currently unknown. +
+ 41 @@ -465,19 +469,19 @@ conformance.

69 NAD Questions about the representation of integer types - Unknown + Yes 70 NAD Interchangeability of function arguments - Unknown + Yes 71 C89 Enumerated types - Unknown + Yes 72 @@ -513,7 +517,7 @@ conformance.

77 NAD Stability of addresses - Unknown + Yes 78 @@ -531,13 +535,13 @@ conformance.

80 C89 Merging of string constants - Unknown + Yes 81 NAD Left shift operator - Unknown + Yes 82 @@ -555,7 +559,7 @@ conformance.

84 NAD Incomplete type in function declaration - Unknown + Yes 85 @@ -567,7 +571,7 @@ conformance.

86 NAD Object-like macros in system headers - Unknown + Yes 87 @@ -579,13 +583,13 @@ conformance.

88 NAD Compatibility of incomplete types - Unknown + Yes 89 C89 Multiple definitions of macros - Unknown + Yes 90 @@ -597,49 +601,49 @@ conformance.

91 NAD Multibyte encodings - Unknown + Yes 92 Dup Partial initialization of strings - Duplicate of 60 + Duplicate of 60 93 C89 Reservation of identifiers - Unknown + Yes 94 NAD - ANSI/ISO C Defect report #rfg1 - Unknown + Are constraints on function return the same as assignment? + Yes 95 NAD - ANSI/ISO C Defect report #rfg2 - Unknown + Is initialization as constrained as assignment? + Yes 96 NAD - ANSI/ISO C Defect report #rfg3 - Unknown + Arrays of incomplete types + Yes 97 Dup - ANSI/ISO C Defect report #rfg4 - Duplicate of 40 + Use of offsetof with an incomplete type + Duplicate of 40 98 NAD - ANSI/ISO C Defect report #rfg5 - Unknown + Pre/post increment/decrement of function or incomplete types + Yes 99