[PATCH] D114622: [clang-tidy][analyzer] Fix false-positive in IdenticalExprChecker and misc-redundant-expression

Balázs Benics via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 26 05:31:57 PST 2021


steakhal added inline comments.


================
Comment at: clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp:54-55
                                        const NestedNameSpecifier *Right) {
-  llvm::FoldingSetNodeID LeftID, RightID;
-  Left->Profile(LeftID);
-  Right->Profile(RightID);
-  return LeftID == RightID;
+  if (const auto *L = Left->getAsType())
+    if (const auto *R = Right->getAsType())
+      return L->getCanonicalTypeUnqualified() ==
----------------
whisperity wrote:
> whisperity wrote:
> > (Wrt. to the comment about not typing stuff out directly, I guess `L` and `R` here will be `X<char>` and `X<long>` and thus not the same.)
> (Style nit to lessen the indent depth, until C++17...)
> (Wrt. to the comment about not typing stuff out directly, I guess L and R here will be X<char> and X<long> and thus not the same.)
I don't quite get what do you mean by this.


================
Comment at: clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp:132-134
+    const DeclRefExpr *DeclRef1 = cast<DeclRefExpr>(Left);
+    const DeclRefExpr *DeclRef2 = cast<DeclRefExpr>(Right);
+    return areEquivalentDeclRefs(DeclRef1, DeclRef2);
----------------
whisperity wrote:
> (Style nit. Or `LeftDR`, `RightDR`.)
`DeclRef1` -> `LeftDR`


================
Comment at: clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp:822
+
+  using my_char = char;
+  sink |= my_trait<char>::value || my_trait<my_char>::value;
----------------
whisperity wrote:
> Are there any more ways we could trick this check to cause false positives? Something through which it doesn't look the same but still refers to the same thing?
> 
> At the top of my head I'm thinking about something along the lines of this:
> 
> ```lang=cpp
> template <typename T>
> struct X {
>   template <typename U>
>   static constexpr bool same = std::is_same_v<T, U>;
> };
> 
> X<char> ch() { return X<char>{}; }
> X<int> i() { return X<int>{}; }
> 
> void test() {
>   coin ? ch().same<long> : i().same<long>;
> }
> ```
> 
> So the "type name" where we want to look up isn't typed out directly.
> Or would these still be caught (and thus fixed) by looking at a `NestedNameSpecifier`?
For the example:
```lang=C++
template <typename T, T V> struct integral_constant {
    static constexpr T value = V;
    typedef T value_type;
    typedef integral_constant<T, V> type;
};
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
template <typename T, typename U> struct is_same : false_type {};
template <typename T> struct is_same<T, T> : true_type {};

template <typename T>
struct X {
  template <typename U>
  static constexpr bool same = is_same<T, U>::value;
};

X<char> ch();
X<int> i();

void test(bool coin) {
  coin ? ch().same<long> : i().same<long>;
}
```
We would have no warnings for this code, nor we had previously:
https://godbolt.org/z/9xo4adfbP

Should I demonstrate this in the test file?
I wouldn't pollute it TBH, since it requires some template machinery which is quite verbose.
However, if you insist I will add it.


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

https://reviews.llvm.org/D114622



More information about the cfe-commits mailing list