Skip to content

Diagnose the code with trailing comma in the function call. #125232

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 2 commits into from
Feb 14, 2025

Conversation

hokein
Copy link
Collaborator

@hokein hokein commented Jan 31, 2025

This patch fixes a regression caused by #114684 where clang accepts trailing commas for function calls.

Fixes #125225

@hokein hokein requested review from a-tarasyuk and cor3ntin January 31, 2025 14:27
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 31, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 31, 2025

@llvm/pr-subscribers-clang

Author: Haojian Wu (hokein)

Changes

Fixes #125225


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

3 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+2)
  • (modified) clang/lib/Parse/ParseExpr.cpp (+3)
  • (modified) clang/test/Parser/recovery.cpp (+7)
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index c513dab810d1f5..f116ef114bb361 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -703,6 +703,8 @@ def ext_consteval_if : ExtWarn<
 def warn_cxx20_compat_consteval_if : Warning<
   "consteval if is incompatible with C++ standards before C++23">,
   InGroup<CXXPre23Compat>, DefaultIgnore;
+def err_extraneous_trailing_comma : Error<
+  "extraneous trailing comma">;
 
 def ext_init_statement : ExtWarn<
   "'%select{if|switch}0' initialization statements are a C++17 extension">,
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index aa8b3870a188c6..e31ef7d404a222 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2237,6 +2237,9 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
             if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
               RunSignatureHelp();
             LHS = ExprError();
+          } else if (!HasError && HasTrailingComma) {
+            // FIXME: add a FIXIT to remove the trailing comma.
+            Diag(Tok, diag::err_extraneous_trailing_comma);
           } else if (LHS.isInvalid()) {
             for (auto &E : ArgExprs)
               Actions.CorrectDelayedTyposInExpr(E);
diff --git a/clang/test/Parser/recovery.cpp b/clang/test/Parser/recovery.cpp
index 4e2811c4cac926..e318461e1961da 100644
--- a/clang/test/Parser/recovery.cpp
+++ b/clang/test/Parser/recovery.cpp
@@ -215,3 +215,10 @@ struct ::template foo, struct ::template bar; // expected-error 2 {{expected ide
 struct ::foo struct::; // expected-error {{no struct named 'foo' in the global namespace}} expected-error {{expected identifier}}
 class :: : {} a;  // expected-error {{expected identifier}} expected-error {{expected class name}}
 }
+
+namespace GH125225 {
+void func(int);
+void k() {
+  func(1, ); // expected-error {{extraneous trailing comma}}
+}
+}

@@ -2237,6 +2237,9 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
RunSignatureHelp();
LHS = ExprError();
} else if (!HasError && HasTrailingComma) {
// FIXME: add a FIXIT to remove the trailing comma.
Diag(Tok, diag::err_extraneous_trailing_comma);
Copy link
Contributor

@cor3ntin cor3ntin Jan 31, 2025

Choose a reason for hiding this comment

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

I think we should just reuse err_expected_expression. The important point here is that there is a diagnostic.
Not sure this happens often enough to warrant a fixit

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Reused the existing err_expected_expression.

I initially thought that the new err_extraneous_trailing_comma provided a clearer message than err_expected_expression, but it only applies to a specific test case (the one added in this PR).

For other cases, such as function2Arg(1, );, the new diagnostic is incorrect.

@cor3ntin
Copy link
Contributor

Can you add a release note and a more detailed description? Thanks

@hokein
Copy link
Collaborator Author

hokein commented Jan 31, 2025

Can you add a release note and a more detailed description? Thanks

Done. I think we don't need a release note, this is a regression fix, and #114684 is not released yet.

@hokein hokein force-pushed the fix-trailing-comma branch from 7df0f5b to 8f8693a Compare January 31, 2025 15:58
@cor3ntin
Copy link
Contributor

cor3ntin commented Feb 4, 2025

@hokein feel free to merge :)

@hokein
Copy link
Collaborator Author

hokein commented Feb 4, 2025

@hokein feel free to merge :)

Thanks for the ping.

We have several instances of func(1,); in our internal codebase, and the number is not small unfortunately. I'm currently working on a cleanup, which will take some time. I plan to merge this patch as soon as the cleanup is complete (ETA: by the end of this week).

Additionally, we will need to backport this fix to the release20 branch.

@hokein hokein merged commit 922f339 into llvm:main Feb 14, 2025
8 checks passed
@hokein hokein deleted the fix-trailing-comma branch February 14, 2025 15:21
@hokein hokein added this to the LLVM 20.X Release milestone Feb 14, 2025
@hokein
Copy link
Collaborator Author

hokein commented Feb 14, 2025

/cherry-pick 922f339

@llvm-ci
Copy link
Collaborator

llvm-ci commented Feb 14, 2025

