From 7fc57d7c97c64b64ef865d71343867ab30cfcf15 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Fri, 18 Nov 2022 14:15:02 -0500 Subject: [PATCH] Add more tests for C DRs and update the status page --- clang/test/C/drs/dr464.c | 19 +++++++ clang/test/C/drs/dr466.c | 30 +++++++++++ clang/test/C/drs/dr483.c | 22 ++++++++ clang/test/C/drs/dr491.c | 30 +++++++++++ clang/test/C/drs/dr494.c | 30 +++++++++++ clang/test/C/drs/dr4xx.c | 127 ++++++++++++++++++++++++++++++++++++++++++--- clang/www/c_dr_status.html | 27 +++++++--- 7 files changed, 269 insertions(+), 16 deletions(-) create mode 100644 clang/test/C/drs/dr464.c create mode 100644 clang/test/C/drs/dr466.c create mode 100644 clang/test/C/drs/dr483.c create mode 100644 clang/test/C/drs/dr491.c create mode 100644 clang/test/C/drs/dr494.c diff --git a/clang/test/C/drs/dr464.c b/clang/test/C/drs/dr464.c new file mode 100644 index 0000000..a9c00b2 --- /dev/null +++ b/clang/test/C/drs/dr464.c @@ -0,0 +1,19 @@ +/* RUN: %clang_cc1 -std=c89 -verify -pedantic -Wno-c11-extensions %s + RUN: %clang_cc1 -std=c99 -verify -pedantic -Wno-c11-extensions %s + RUN: %clang_cc1 -std=c11 -verify -pedantic %s + RUN: %clang_cc1 -std=c17 -verify -pedantic %s + RUN: %clang_cc1 -std=c2x -verify -pedantic %s + */ + +/* expected-no-diagnostics */ + +/* WG14 DR464: yes + * Clarifying the Behavior of the #line Directive + * + * Note: the behavior described by this DR allows for two different + * interpretations, but WG14 N2322 (adopted for C2x) adds a recommended + * practice which is what we're testing our interpretation against. + */ +#line 10000 +_Static_assert(__LI\ +NE__ == 10000, ""); diff --git a/clang/test/C/drs/dr466.c b/clang/test/C/drs/dr466.c new file mode 100644 index 0000000..6b5811d --- /dev/null +++ b/clang/test/C/drs/dr466.c @@ -0,0 +1,30 @@ +/* RUN: %clang_cc1 -std=c89 -Wno-gcc-compat -ast-dump -o - %s | FileCheck %s + RUN: %clang_cc1 -std=c99 -ast-dump -o - %s | FileCheck %s + RUN: %clang_cc1 -std=c11 -ast-dump -o - %s | FileCheck %s + RUN: %clang_cc1 -std=c17 -ast-dump -o - %s | FileCheck %s + RUN: %clang_cc1 -std=c2x -ast-dump -o - %s | FileCheck %s + */ + +/* WG14 DR466: yes + * Scope of a for loop control declaration + */ +int dr466(void) { + for (int i = 0; ; ) { + long i = 1; /* valid C, invalid C++ */ + // ... + return i; /* (perhaps unexpectedly) returns 1 in C */ + } +} + +/* +CHECK: FunctionDecl 0x{{.+}} dr466 'int (void)' +CHECK-NEXT: CompoundStmt +CHECK-NEXT: ForStmt +CHECK-NEXT: DeclStmt +CHECK-NEXT: VarDecl 0x{{.+}} {{.+}} i 'int' +CHECK: CompoundStmt +CHECK-NEXT: DeclStmt +CHECK-NEXT: VarDecl [[ACTUAL:0x.+]] col:{{.+}} used i 'long' +CHECK: ReturnStmt +CHECK: DeclRefExpr 0x{{.+}} 'long' lvalue Var [[ACTUAL]] 'i' 'long' +*/ diff --git a/clang/test/C/drs/dr483.c b/clang/test/C/drs/dr483.c new file mode 100644 index 0000000..2d4b7bc --- /dev/null +++ b/clang/test/C/drs/dr483.c @@ -0,0 +1,22 @@ +/* RUN: %clang_cc1 -std=c89 -verify -pedantic -Wno-c11-extensions %s + RUN: %clang_cc1 -std=c99 -verify -pedantic -Wno-c11-extensions %s + RUN: %clang_cc1 -std=c11 -verify -pedantic %s + RUN: %clang_cc1 -std=c17 -verify -pedantic %s + RUN: %clang_cc1 -std=c2x -verify -pedantic %s + */ + +/* expected-no-diagnostics */ + +/* WG14 DR483: yes + * __LINE__ and __FILE__ in macro replacement list + * + * The crux of this DR is to ensure that __LINE__ (and __FILE__) use in a macro + * replacement list report the line and file of the expansion of that macro, + * not the line and file of the macro definition itself. + */ +#line 500 +#define MAC() __LINE__ + +#line 1000 +_Static_assert(MAC() == 1000, ""); + diff --git a/clang/test/C/drs/dr491.c b/clang/test/C/drs/dr491.c new file mode 100644 index 0000000..d59c27b --- /dev/null +++ b/clang/test/C/drs/dr491.c @@ -0,0 +1,30 @@ +/* RUN: %clang_cc1 -std=c89 -verify -Wreserved-macro-identifier %s + RUN: %clang_cc1 -std=c99 -verify -Wreserved-macro-identifier %s + RUN: %clang_cc1 -std=c11 -verify -Wreserved-macro-identifier %s + RUN: %clang_cc1 -std=c17 -verify -Wreserved-macro-identifier %s + RUN: %clang_cc1 -std=c2x -verify -Wreserved-macro-identifier %s + */ + +/* WG14 DR491: partial + * Concern with Keywords that Match Reserved Identifiers + * + * Claiming this as partial because we do not reject code using a reserved + * identifier, but our reserved identifier code incorrectly identifies some + * keywords as reserved identifiers for macro names, but not others. + */ + +#define const const +#define int int +#define restrict restrict + +/* FIXME: none of these should diagnose the macro name as a reserved + * identifier per C2x 6.4.2p7 (similar wording existed in earlier standard + * versions). + */ +#define _Static_assert _Static_assert /* expected-warning {{macro name is a reserved identifier}} */ +#define _Alignof(x) _Alignof(x) /* expected-warning {{macro name is a reserved identifier}} */ +#define _Bool _Bool /* expected-warning {{macro name is a reserved identifier}} */ +#define __has_c_attribute __has_c_attribute /* expected-warning {{macro name is a reserved identifier}} + expected-warning {{redefining builtin macro}} + */ +#define __restrict__ __restrict__ /* expected-warning {{macro name is a reserved identifier}} */ diff --git a/clang/test/C/drs/dr494.c b/clang/test/C/drs/dr494.c new file mode 100644 index 0000000..cdcfc41 --- /dev/null +++ b/clang/test/C/drs/dr494.c @@ -0,0 +1,30 @@ +/* RUN: %clang_cc1 -std=c89 %s -emit-llvm -o - | FileCheck %s + RUN: %clang_cc1 -std=c99 %s -emit-llvm -o - | FileCheck %s + RUN: %clang_cc1 -std=c11 %s -emit-llvm -o - | FileCheck %s + RUN: %clang_cc1 -std=c17 %s -emit-llvm -o - | FileCheck %s + RUN: %clang_cc1 -std=c2x %s -emit-llvm -o - | FileCheck %s + */ + +/* WG14 DR494: yes + * Part 1: Alignment specifier expression evaluation + */ +void dr494(void) { + int i = 12; + int j = _Alignof(int [++i]); + int k = sizeof(int [++i]); + /* Check that we store a straight value for i and j, but have to calculate a + * value for storing into k. That's because sizeof() needs to execute code to + * get the correct value from a VLA, but _Alignof is not allowed to execute + * the VLA extent at runtime. + */ +/* CHECK: %[[I:.+]] = alloca i32 + CHECK: %[[J:.+]] = alloca i32 + CHECK: %[[K:.+]] = alloca i32 + CHECK: store i32 12, ptr %[[I]] + CHECK: store i32 4, ptr %[[J]] + CHECK: %[[ZERO:.+]] = load i32, ptr %[[I]] + CHECK: %[[INC:.+]] = add nsw i32 %[[ZERO]], 1 + CHECK: store i32 %[[INC]], ptr %[[I]] + */ +} + diff --git a/clang/test/C/drs/dr4xx.c b/clang/test/C/drs/dr4xx.c index e2cf249..6acb479 100644 --- a/clang/test/C/drs/dr4xx.c +++ b/clang/test/C/drs/dr4xx.c @@ -60,6 +60,18 @@ * * WG14 DR459: yes * atomic_load missing const qualifier + * + * WG14 DR475: yes + * Misleading Atomic library references to atomic types + * + * WG14 DR485: yes + * Problem with the specification of ATOMIC_VAR_INIT + * + * WG14 DR486: yes + * Inconsistent specification for arithmetic on atomic objects + * + * WG14 DR490: yes + * Unwritten Assumptions About if-then */ /* WG14 DR412: yes @@ -201,13 +213,112 @@ void dr463(void) { (void)(1 << ((__CHAR_BIT__ * sizeof(int)) - 1)); } -/* WG14 DR464: yes - * Clarifying the Behavior of the #line Directive +/* WG14 DR478: yes + * Valid uses of the main function + */ +int main(void) { + /* This DR clarifies that C explicitly allows you to call main() in a hosted + * environment; it is not special as it is in C++, so recursive calls are + * fine as well as nonrecursive direct calls. + */ + main(); /* ok */ +} + +void dr478(void) { + int (*fp)(void) = main; /* ok */ + main(); /* ok */ +} + +/* WG14 DR481: yes + * Controlling expression of _Generic primary expression + */ +void dr481(void) { + /* The controlling expression undergoes lvalue to rvalue conversion, and that + * performs array decay and strips qualifiers. + */ + (void)_Generic("bla", char *: "blu"); + (void)_Generic((int const){ 0 }, int: "blu"); /* c89only-warning {{compound literals are a C99-specific feature}} */ + (void)_Generic(+(int const){ 0 }, int: "blu"); /* c89only-warning {{compound literals are a C99-specific feature}} */ + + (void)_Generic("bla", /* expected-error {{controlling expression type 'char *' not compatible with any generic association type}} */ + char[4]: "blu"); /* expected-warning {{due to lvalue conversion of the controlling expression, association of type 'char[4]' will never be selected because it is of array type}} */ + + (void)_Generic((int const){ 0 }, /* expected-error {{controlling expression type 'int' not compatible with any generic association type}} + c89only-warning {{compound literals are a C99-specific feature}} + */ + int const: "blu"); /* expected-warning {{due to lvalue conversion of the controlling expression, association of type 'const int' will never be selected because it is qualified}} */ + + (void)_Generic(+(int const){ 0 }, /* expected-error {{controlling expression type 'int' not compatible with any generic association type}} + c89only-warning {{compound literals are a C99-specific feature}} + */ + int const: "blu"); /* expected-warning {{due to lvalue conversion of the controlling expression, association of type 'const int' will never be selected because it is qualified}} */ +} + +/* WG14 DR489: partial + * Integer Constant Expression * - * Note: the behavior described by this DR allows for two different - * interpretations, but WG14 N2322 (adopted for C2x) adds a recommended - * practice which is what we're testing our interpretation against. + * The DR is about whether unevaluated operands have to follow the same + * restrictions as the rest of the expression in an ICE, and according to the + * committee, they do. + */ +void dr489(void) { + struct S { + int bit : 12 || 1.0f; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}} */ + }; + enum E { + Val = 0 && 1.0f /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}} */ + }; + + int i; + + /* FIXME: mentioning the 'aligned' attribute is confusing, but also, should + * this be folded as an ICE as a GNU extension? GCC does not fold it. + */ + _Alignas(0 ? i++ : 8) char c; /* expected-error {{'aligned' attribute requires integer constant}} */ + + /* FIXME: this should get the constant folding diagnostic as this is not a + * valid ICE because the floating-point constants are not the immediate + * operand of a cast. It should then also get a diagnostic about trying to + * declare a VLA with static storage duration and the C99 extension warning + * for VLAs in C89. + */ + static int vla[sizeof(1.0f + 1.0f)]; + + int val[5] = { [1 ? 0 : i--] = 12 }; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}} + c89only-warning {{designated initializers are a C99 feature}} + */ + + /* FIXME: this should be the constant folding diagnostic as this is not a + * valid ICE because of the / operator. + */ + _Static_assert(sizeof(0 / 0), ""); + + /* FIXME: this should also get the constant folding diagnostic as this is not + * a valid ICE because of the = operator. + */ + (void)_Generic(i = 12, int : 0); /* expected-warning {{expression with side effects has no effect in an unevaluated context}} */ + + switch (i) { + case (int)0.0f: break; /* okay, a valid ICE */ + + /* FIXME: this should be accepted in C2x and up without a diagnostic, as C23 + * added compound literals to the allowed list of things in an ICE. The + * diagnostic is correct for C17 and earlier though. + */ + case (int){ 2 }: break; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}} + c89only-warning {{compound literals are a C99-specific feature}} + */ + case 12 || main(): break; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}} */ + } +} + +/* WG14 DR492: yes + * Named Child struct-union with no Member */ -#line 10000 -_Static_assert(__LI\ -NE__ == 10000, ""); +struct dr492_t { + union U11 { /* expected-warning {{declaration does not declare anything}} */ + int m11; + float m12; + }; + int m13; +} dr492; diff --git a/clang/www/c_dr_status.html b/clang/www/c_dr_status.html index ff5646d..47a7a03 100644 --- a/clang/www/c_dr_status.html +++ b/clang/www/c_dr_status.html @@ -2441,7 +2441,7 @@ conformance.

466 NAD Scope of a for loop control declaration - Unknown + Yes 467 @@ -2513,7 +2513,7 @@ conformance.

478 NAD Valid uses of the main function - Unknown + Yes 479 @@ -2531,7 +2531,7 @@ conformance.

481 C11 Controlling expression of _Generic primary expression - Unknown + Clang 3.8 482 @@ -2543,7 +2543,7 @@ conformance.

483 NAD __LINE__ and __FILE__ in macro replacement list - Unknown + Yes 484 @@ -2579,7 +2579,12 @@ conformance.

489 NAD Integer Constant Expression - Unknown + +
Partial + Clang inconsistently diagnoses folding a constan expression into an ICE + as an extension. +
+ 490 @@ -2591,13 +2596,19 @@ conformance.

491 C11 Concern with Keywords that Match Reserved Identifiers - Unknown + +
Partial + Clang issues a reserved identifier diagnostic when the identifier leads + with an underscore followed by a capital letter or double underscores, + even if the identifier is used for a macro definition. +
+ 492 NAD Named Child struct-union with no Member - Unknown + Clang 3.6 493 @@ -2609,7 +2620,7 @@ conformance.

494 C11 Part 1: Alignment specifier expression evaluation - Unknown + Yes 495 -- 2.7.4