-
Notifications
You must be signed in to change notification settings - Fork 21
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
clang-format-18 false negative when using function-try block #250
Comments
What does the review summary comment say? The I have to ask, what triggers are used by your CI workflow? I think I asked you this before but got no answer. For example the triggers are under the yaml field on:
pull_request:
branches: [main, master, develop]
paths: ['**.c', '**.cpp', '**.h', '**.hpp', '**.cxx', '**.hxx', '**.cc', '**.hh', '**CMakeLists.txt', 'meson.build', '**.cmake']
push:
branches: [main, master, develop]
paths: ['**.c', '**.cpp', '**.h', '**.hpp', '**.cxx', '**.hxx', '**.cc', '**.hh', '**CMakeLists.txt', 'meson.build', '**.cmake'] Also, which lines are changed in the following code? void TestFunc(const std::string& data) try {
do_something();
do_something_more();
} catch (const std::exception& ex) {
log_error(ex);
} |
In general I don't have problems with other code. That's why I think the triggers not relevant here. Only the line with |
If you don't answer all my questions, then I'm unable to help/diagnose the problem. I'm guessing this has occurred on a private repo. |
Are you also using clang-format v18 locally?
This is important because the review may not be updated based on what event triggers the workflow.
I'm curious if the "full clang-format patch" includes the line about |
The repo is private. Excerpt from related yaml file:
I formatted entire file locally with clang-format 18.1.7 (on CI I see 18.1.8 but I had faced similar problem before while CI had 18.1.7 as well) before push to PR. When I changed code into this (added extra spaces inside of parentheses):
I got a message with diff in PR review: I.e. no problems on line with When I apply the diff (i.e. format file again locally) I will see:
The only way I found to work around the problem (get no complains from linter side) - don't use function-try-block and use regular try-block like this:
|
So it is a reusable workflow. What are the triggers for the actual workflow that invokes the reusable workflow? I ask because reusable workflows inherit the event type from the calling workflow.
I was more concerned about a difference between major versions. I doubt this problem is occurring from a difference between patch versions
It sounds like file-annotations: false Note We have no way of deleting an outdated file annotation because they are only relevant to the commit that created the annotation. This usually isn't a problem because refreshing the list of file changes in a PR will only show annotations created by the latest commit to the head branch. It could be that the line number in the annotation is incorrect, but this is highly unlikely. |
I disabled annotation as you suggested
As far as I understand the line |
No. We would need more than just the snippet:
You can enable cpp-linter's debug output: verbosity: debug # default is 'info' If I recall correctly, this should show the output from
|
I forgot, clang-format output is basically the modified source. With Could this just be a difference in LF vs CRLF? |
I don't think so. All lines have the same ending. But complaining only for the one with I would like to repeat that the problem not raising with regular try/catch block, only with function-try-block. Looks like clang-format (or other wrapper) returns non-zero exit code to cpp-linter, but doesn't suggest any changes. |
If clang-format was returning a non-zero exit code, then it would have been reported with debug output enabled. logger.info('Running "%s"', " ".join(cmds))
results = subprocess.run(cmds, capture_output=True)
if results.returncode:
logger.debug(
"%s raised the following error(s):\n%s", cmds[0], results.stderr.decode()
) (from src here) |
What is the output when you run the following command locally?
(assuming I'm curious to see what the XML output is. It might be that v18 uses a format that is different from previous versions' XML output (we've seen that problem before). |
Its not. You clearly use 4-space indents, Google guidelines mandate 2-space indents. I wouldn't be surprised if you deviate from their guidelines further. |
output-replacement-xml returns me the following:
Offset 2789 points right after the curly brace:
I'm not sure what does it mean. How to read this xml-output.
I mean that for the sake of reproducibility it (I hope) should not depend on .clang-format style. Just try to format my code snippet with your settings and look into response from cpp-linter, if it's not so hard for you. |
Using the xml feedback that you provided, I saved this locally to a file named "fmt.xml". Then I opened a python interpretter to parse the xml similarly to how cpp-linter does: >>> from pathlib import Path
>>> f = Path("fmt.xml").read_text(encoding="utf-8")
>>> f
"<?xml version='1.0'?>\n<replacements xml:space='preserve' incomplete_format='false'>\n<replacement offset='2789' length='0'> </replacement>\n</replacements>\n"
>>> import xml.etree.ElementTree as ET
>>> tree = ET.fromstring(f)
>>> len(tree)
1
>>> tree[0]
<Element 'replacement' at 0x7f0ce8f45170>
>>> tree[0].text
'\r\n '
>>> int(tree[0].attrib["offset"]) # the position where replacement begins
2789
>>> int(tree[0].attrib["length"]) # the number of characters to remove
0 Given that you said offset 2789 corresponds to the end of the How to fix this?I'm not sure what is happening in cpp-linter. I have to investigate the code to make sure that this case is covered. It certainly should be. |
This comment was marked as outdated.
This comment was marked as outdated.
Does you project use mixed line endings? Or only LF? Or only CRLF? |
It looks like you did understand my analysis. This feels like it might be a bug in clang-format v18. I'm going to research how pygit2 (python binding we use for libgit2) deals with creating a patch from 2 buffers. The resulting patch is what cpp-linter uses to create code suggestions. |
Can you double check the offset is translated correctly into line & column? It is a 1-based count. You can do this with a python prompt: from pathlib import Path
offset = 2789
filename = "filename.cpp" # replace this with the actual filename
ba = Path(filename).read_bytes()[:offset]
lines = ba.count(b"\n") + 1 # lines are a 1-based count
cols = offset - ba.rfind(b"\n")
print("line:", lines, "col:", cols) This is an expanded version of the code that cpp-linter uses |
Exactly the same position that I mentioned before
|
It seems that we can post an issue (bug) on LLVM GH only based on the assumption that we must get "empty" output-replacements-xml, e.g.:
if we did clang-format with fix before on the same .clang-format settings. Am I right? |
I would focus on this fact. The function-try-block is basically syntactic sugar for encapsulating the entire function body in a try-catch block. However, it is ideally used for a class' constructor that derives from a base class. Other use cases (like what you're doing) are really just a clever workaround for projects with restrictions on line length.
That is what an empty XML should look like, yes. If you do raise this upstream, then please leave a reference to this thread. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Hmm, I'm looking at the diff flags that cpp-linter can use when creating a patch that gets translated into code suggestions in a PR review. Most diff flags don't really apply to our use case, which creates a patch from 2 arbitrary buffers, not anything in the index or working tree. However, I did find a flag that might be applicable to our specific usage:
Although, I'm not sure if this flag would help avoid this problem (as reported in OP). I doubt it would hurt anything if I added it to cpp-linter. |
I discovered this trick when researching a solution to the problem reported in cpp-linter/cpp-linter-action#250
ConclusionThis is definitely a bug in clang-format. In cpp-linter, we use the XML output to count the suggested format fixes and represent it to the user as the To work around this problem, I would suggest you either
|
I have code like this, formatted locally with clang-format. I use function-try-block here:
cpp-linter has complaints on this code, pointing to the line with
catch
(99):At the same time I don't see any diff suggestions in PR despite I have
format-review: true
and if I intentionally add wrongly-formatted changes on other lines - I will see only diff for those lines (but line withcatch
still won't be in diff for some reason).Full list of options that I use:
Looks like everything is OK with formatting, but cpp-linter mark that code as not-formatted.
The text was updated successfully, but these errors were encountered: