This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Improve modernize-redundant-void-arg to recognize macro uses
ClosedPublic

Authored by LegalizeAdulthood on Dec 30 2021, 2:34 PM.

Details

Summary

Sometimes a macro invocation will look like an argument list
declaration. Improve the check to detect this situation and not
try to modify the macro invocation.

Thanks to Nathan James for the fix.

  • Ignore implicit typedefs (e.g. compiler builtins)
  • Improve lexing state machine to locate void argument tokens
  • Add additional return_t() macro tests
  • clang-format control in the test case file

Fixes #43791

Diff Detail

Event Timeline

LegalizeAdulthood requested review of this revision.Dec 30 2021, 2:34 PM

Generally LGTM, just a testing request.

clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
562

Can you also add a test for:

void func(return_t(void));
clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
562

:-)

What are you suggesting the result should be? Honestly, looking at that, I'm not sure myself :)

IMO, if I saw this in a code review, I would flag it because you're using a macro called "return type" to specify the type of an argument.

aaron.ballman added inline comments.Jan 5 2022, 12:37 PM
clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
562

LoL, yeah, the name return_t would certainly be novel to use in a parameter list, but what I was hoping to test is whether we try to fix the use of the macro within the parameter list or not. I *think* it probably makes sense to issue the diagnostic, but I don't think it makes sense to try to fix it because the macro could be defined differently for different configurations. But the diagnostic is silenced as well as the fix-it, I wouldn't lose a whole lot of sleep over it.

clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
562

Well it could conceivably be used to declare a function pointer argument like this:

void func(return_t(void) (*fp)(void));

In that case, my expectation is that the check would fix the void arg, but not the arg to the macro.

clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
562

OK, that was a good idea to add the test I described above because it failed :),
so let me improve the check some more.

jrtc27 added a subscriber: jrtc27.Jan 6 2022, 5:43 PM
jrtc27 added inline comments.
clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
562

If you want a less-contrived example that shows up all over the place in crusty old C code that supports (or, perhaps, supported and let bitrot support for) pre-ANSI C compilers:

#define __P(x) x
void foo __P((void));

(the idea being that, for pre-ANSI C compilers, you'd instead define __P(x) as () to get void foo ();)

clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
562

Well, in (modern) C you don't want to remove the void in (void) at all.

This check applies only to C++ code, so we should be safe here.

I'll add a test case just to cover it -- I think the correct result should be
that the check leaves this instance of (void) intact.

LegalizeAdulthood edited the summary of this revision. (Show Details)

Add more test cases and improve the Lexing state machine

LegalizeAdulthood marked 3 inline comments as done.Jan 7 2022, 5:47 PM
LegalizeAdulthood set the repository for this revision to rG LLVM Github Monorepo.Jan 10 2022, 2:42 PM
aaron.ballman added inline comments.Jan 11 2022, 5:25 AM
clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp
51

Might as well fix the clang-format issue.

149

I think a safer interface to this is to use a const IdentifierTable & here and in isMacroIdentifier(). Then, in isMacroIdentifier(), instead of using get() (which has no const overload because it can add an identifier to the table), you can use find(). This removes any possibility of accidentally adding identifiers to the table (even in future refactorings).

157–161
164–168
173–177
180–184
215–219
224–226
clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
202

Unrelated change can be split out an NFC commit if you'd like, but we don't typically attempt to clang-format existing test files, so also not really necessary either.

562

Well, in (modern) C you don't want to remove the void in (void) at all.

In everything but -ansi mode, in fact (C89 supported prototypes). :-D

I'll add a test case just to cover it -- I think the correct result should be that the check leaves this instance of (void) intact.

Thanks for the coverage, and I agree, we shouldn't try mucking with a fix in the presence of a macro.

clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp
157–161
  • clang-format
  • use const IdentifierTable & to avoid accidental modification
  • drop braces from simple block statements as per style guide
LegalizeAdulthood marked 10 inline comments as done.Jan 11 2022, 2:21 PM
aaron.ballman accepted this revision.Jan 12 2022, 12:35 PM

LGTM, thanks!

This revision is now accepted and ready to land.Jan 12 2022, 12:35 PM