This is an archive of the discontinued LLVM Phabricator instance.

[clang-format] [PR46130] When editing a file with unbalance {} the namespace comment fixer can incorrectly comment the wrong closing brace
ClosedPublic

Authored by MyDeveloperDay on May 29 2020, 12:11 PM.

Details

Summary

https://bugs.llvm.org/show_bug.cgi?id=46130 from Twitter https://twitter.com/ikautak/status/1265998988232159232

I have seen this myself many times.. if you have format on save and you work in an editor where you are constantly saving (:w muscle memory)

If you are in the middle of editing and somehow you've missed a { or } in your code, somewhere, often way below where you are at the bottom of your file the namespace comment fixer will have put the namespace on the previous closing brace.

This leads to you having to fix up the bottom of the file.

This revision prevents that happening by performing an initial pass of the tokens and simply counting the number of { and } and ensuring they balance.

If they don't balance we don't do any namespace fixing as it will likely be unstable and incorrect.

Diff Detail

Event Timeline

curdeius accepted this revision.May 29 2020, 1:21 PM

LGTM.
It may be silly, but the fact that this code runs over all the tokens makes me think: do we have any performance-related non-regression tests for clang-format?

clang/unittests/Format/NamespaceEndCommentsFixerTest.cpp
1093

Nit: You may add PR46130 in the test name *if* this is what is done usually (I see it in the test above).

This revision is now accepted and ready to land.May 29 2020, 1:21 PM

We don't really have any performance tests, but the following shows some analysis, all builds are release build:

  • clang-format-ns is built with this change (compiled with VS2017)
  • clang-format is without (compiled with VS2017)
  • c:/Program\ Files/LLVM/bin/clang-format is the last Feb 2020 snapshot build version of clang-format (probably compiled with clang-cl)
  • build_release_cl/clang-format with this change (compiled with clang-cl from Fab2020 snapshot) _ build_2019/clang-format with this change (compiled with VS2019)

The test is to run clang-format over the largest file in LLVM

./libcxxabi/test/test_demangle.pass.cpp is 5.2M in size = 30,000 lines, 29799 opening and closing braces

For a file this size I think I'd expect IO to dominate (I'm running this test on an Intel i7-800 CPU @3,.20GHz with an SSD, Running cygwin in Windows 10)

I've run these tests multiple times and they are often the same or similar timings (I'm running the base clang-format as a benchmark twice because the first run is often slower

time /clang/build_release/bin/clang-format ../libcxxabi/test/test_demangle.pass.cpp > speed1 (Baseline to get test_demangle.pass.cpp into system cache)

real    0m3.957s
user    0m0.000s
sys     0m0.000s

time /clang/build_release/bin/clang-format-ns ../libcxxabi/test/test_demangle.pass.cpp > speed1

real    0m3.994s
user    0m0.000s
sys     0m0.000s
time /clang/build_release/bin/clang-format ../libcxxabi/test/test_demangle.pass.cpp > speed1

real    0m3.990s
user    0m0.000s
sys     0m0.000s

time  c:/Program\ Files/LLVM/bin/clang-format ../libcxxabi/test/test_demangle.pass.cpp > speed1

real    0m3.793s
user    0m0.000s
sys     0m0.000s

time /clang/build_release_cl/bin/clang-format ../libcxxabi/test/test_demangle.pass.cpp > speed1

real    0m3.442s
user    0m0.000s
sys     0m0.000s

time /clang/build_2019/bin/clang-format ../libcxxabi/test/test_demangle.pass.cpp > speed1

real    0m3.820s
user    0m0.000s
sys     0m0.000s

The speed difference of this change of clang-format is fairly negligible, varying by about +/-20ms one way or the other (often swinging the other between runs or depending on which goes first)

I feel this change is relatively low impact, (perhaps the loop could be moved into some earlier equivalent loop but for clarity, I think it's ok here for now.)

I'm not 100% sure how we could reliably test performance generally in clang-format, but I think it would be good to have something.

The key takeaway is likely that clang-cl is quicker! and it obviously more about which compiler you choose.

OK, great. Thanks for all the information.

This revision was automatically updated to reflect the committed changes.

arc adds many unneeded tags from Phabricator. You can drop Reviewers: Subscribers: Tags: and the text Summary: with the following script:

arcfilter () {
  arc amend
  git log -1 --pretty=%B | awk '/Reviewers:|Subscribers:/{p=1} /Reviewed By:|Differential Revision:/{p=0} !p && !/^Summary:$/ {sub(/^Summary: /,"");print}' | git commit --amend --date=now -F -
}

Reviewed By: is considered important by some people (https://lists.llvm.org/pipermail/llvm-dev/2020-January/137889.html). You should keep the tag. (I started to use --date=now because some people find author date != committer date annoying. The committer date is usually what people care.))