This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] implement utility-function to add 'const' to variables
ClosedPublic

Authored by JonasToth on Nov 11 2018, 12:15 PM.

Details

Summary

This patch extends the already existing facility to add 'const' to variables
to be more flexible and correct. The previous version did not consider pointers
as value AND pointee. For future automatic introduction for const-correctness
this shortcoming needs to be fixed.
It always allows configuration where the 'const' token is inserted, either on
the left side (if possible) or the right side.
It adds many unit-tests to the utility-function that did not exist before, as
the function was implicitly tested through clang-tidy checks. These
tests were not changed, as the API is still compatible.

Event Timeline

JonasToth created this revision.Nov 11 2018, 12:15 PM
alexfh added inline comments.Nov 12 2018, 2:00 AM
unittests/clang-tidy/AddConstTest.cpp
733 ↗(On Diff #173569)

It would be interesting to see test cases with multiple instantiations of the template the fix applies to.

JonasToth updated this revision to Diff 174828.Nov 20 2018, 1:16 PM

add tests for different template instantiations

JonasToth added inline comments.Nov 20 2018, 1:18 PM
unittests/clang-tidy/AddConstTest.cpp
733 ↗(On Diff #173569)

I added test for a template function with many instantiations, but there should not be a difference between the instantiations, because only the original code would be transformed, and there the 'how it looks' counts, so in this case it will be treated as a value.
Did I misinterpret your question?

JonasToth updated this revision to Diff 175444.Nov 27 2018, 3:43 AM

reabse to master + ping :)

Looks reasonable to me (or at least all these tests make this look good :)), but i'm not sure i can fully review this.

Looks reasonable to me (or at least all these tests make this look good :)), but i'm not sure i can fully review this.

No problem ;)

