================ @@ -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