================
@@ -0,0 +1,330 @@
+// RUN: %check_clang_tidy %s bugprone-null-check-after-dereference %t
+
+struct S {
+  int a;
+};
+
+int warning_deref(int *p) {
+  *p = 42;
+
+  if (p) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point [bugprone-null-check-after-dereference]
+    // CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+  // FIXME: If there's a direct path, make the error message more precise, ie. 
remove `one of the locations`
+    *p += 20;
+    return *p;
+  } else {
+    return 0;
+  }
+}
+
+int warning_member(S *q) {
+  q->a = 42;
+
+  if (q) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+    // CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+    q->a += 20;
+    return q->a;
+  } else {
+    return 0;
+  }
+}
+
+int negative_warning(int *p) {
+  *p = 42;
+
+  if (!p) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: pointer value is checked even 
though it cannot be null at this point
+    // CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+    return 0;
+  } else {
+    *p += 20;
+    return *p;
+  }
+}
+
+int no_warning(int *p, bool b) {
+  if (b) {
+    *p = 42;
+  }
+
+  if (p) {
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: pointer value is checked 
even though it cannot be null at this point 
+    *p += 20;
+    return *p;
+  } else {
+    return 0;
+  }
+}
+
+int else_branch_warning(int *p, bool b) {
+  if (b) {
+    *p = 42;
+  } else {
+    *p = 20;
+  }
+
+  if (p) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+    // CHECK-MESSAGES: :[[@LINE-7]]:5: note: one of the locations where the 
pointer's value cannot be null
+    return 0;
+  } else {
+    *p += 20;
+    return *p;
+  }
+}
+
+int two_branches_warning(int *p, bool b) {
+  if (b) {
+    *p = 42;
+  }
+  
+  if (!b) {
+    *p = 20;
+  }
+
+  if (p) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+    // CHECK-MESSAGES: :[[@LINE-9]]:5: note: one of the locations where the 
pointer's value cannot be null
+    return 0;
+  } else {
+    *p += 20;
+    return *p;
+  }
+}
+
+int two_branches_reversed(int *p, bool b) {
+  if (!b) {
+    *p = 42;
+  }
+  
+  if (b) {
+    *p = 20;
+  }
+
+  if (p) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+    // CHECK-MESSAGES: :[[@LINE-9]]:5: note: one of the locations where the 
pointer's value cannot be null
+    return 0;
+  } else {
+    *p += 20;
+    return *p;
+  }
+}
+
+
+int regular_assignment(int *p, int *q) {
+  *p = 42;
+  q = p;
+
+  if (q) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+    // CHECK-MESSAGES: :[[@LINE-5]]:3: note: one of the locations where the 
pointer's value cannot be null
+    *p += 20; 
+    return *p;
+  } else {
+    return 0;
+  }
+}
+
+int nullptr_assignment(int *nullptr_param, bool b) {
+  *nullptr_param = 42;
+  int *nullptr_assigned;
+
+  if (b) {
+    nullptr_assigned = nullptr;
+  } else {
+    nullptr_assigned = nullptr_param;
+  }
+
+  if (nullptr_assigned) {
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: pointer value is checked 
even though it cannot be null at this point
+    *nullptr_assigned = 20;
+    return *nullptr_assigned;
+  } else {
+    return 0;
+  }
+}
+
+extern int *fncall();
+extern void refresh_ref(int *&ptr);
+extern void refresh_ptr(int **ptr);
+
+int fncall_reassignment(int *fncall_reassigned) {
+  *fncall_reassigned = 42;
+
+  fncall_reassigned = fncall();
+
+  if (fncall_reassigned) {
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: pointer value is checked 
even though it cannot be null at this point
+    *fncall_reassigned = 42;
+  }
+  
+  fncall_reassigned = fncall();
+
+  *fncall_reassigned = 42;
+
+  if (fncall_reassigned) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+    // CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+    *fncall_reassigned = 42;
+  }
+  
+  refresh_ptr(&fncall_reassigned);
+
+  if (fncall_reassigned) {
+    // CHECK-MESSAGES-NOT: :[[@LINE-1]]:7: warning: pointer value is checked 
even though it cannot be null at this point
+    *fncall_reassigned = 42;
+  }
+  
+  refresh_ptr(&fncall_reassigned);
+  *fncall_reassigned = 42;
+
+  if (fncall_reassigned) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: pointer value is checked even 
though it cannot be null at this point
+    // CHECK-MESSAGES: :[[@LINE-4]]:3: note: one of the locations where the 
pointer's value cannot be null
+    *fncall_reassigned = 42;
+    return *fncall_reassigned;
+  } else {
+    return 0;
+  }
+}
+
+int chained_references(int *a, int *b, int *c, int *d, int *e) {
----------------
Discookie wrote:

Only 3 should be enough, but got carried away...

https://github.com/llvm/llvm-project/pull/84166
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to