This is an archive of the discontinued LLVM Phabricator instance.

[clang][Sema] Add fixit for scoped enum format error
ClosedPublic

Authored by abrachet on Jun 23 2023, 5:13 AM.

Details

Summary

This helps transition code bases to handle the new warning added in 3632e2f5179
Before:

clang/test/FixIt/format.cpp:10:16: warning: format specifies type 'int' but the argument has type 'N::E' [-Wformat]
   10 |   printf("%d", N::E::One); // expected-warning{{format specifies type 'int' but the argument has type 'N::E'}}
      |           ~~   ^~~~~~~~~
      |           %d

After:

clang/test/FixIt/format.cpp:10:16: warning: format specifies type 'int' but the argument has type 'N::E' [-Wformat]
   10 |   printf("%d", N::E::One); // expected-warning{{format specifies type 'int' but the argument has type 'N::E'}}
      |           ~~   ^~~~~~~~~
      |                static_cast<int>( )

Diff Detail

Event Timeline

abrachet created this revision.Jun 23 2023, 5:13 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 23 2023, 5:13 AM
abrachet requested review of this revision.Jun 23 2023, 5:13 AM
tbaeder added inline comments.Jun 27 2023, 7:22 AM
clang/test/FixIt/format.cpp
16

Does this CHECK line and the following one do anything without the : suffix?

abrachet updated this revision to Diff 534978.Jun 27 2023, 7:30 AM
abrachet marked an inline comment as done.
abrachet added inline comments.
clang/test/FixIt/format.cpp
16

Thanks good catch

aaron.ballman added inline comments.Jul 2 2023, 10:04 AM
clang/test/FixIt/format.cpp
2

I'd like to see a C test for this functionality as well.

cjdb added a comment.Jul 5 2023, 10:23 AM

Please add a release note for this.

abrachet updated this revision to Diff 538669.Jul 10 2023, 8:44 AM
abrachet marked an inline comment as done.
abrachet edited the summary of this revision. (Show Details)

Please add a release note for this.

Done

clang/test/FixIt/format.cpp
2

I don't think there is a way to get this warning to trigger for C code. The paper you linked in D153622 discusses mostly giving enum's type specifications (and clang has an extension for this). AFAICT, scoped enumerations through enum class are not possible in C even through extensions

aaron.ballman accepted this revision.Jul 13 2023, 5:38 AM

LGTM!

clang/test/FixIt/format.cpp
2

Whoops, you're of course correct -- my brain was mixing up scoped enumeration and enumeration with a fixed underlying type. Sorry for that!

This revision is now accepted and ready to land.Jul 13 2023, 5:38 AM
This revision was landed with ongoing or failed builds.Jul 14 2023, 9:25 AM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptJul 14 2023, 9:25 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
cjdb added a comment.Jul 14 2023, 3:08 PM

Sorry, forgot to come back and LGTM, but it did indeed LGTM!

smeenai added a subscriber: smeenai.EditedJul 26 2023, 3:31 PM

Sorry for the delayed comment here.

The fix-it is convenient, but is it the best suggestion? It'll end up suggesting truncating the enum value instead of using the proper format specifier in https://godbolt.org/z/xdhrefG95, for example. More insidiously, the static_cast might work fine for all enum uses today but silently cause issues for future enum values.

Using std::to_underyling and matching the format specifier to the underlying type would be the best suggestion IMO, but that only works in C++23 and above :( I guess std::underlying_type_t isn't super ugly either for C++14 and above, but bare std::underlying_type is pretty rough to use in a cast. All of those require the addition of a header though, and I'm not sure if that's acceptable for a fix-it.

Would we at least consider suggesting a format specifier and cast based on the underlying type of the enum, instead of just casting to whatever type the format specifier was using? That won't guard against future changes to the enum, but it's better than the status quo IMO.

To be clear, I realize that applying the current fix-it won't make the code any worse than it was already. It'd be great if we could make it better instead though :)