This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Improve macro handling in modernize-macro-to-enum
ClosedPublic

Authored by LegalizeAdulthood on Apr 15 2022, 7:42 PM.

Details

Summary

When a macro is undef'ed or used in a preprocessor conditional
expression, we need to remember that macro should it later be
defined in the file to an integral value. We need to exclude
such macro names from being turned into an enum.

Maintain a blacklist of identifiers that we've seen in an
undef or conditional preprocessor directive. When the file is
done processing, remove all the blacklisted identifiers from
conversion to an enum.

Fixes #54842

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptApr 15 2022, 7:42 PM
LegalizeAdulthood requested review of this revision.Apr 15 2022, 7:42 PM

This is an initial pass. While I believe the code handles other scenarios, I still need to add some more test cases.

Add more test cases

Make method names symmetric

Internal methods are private

Generally looks correct to me, but I did have some questions about the types used in the fix.

clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp
235

This smells expensive (compared to a SmallVector<StringRef> or somesuch).

303–305

So you're manually keeping the vector sorted instead of using a set?

Any chance that we can store a StringRef rather than paying the expense of all these copies? And would it make sense to switch to using an ordered container rather than an unordered one?

LegalizeAdulthood marked 2 inline comments as done.Apr 19 2022, 9:14 AM
LegalizeAdulthood added inline comments.
clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp
235

Initially I had StringRef, but the problem is that the lifetime of those string references doesn't last long enough. From StringRef docs:

This class does not own the string data, it is expected to be used in situations where the character data resides in some other buffer, whose lifetime extends past that of the StringRef. For this reason, it is not in general safe to store a StringRef.

303–305

Can't store a StringRef because the underlying data doesn't live long enough (I tried it).

Yes, I was keeping a sorted array. I can switch it to a set; I guess memory locality doesn't really matter much in this case because we've already got std::string throwing things on the heap.

Let me know what you think is best, I'm ambivalent about it.

aaron.ballman accepted this revision.Apr 19 2022, 9:30 AM

LGTM! Thank you for the fix!

clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp
235

Ah, I was thinking that the original string data was sufficiently long-lived for this to actually work, but you're right, that's just playing with fire. Sorry for the noise!

303–305

Yeah, I'm ambivalent about it now as well -- I'd say this is fine as-is.

This revision is now accepted and ready to land.Apr 19 2022, 9:30 AM
This revision was automatically updated to reflect the committed changes.
LegalizeAdulthood marked 2 inline comments as done.