LLVM Buildbot has detected a new failure on builder lldb-x86_64-debian running on lldb-x86_64-debian while building clang at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/16226

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: tools/lldb-server/signal-filtering/TestGdbRemote_QPassSignals.py (230 of 2777)
PASS: lldb-api :: lang/c/global_variables/TestGlobalVariables.py (231 of 2777)
PASS: lldb-api :: commands/expression/issue_11588/Test11588.py (232 of 2777)
PASS: lldb-api :: commands/expression/formatters/TestFormatters.py (233 of 2777)
PASS: lldb-api :: functionalities/thread/concurrent_events/TestConcurrentWatchpointWithDelayWatchpointThreads.py (234 of 2777)
PASS: lldb-api :: functionalities/tail_call_frames/unambiguous_sequence/TestUnambiguousTailCalls.py (235 of 2777)
PASS: lldb-api :: tools/lldb-server/TestGdbRemoteCompletion.py (236 of 2777)
UNSUPPORTED: lldb-api :: functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py (237 of 2777)
PASS: lldb-api :: functionalities/thread/concurrent_events/TestConcurrentBreakpointsDelayedBreakpointOneWatchpoint.py (238 of 2777)
PASS: lldb-api :: functionalities/data-formatter/special-chars/TestSummaryStringSpecialChars.py (239 of 2777)
FAIL: lldb-api :: functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py (240 of 2777)
******************** TEST 'lldb-api :: functionalities/thread/thread_specific_break_plus_condition/TestThreadSpecificBpPlusCondition.py' FAILED ********************
Script:
--
/usr/bin/python3 /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./lib --env LLVM_INCLUDE_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/include --env LLVM_TOOLS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./bin --arch x86_64 --build-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex --lldb-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/lldb --compiler /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/clang --dsymutil /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./bin --lldb-obj-root /home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb --lldb-libs-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./lib -t /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/functionalities/thread/thread_specific_break_plus_condition -p TestThreadSpecificBpPlusCondition.py
--
Exit Code: 1

Command Output (stdout):
--
lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 922f339c4ef3631f66dc4b8caa4c356103dbf69d)
  clang revision 922f339c4ef3631f66dc4b8caa4c356103dbf69d
  llvm revision 922f339c4ef3631f66dc4b8caa4c356103dbf69d
Skipping the following test categories: ['libc++', 'dsym', 'gmodules', 'debugserver', 'objc']

--
Command Output (stderr):
--
Change dir to: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/functionalities/thread/thread_specific_break_plus_condition
UNSUPPORTED: LLDB (/home/worker/2.0.1/lldb-x86_64-debian/build/bin/clang-x86_64) :: test_python_dsym (TestThreadSpecificBpPlusCondition.ThreadSpecificBreakPlusConditionTestCase.test_python_dsym) (test case does not fall in any category of interest for this run) 
runCmd: settings clear -all

output: 

runCmd: settings set symbols.enable-external-lookup false

output: 

runCmd: settings set target.inherit-tcc true

output: 

runCmd: settings set target.disable-aslr false

output: 

runCmd: settings set target.detach-on-error false

output: 

@llvmbot
Copy link
Member

llvmbot commented Feb 14, 2025

/pull-request #127215

joaosaffran pushed a commit to joaosaffran/llvm-project that referenced this pull request Feb 14, 2025
)

This patch fixes a regression caused by
llvm#114684 where clang accepts
trailing commas for function calls.

Fixes llvm#125225
swift-ci pushed a commit to swiftlang/llvm-project that referenced this pull request Feb 14, 2025
)

This patch fixes a regression caused by
llvm#114684 where clang accepts
trailing commas for function calls.

Fixes llvm#125225

(cherry picked from commit 922f339)
@bjope
Copy link
Collaborator

bjope commented Feb 17, 2025

This seems to break something with variadic args and the gcc hack with ## to ignore the trailing comma error:

#include <stdio.h>
#define debug_ok(format, ...) fprintf(stderr, format, ## __VA_ARGS__)
void foo() {
    debug_ok("qwerty");
}

#define debug_nok(...) fprintf(stderr, "qwerty", ## __VA_ARGS__)
void bar() {
    debug_nok();
}

At least with -std=c23 we get this:

<source>:9:5: error: expected expression
    9 |     debug_nok();
      |     ^
<source>:7:64: note: expanded from macro 'debug_nok'
    7 | #define debug_nok(...) fprintf(stderr, "qwerty", ## __VA_ARGS__)
      |                                                                ^
1 error generated.
Compiler returned: 1

See godbolt test here: https://godbolt.org/z/fejP1oa1f

But given that there is a difference between the foo and bar tests maybe I've missed some special rule for when this variadic macro solution with ## applies.

@hokein
Copy link
Collaborator Author

hokein commented Feb 17, 2025

clang19 rejects this code as well, https://godbolt.org/z/Yf96W8KWv.

To make this case work, I think we should use the __VA_OPT__.

#define debug_nok(...) fprintf(stderr, "qwerty" __VA_OPT__(,) ## __VA_ARGS__)

@bjope
Copy link
Collaborator

bjope commented Feb 17, 2025

Thanks. I see now that it did not work with older clang (at least not 19.1.0).

It did however work with our downstream fork before this patch. I haven't figured out how we avoided the error in the past. I guess we must have something downstream that avoided the error in the past, but I can't remember that we've done anything actively to suppress such errors. Weird.

I also agree that our downstream users should try to use VA_OPT instead (hopefully there are no other tools that would complain about that).

sivan-shani pushed a commit to sivan-shani/llvm-project that referenced this pull request Feb 24, 2025
)

This patch fixes a regression caused by
llvm#114684 where clang accepts
trailing commas for function calls.

Fixes llvm#125225
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
Development

Successfully merging this pull request may close these issues.

clang accepts invalid code that with trailing comma
6 participants