Fail to match equal NULL expression on specific C program

I am trying to add a clang-tidy checker to detect patterns like if (ptr == NULL) or something more complicated, which should be easily achieved by using AST matcher like below:

auto PtrVar = hasType(isAnyPointer());
auto PtrTracer = expr(anyOf(declRefExpr(PtrVar), memberExpr(member(PtrVar))));
auto EqNull = binaryOperator(hasOperatorName("=="), hasOperands(PtrTracer, ignoringImpCasts(nullPointerConstant())));

It works well on my test program:

#include <cstdio>
#include <cstdlib>
#include <cstring>

struct O {
  int x;
  char *s;

struct M {
  int num;
  char *name;
  O *o;

int main() {
  const char *s = "hello world";
  M *m = (M *)malloc(sizeof(M));
  if (m == NULL || m->num == 0 || m->name + 1 == NULL || m->o == NULL) {
    return -1;
  size_t len = strlen(s);
  if (s == NULL) {
    return -1;
  if (strlen(s) > 4) return -1;
  else if (sizeof(s) < puts(s)) return 1;
  for (int i = 0; i < len; i++) {
    if (s[i] == ' ') {
  return 0;

However, when I run the checker on real-world programs, it always misses lots of simple cases. For example, I fail to match any pattern like ptr == NULL in bfd/compress.c of binutils project, though I can definitely match the two operands. Even when I copied my own test code into that file, the checker cannot show any results.

I dumped the AST of target code and tried to ignore imp/paren/cstyle casts, but all my efforts failed.

BinaryOperator 0x55cffa5344e0 <bfd/compress.c:630:7, /home/analyzer/.local/lib/clang/15.0.0/include/stddef.h:89:25> 'int' '=='
|   | | |-ImplicitCastExpr 0x55cffa5344b0 <bfd/compress.c:630:7> 'bfd_byte *' <LValueToRValue>
|   | | | `-DeclRefExpr 0x55cffa534410 <col:7> 'bfd_byte *' lvalue Var 0x55cffa533430 'uncompressed_buffer' 'bfd_byte *'
|   | | `-ImplicitCastExpr 0x55cffa5344c8 </home/analyzer/.local/lib/clang/15.0.0/include/stddef.h:89:16, col:25> 'bfd_byte *' <BitCast>
|   | |   `-ParenExpr 0x55cffa534490 <col:16, col:25> 'void *'
|   | |     `-CStyleCastExpr 0x55cffa534468 <col:17, col:24> 'void *' <NullToPointer>
|   | |       `-IntegerLiteral 0x55cffa534430 <col:24> 'int' 0

It seems to be a problem with .c files but not .cpp files. If I save my test code as C file and generate compile_commands.json, the checker also fails to match the equal null expersion.
I also tried to run clang-query on the source code but it also failed, so it may not be a problem specific to clang-tidy.

Update: this could be fixed by wrapping nullPointerConstant with cStyleCastExpr or applying ignoringCasts to the node.

You probably want to ignore casts on both side of the comparison.