Skip to content

[C23][Parser] Accept single variadic parameter function declarator in type name #145362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 24, 2025

Conversation

yronglin
Copy link
Contributor

@yronglin yronglin commented Jun 23, 2025

Fixes: #145250.

This PR makes clang accept single variadic parameter function declarator in type name.
Eg.

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

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jun 23, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 23, 2025

@llvm/pr-subscribers-clang

Author: None (yronglin)

Changes

Fixs: #145250.


Full diff: https://github.com/llvm/llvm-project/pull/145362.diff

3 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+2)
  • (modified) clang/lib/Parse/ParseDecl.cpp (+2-1)
  • (modified) clang/test/C/C23/n2975.c (+12)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 96477ef6ddc9a..89d86c3371247 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -295,6 +295,8 @@ C23 Feature Support
   type. Fixes #GH140887
 - Documented `WG14 N3006 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm>`_
   which clarified how Clang is handling underspecified object declarations.
+- Clang now accepts single variadic parameter in type-name. It's a part of
+  `WG14 N2975 <https://open-std.org/JTC1/SC22/WG14/www/docs/n2975.pdf>`_
 
 C11 Feature Support
 ^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 02f33511dbd61..7e739e09b15e8 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -7048,7 +7048,8 @@ void Parser::ParseParenDeclarator(Declarator &D) {
     // paren, because we haven't seen the identifier yet.
     isGrouping = true;
   } else if (Tok.is(tok::r_paren) || // 'int()' is a function.
-             (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis) &&
+             ((getLangOpts().CPlusPlus || getLangOpts().C23) &&
+              Tok.is(tok::ellipsis) &&
               NextToken().is(tok::r_paren)) || // C++ int(...)
              isDeclarationSpecifier(
                  ImplicitTypenameContext::No) || // 'int(int)' is a function.
diff --git a/clang/test/C/C23/n2975.c b/clang/test/C/C23/n2975.c
index 6e7c936855e51..854afeff7a2b7 100644
--- a/clang/test/C/C23/n2975.c
+++ b/clang/test/C/C23/n2975.c
@@ -51,3 +51,15 @@ void use(void) {
   // ...including conversion errors.
   fp other_local = diag; // expected-error {{incompatible function pointer types initializing 'fp' (aka 'void (*)(...)') with an expression of type 'void (int, int, ...)'}}
 }
+
+// int(...) not parsed as variadic function type.
+// https://github.com/llvm/llvm-project/issues/145250
+int va_fn(...);  // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}}
+
+// As typeof() argument
+typeof(int(...))*fn_ptr = &va_fn;  // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}} \
+                                   // expected-warning {{'typeof' is incompatible with C standards before C23}}
+
+// As _Generic association type
+int i = _Generic(typeof(va_fn), int(...):1);  // expected-warning {{'...' as the only parameter of a function is incompatible with C standards before C23}} \
+                                              // expected-warning {{'typeof' is incompatible with C standards before C23}}

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you for the fix!

@yronglin
Copy link
Contributor Author

Thanks for your review!

@yronglin yronglin merged commit bd6ee6a into llvm:main Jun 24, 2025
11 checks passed
DrSergei pushed a commit to DrSergei/llvm-project that referenced this pull request Jun 24, 2025
… 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]>
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
… 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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Clang] int(...) not parsed as variadic function type
3 participants