This is an archive of the discontinued LLVM Phabricator instance.

Teach -Wtautological-overlap-compare about enums
ClosedPublic

Authored by george.burgess.iv on Sep 24 2015, 10:54 PM.

Details

Summary

Currently, -Wtautological-overlap-compare only emits warnings if the comparisons are between integer literals and variables. This patch adds support for comparison between variables and enums if the user's intent seems moderately obvious.

Richard -- I chose you for review because it looks like you touched the code last. If you're busy, I'm happy to petition others :)

Diff Detail

Event Timeline

george.burgess.iv retitled this revision from to Teach -Wtautological-overlap-compare about enums.
george.burgess.iv updated this object.
george.burgess.iv added a reviewer: rtrieu.
george.burgess.iv added a subscriber: cfe-commits.

Thank you for working on this -- I think it's a good cleanup and feature-add! I have a few minor comments, but generally LGTM. You should wait for an okay from Richard, however.

lib/Analysis/CFG.cpp
54

Please don't compare a pointer against nullptr with an equality operator. This can be simplified into:

if (const auto *DR = dyn_cast<>)
  return isa<> ? "
return nullptr;
97

Are you sure that A and B will only ever be DeclRefExprs? You dyn_cast elsewhere.

george.burgess.iv marked an inline comment as done.

Addressed all feedback

lib/Analysis/CFG.cpp
54

Thanks for catching that!

97

I'm 100% sure if my code matches my intent exactly. ;)

This helper exists solely to make checkIncorrectLogicOperator a bit cleaner -- by the time we call it there, we can assume tryNormalizeBinaryOperator succeeded on both BinOps, and tryNormalizeBinaryOperator only returns DeclRefExprs (that contain EnumConstantDecls) or IntegerLiterals.

I see that this is unclear though, so I added a line to the function comment to make this constraint more explicit. If you think it would be better, I can also just manually inline this code in checkIncorrectLogicOperator.

aaron.ballman accepted this revision.Sep 25 2015, 1:09 PM
aaron.ballman added a reviewer: aaron.ballman.

Thanks, I think this looks good (pending confirmation from Richard).

~Aaron

This revision is now accepted and ready to land.Sep 25 2015, 1:09 PM
rtrieu accepted this revision.Sep 30 2015, 2:41 PM
rtrieu edited edge metadata.

Fix the comments, then it should be ready to commit.

lib/Analysis/CFG.cpp
49

Why is this a lambda instead of a helper function?

88

Use E1 and E2 instead of A and B to match the naming of decls below.

98

Change the comment to note that IntegerLiterals are handled above and only EnumConstantDecls are expected beyond this point.

99–104

There's a few extra casts in here, plus some blind conversions between types. Add your assumptions for the types in asserts. Also, DeclContext should use cast<> to get to Decl types. I recommend the following:

assert(isa<DeclRefExpr>(E1) && isa<DeclRefExpr>(E2));
auto *Decl1 = cast<DeclRefExpr>(E1)->getDecl();
auto *Decl2 = cast<DeclRefExpr>(E2)->getDecl();

assert(isa<EnumConstantDecl>(Decl1) && isa<EnumConstantDecl>(Decl2));
const DeclContext *DC1 = Decl1->getDeclContext();
const DeclContext *DC2 = Decl2->getDeclContext();

assert(isa<EnumDecl>(DC1) && isa<EnumDecl>(DC2));
return DC1 == DC2;
george.burgess.iv marked 4 inline comments as done.

Changed code to address all feedback + committed as r249053. Thanks for the reviews!

lib/Analysis/CFG.cpp
49

Because it's small + super specific to tryNormalizeBinaryOperator, and making it a lambda lets me scope it it only to where it's useful. It's now a helper function. :)

99–104

I was under the impression that the cast<Foo>(Bar) asserts isa<Foo>(Bar) for me, so I thought that asserts like those would just be redundant. Changed to your version anyway :)

Next time, add

Differential Revision: <URL>

to your commit and Phabricator will close the diff automatically.

http://llvm.org/docs/Phabricator.html

lib/Analysis/CFG.cpp
99–104

You are correct, 'cast<Foo>(Bar)' does assert 'isa<Foo>(Bar)'. However, when Bar is not Foo, using the assert here means the crash will produce a backtrace will point straight to this function instead of an assert that points deep into the casting functions.