aaron.ballman added inline comments.Nov 29 2018, 5:56 AM
clang-tidy/utils/FixItHintUtils.cpp
35 ↗(On Diff #175444)

This file is replicating a bunch of functionality that exists on the Type* already. Why do this rather than have the caller do QT->isArrayType() and skip this function entirely? (Same exists elsewhere here.)

109 ↗(On Diff #175444)

always right -> always to the right

clang-tidy/utils/FixItHintUtils.h
47 ↗(On Diff #175444)

I feel like this could be trivially generalized to any type qualifier, not just const. How would you feel about renaming this to: addQualifierToVarDecl() and adding a parameter of type DeclSpec::TQ to specify which qualifier to add?

JonasToth marked 2 inline comments as done.Dec 5 2018, 5:12 AM
JonasToth added inline comments.
clang-tidy/utils/FixItHintUtils.cpp
35 ↗(On Diff #175444)

I had the issue that typedefs are resolved, but shouldn't. If I am not mistaken QT->isArrayType() would go to the canconical type.

using MyPtr = int*;
MyPtr foo = nullptr;

Is treated wrong in that case.

clang-tidy/utils/FixItHintUtils.h
47 ↗(On Diff #175444)

Yes, sounds good.

  • generalize to DeclSpec::TQ
  • add dependent type-tests with typename
JonasToth marked 4 inline comments as done.Jan 17 2019, 10:59 AM
JonasToth marked an inline comment as done.Jan 17 2019, 10:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 7 2019, 7:33 AM

another ping. @alexfh and @aaron.ballman you commented on prior versions. Would be nice if you could take a (final) look at this patch!

A few more comments.

clang-tidy/utils/FixItHintUtils.cpp
83 ↗(On Diff #182345)

The first operand being llvm::Twine is enough for the whole chained concatenation expression to be llvm::Twine.

unittests/clang-tidy/AddConstTest.cpp
15 ↗(On Diff #182345)

What's the point of default values of template arguments here?

53 ↗(On Diff #182345)

Is this still needed? If yes, please use "FIXME" instead and expand on what exactly is missing or needs to be done.

JonasToth updated this revision to Diff 188716.Feb 28 2019, 5:22 AM
JonasToth marked 3 inline comments as done.
  • address review comments
  • rebase to master
JonasToth marked an inline comment as done.Feb 28 2019, 5:22 AM
JonasToth added inline comments.
unittests/clang-tidy/AddConstTest.cpp
15 ↗(On Diff #182345)

Wups, relict of older version.

I think this looks good now, one nit about test coverage.
Did you run this through your buildbot, any issues?

clang-tidy/utils/FixItHintUtils.cpp
35 ↗(On Diff #175444)

There is a test for that, right?

unittests/clang-tidy/AddConstTest.cpp
733 ↗(On Diff #173569)
lebedev.ri added inline comments.Mar 17 2019, 12:28 AM
unittests/clang-tidy/AddConstTest.cpp
733 ↗(On Diff #173569)
JonasToth marked 5 inline comments as done.Nov 16 2019, 3:48 PM
JonasToth added inline comments.
clang-tidy/utils/FixItHintUtils.cpp
35 ↗(On Diff #175444)

Yes, both typedef and using.

unittests/clang-tidy/AddConstTest.cpp
733 ↗(On Diff #173569)

i added tests for specializations.

JonasToth updated this revision to Diff 229705.Nov 16 2019, 3:48 PM
JonasToth marked 2 inline comments as done.
JonasToth removed a subscriber: mgehre.
  • [Misc] port patch to monorepo
  • add more test cases for the transformation

I know it has been a long time, but this patch is ready, i think :)
i would appreciate some reviews ;)

aaron.ballman added inline comments.Nov 24 2019, 7:00 AM
clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp
31–32

ObjC pointer types?

35–42

I don't see how these are improvements over checking QT->isArrayType() and friends within the caller.

83

Do you need both casts for Twine? I would imagine only the first is needed.

151

I think this path is reachable -- it should be an assert() instead and return None.

177

I think Context should be by reference instead of by pointer.

213–214

I think this is reachable as well.

clang-tools-extra/clang-tidy/utils/FixItHintUtils.h
27

const -> qualifier (similar for the comments in the enumerators)

33

Same here.

37

goes for -> attaches to?

45

Comment seems out of date here as well.

JonasToth updated this revision to Diff 235610.Dec 30 2019, 9:00 AM
JonasToth marked 14 inline comments as done.
  • create fresh branch with latest diff of the revision
  • fix review comments
clang-tools-extra/clang-tidy/utils/FixItHintUtils.cpp
35–42

True!

83

In case of ' ' it is necessary, in case of " " its not. I go with " ", should not be more expensive or anything, right?

151

When testing LLVM i saw some path triggering the assertions and unreachables.

I want to go the None-route for now and only emit warnings without fixit. That will help to find false-positives unhandled cases better and is less problematic.

Is it only objc-code that could trigger this?

JonasToth updated this revision to Diff 235611.Dec 30 2019, 9:03 AM
  • fix brace
JonasToth updated this revision to Diff 235703.Dec 31 2019, 3:57 AM
  • improve test situation and fix a crash coming from invalid source locations
JonasToth updated this revision to Diff 235704.Dec 31 2019, 4:03 AM
  • adjust skipLParens code slightly to remove redundant checks
JonasToth updated this revision to Diff 235705.Dec 31 2019, 4:17 AM
  • clarify FIXME problem
aaron.ballman accepted this revision.Jan 1 2020, 7:56 AM

I think this generally looks good, thank you for all the hard work on this! I just found some minor nits and testing requests. Assuming no surprises with the tests, LGTM.

clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
175–176

Unrelated change?

clang-tools-extra/clang-tidy/utils/FixItHintUtils.h
37

attaches for -> attaches to

clang-tools-extra/unittests/clang-tidy/AddConstTest.cpp
66

I don't think this is needed -- just add a newline between the literals and let string concat work its magic? (Same elsewhere)

StringRef S = "typedef int MyInt;"
              "MyInt target = 0;";
83–84

This does what I would expect, but boy does it make me sad to see (because target is not actually a const int * but is instead an int * const).

535

Can you add a test for this scenario:

struct S {
  int i;
} x = { 0 };

where you want to apply the const to the type of x?

1006

Can you also add some ObjC pointer tests?

This revision is now accepted and ready to land.Jan 1 2020, 7:56 AM
JonasToth updated this revision to Diff 235838.Jan 2 2020, 2:21 AM
JonasToth marked 3 inline comments as done.
  • address review comments
JonasToth marked an inline comment as done.Jan 2 2020, 2:22 AM
JonasToth added inline comments.
clang-tools-extra/unittests/clang-tidy/AddConstTest.cpp
66

My Idea was to highlight the expected code-change and create both the before and after-version from the same snippets.
With S being all the code, i would need to test for the full code.

I think with your proposal the test looks like this:

StringRef S = "typedef int MyInt;"
              "MyInt target = 0;";
EXPECT_EQ("typedef int MyInt;"
          "const MyInt target = 0;",
          runCheckOnCode<ValueLTransform>(S));

I prefer the current version, especially with the bigger test later this file.

83–84

You are right, but I am not sure what the proper policy should be. I think the smarts to detect such potential improper const should be in the library code calling the transformation.
The utility should allow both transformations.

1006

i added the most basic test, do you think more is necessary? I don't know a lot about the objc languages.

aaron.ballman added inline comments.Jan 2 2020, 9:51 AM
clang-tools-extra/unittests/clang-tidy/AddConstTest.cpp
66

Okay, that's a good point. Also, this is testing code, so if it's a bit... odd... it's not an issue.

83–84

I think the API behaves how I would expect it to and agree that the caller should be the one deciding what to add the qualifier to. It just hurts me to see the test code verifying it (but the test code is good). ;-)

1006

Ah, those are regular C pointers, not ObjC pointers. I was thinking more along the lines of:

@class Object;
Object *g; // Try adding const to this

@interface Inter
- (void) foo1: (int *)arg1; // Try adding const to this parameter
@end
JonasToth marked 6 inline comments as done.Jan 2 2020, 1:22 PM
JonasToth added inline comments.
clang-tools-extra/unittests/clang-tidy/AddConstTest.cpp
1006

Well, those don't work well.
Can i still commit? :) FIXMEs are there.

JonasToth updated this revision to Diff 235938.Jan 2 2020, 1:22 PM
  • add proper objc test, that fail mostly
JonasToth marked 3 inline comments as done.Jan 2 2020, 1:23 PM

Still LG with a small nit in one of the FIXME tests.

clang-tools-extra/unittests/clang-tidy/AddConstTest.cpp
1006

Can i still commit? :) FIXMEs are there.

Yes, I think you've still made good progress with the patch as-is. We can correct the ObjC stuff in a follow-up.

1056

The whitespace looks incorrect here.

JonasToth marked an inline comment as done.Jan 3 2020, 10:46 AM
JonasToth added inline comments.
clang-tools-extra/unittests/clang-tidy/AddConstTest.cpp
1056

It does, but it is actually how it is expected to look.
All pointer transformations create a double-blank if there was a blank before the star. My thought was, that clang-format should be used anyway, so it should do this cleanup. (especially with the -format option for clang-tidy).
The additional whitespace needs to be inserted to avoid intconst* target; for int* target; variables. Thats why it is always added, if necessary or not.

aaron.ballman added inline comments.Jan 3 2020, 11:11 AM
clang-tools-extra/unittests/clang-tidy/AddConstTest.cpp
1056

It does, but it is actually how it is expected to look.

Okay, that's fair -- we usually let clang-format handle that sort of thing anyway and I cannot think of a case where the transformation would be incorrect.

This revision was automatically updated to reflect the committed changes.

Thank you for all the review over the time this took to land! :)

thakis added a subscriber: thakis.Jan 3 2020, 12:44 PM

This breaks tests on Windows: http://45.33.8.238/win/5061/step_8.txt

Please take a look, and if takes a while to investigate, please revert in the meantime. (Probably needs the fno-delayed-template-instantiation kludge that's in many other tests.)

This breaks tests on Windows: http://45.33.8.238/win/5061/step_8.txt

Please take a look, and if takes a while to investigate, please revert in the meantime. (Probably needs the fno-delayed-template-instantiation kludge that's in many other tests.)

you are right. I belive it is "-fno-delayed-template-parsing" though. I added it to the default arguments runCheckOnCode for quickfix.