aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM!



================
Comment at: 
clang-tools-extra/test/clang-tidy/checkers/bugprone-redundant-branch-condition.cpp:1092
+      // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant condition 'isSet' 
[bugprone-redundant-branch-condition]
+      // CHECK-FIXES: {{isSet}}
+    }
----------------
zinovy.nis wrote:
> aaron.ballman wrote:
> > zinovy.nis wrote:
> > > aaron.ballman wrote:
> > > > zinovy.nis wrote:
> > > > > aaron.ballman wrote:
> > > > > > There's not a whole lot of context for FileCheck to determine if 
> > > > > > it's been correctly applied or not (same below) -- for instance, 
> > > > > > won't this pass even if no changes are applied because FileCheck is 
> > > > > > still going to find `isSet` in the file?
> > > > > Thanks. Fixed.
> > > > Maybe it's just early in the morning for me, but... I was expecting the 
> > > > transformation to be:
> > > > ```
> > > > if (RetT::Test(isSet).Ok() && isSet) {
> > > >   if (RetT::Test(isSet).Ok() && isSet) {
> > > >   }
> > > > }
> > > > ```
> > > > turns into
> > > > ```
> > > > if (RetT::Test(isSet).Ok() && isSet) {
> > > > }
> > > > ```
> > > > Why does it remove the `&& isSet` instead? That seems like it's 
> > > > changing the logic here from `if (true && false)` to `if (true)`.
> > > IMO it's correct.
> > > `isSet` cannot change its value between `if`s while 
> > > `RetT::Test(isSet).Ok()` can.
> > > So we don't need to re-evaluate `isSet` and need to re-evaluate 
> > > `RetT::Test(isSet).Ok()` only.
> > > 
> > > 
> > > 
> > > > That seems like it's changing the logic here from if (true && false) to 
> > > > if (true).
> > > 
> > > 
> > > As I understand only the second `if` is transformed.
> > Does this only trigger as a redundant branch condition if the definition of 
> > `RetT::Test()` is available? Because `Test()` takes a `bool&` so it sure 
> > seems like `isSet` could be modified between the branches if the definition 
> > isn't found because it's being passed as a non-const reference to `Test()`.
> 1) 
> > if the definition of RetT::Test() is available?
> 
> Removing the body from RetT::Test changes nothing.
> 
> 2) Turning `RetT Test(bool &_isSet)` -> `RetT Test(bool _isSet)` also changes 
> nothing.
> 
> 
> 
> 
Given the following four ways of declaring `Test()`:
```
static RetT Test(bool &_isSet); // #1
static RetT Test(bool _isSet); // #2
static RetT Test(const bool &_isSet); // #3
static RetT Test(bool &_isSet) { return 0; } // #4
```
I would expect #2 and #3 to behave the same way -- the `isSet` argument could 
never be modified by calling `Test()` and so the second `Test(isSet) && isSet` 
is partially redundant and the second `if` statement can drop the ` && isSet`. 
(Without dropping the `Test(isSet)` because the call could still modify some 
global somewhere, etc.)

I would expect #1 to not modify the second `if` statement at all because 
there's no way of knowing whether `Test(isSet) && isSet` is the same between 
the first `if` statement and the second one (because the second call to 
`Test(isSet)` may modify `isSet` in a way the caller can observe).

Ideally, #4 would be a case where we could remove the entire second `if` 
statement because we can identify that not only does `isSet` not get modified 
despite being passed by non-const reference, we can see that the `Test()` 
function doesn't modify any state at all. However, this seems like it would 
require data flow analysis and so I think it makes sense to treat #4 the same 
as #1.

That said, I just realized the check isn't being very careful with reference 
parameters in the first place: https://godbolt.org/z/P1aP3W, so your changes 
aren't introducing a new problem, they just happened to highlight an existing 
issue.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91037/new/

https://reviews.llvm.org/D91037

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to