Skip to content

[clang-tidy] modernize-use-nullptr matches "NULL" in templates #109169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,20 @@ AST_MATCHER(Type, sugaredNullptrType) {
/// to null within.
/// Finding sequences of explicit casts is necessary so that an entire sequence
/// can be replaced instead of just the inner-most implicit cast.
///
/// TODO/NOTE: The second "anyOf" below discards matches on a substituted type,
/// since we don't know if that would _always_ be a pointer type for all other
/// specializations, unless the expression was "__null", in which case we assume
/// that all specializations are expected to be for pointer types. Ideally this
/// would check for the "NULL" macro instead, but that'd be harder to express.
/// In practice, "NULL" is often defined as "__null", and this is a useful
/// condition.
StatementMatcher makeCastSequenceMatcher(llvm::ArrayRef<StringRef> NameList) {
auto ImplicitCastToNull = implicitCastExpr(
anyOf(hasCastKind(CK_NullToPointer), hasCastKind(CK_NullToMemberPointer)),
unless(hasImplicitDestinationType(qualType(substTemplateTypeParmType()))),
anyOf(hasSourceExpression(gnuNullExpr()),
unless(hasImplicitDestinationType(
qualType(substTemplateTypeParmType())))),
unless(hasSourceExpression(hasType(sugaredNullptrType()))),
unless(hasImplicitDestinationType(
qualType(matchers::matchesAnyListedTypeName(NameList)))));
Expand Down
4 changes: 4 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ Changes in existing checks
a false positive when only an implicit conversion happened inside an
initializer list.

- Improved :doc:`modernize-use-nullptr
<clang-tidy/checks/modernize/use-nullptr>` check to also recognize
``NULL``/``__null`` (but not ``0``) when used with a templated type.

- Improved :doc:`modernize-use-std-print
<clang-tidy/checks/modernize/use-std-print>` check to support replacing
member function calls too.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,31 @@ void test_macro_expansion4() {
#undef MY_NULL
}

template <typename T> struct pear {
// If you say __null (or NULL), we assume that T will always be a pointer
// type, so we suggest replacing it with nullptr. (We only check __null here,
// because in this test NULL is defined as 0, but real library implementations
// it is often defined as __null and the check will catch it.)
void f() { x = __null; }
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr [modernize-use-nullptr]
// CHECK-FIXES: x = nullptr;

// But if you say 0, we allow the possibility that T can be used with integral
// and pointer types, and "0" is an acceptable initializer (even if "{}" might
// be even better).
void g() { y = 0; }
// CHECK-MESSAGES-NOT: :[[@LINE-1]] warning: use nullptr

T x;
T y;
};
void test_templated() {
pear<int*> p;
p.f();
p.g();
dummy(p.x);
}

#define IS_EQ(x, y) if (x != y) return;
void test_macro_args() {
int i = 0;
Expand Down
Loading