Skip to content

Commit 4c92dd6

Browse files
yronglinAnthony Tran
authored andcommitted
[C23][Parser] Accept single variadic parameter function declarator in type name (llvm#145362)
Fixs: llvm#145250. This PR makes clang accept single variadic parameter function declarator in type name. Eg. ```c int va_fn(...); // ok // As typeof() argument typeof(int(...))*fn_ptr = &va_fn; // ok // As _Generic association type int i = _Generic(typeof(va_fn), int(...):1); // ok ``` Signed-off-by: yronglin <[email protected]>
1 parent 10fc24e commit 4c92dd6

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ C23 Feature Support
295295
type. Fixes #GH140887
296296
- Documented `WG14 N3006 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm>`_
297297
which clarified how Clang is handling underspecified object declarations.
298+
- Clang now accepts single variadic parameter in type-name. It's a part of
299+
`WG14 N2975 <https://open-std.org/JTC1/SC22/WG14/www/docs/n2975.pdf>`_
298300

299301
C11 Feature Support
300302
^^^^^^^^^^^^^^^^^^^

clang/lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7048,7 +7048,8 @@ void Parser::ParseParenDeclarator(Declarator &D) {
70487048
// paren, because we haven't seen the identifier yet.
70497049
isGrouping = true;
70507050
} else if (Tok.is(tok::r_paren) || // 'int()' is a function.
7051-
(getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
7051+
((getLangOpts().CPlusPlus || getLangOpts().C23) &&
7052+
Tok.is(tok::ellipsis) &&
70527053
NextToken().is(tok::r_paren)) || // C++ int(...)
70537054
isDeclarationSpecifier(
70547055
ImplicitTypenameContext::No) || // 'int(int)' is a function.

clang/test/C/C23/n2975.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,15 @@ void use(void) {
5151
// ...including conversion errors.
5252
fp other_local = diag; // expected-error {{incompatible function pointer types initializing 'fp' (aka 'void (*)(...)') with an expression of type 'void (int, int, ...)'}}
5353
}
54+
55+
// int(...) not parsed as variadic function type.
56+
// https://github.com/llvm/llvm-project/issues/145250
57+
int va_fn(...); // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}}
58+
59+
// As typeof() argument
60+
typeof(int(...))*fn_ptr = &va_fn; // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}} \
61+
// expected-warning {{'typeof' is incompatible with C standards before C23}}
62+
63+
// As _Generic association type
64+
int i = _Generic(typeof(va_fn), int(...):1); // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}} \
65+
// expected-warning {{'typeof' is incompatible with C standards before C23}}

0 commit comments

Comments
 (0)