Skip to content

Conversation

@zahiraam
Copy link
Contributor

@zahiraam zahiraam commented May 2, 2025

A nullptr dereference is detected by the code sanitizer. Adding an assert to make sure it's caught.

@zahiraam zahiraam marked this pull request as ready for review May 2, 2025 14:22
@zahiraam zahiraam requested a review from tahonermann May 2, 2025 14:22
@llvmbot
Copy link
Member

llvmbot commented May 2, 2025

@llvm/pr-subscribers-clang-tools-extra

@llvm/pr-subscribers-clang-tidy

Author: Zahira Ammarguellat (zahiraam)

Changes

A nullptr dereference is detected by the code sanitizer. Adding an assert to make sure it's caught.


Full diff: https://github.com/llvm/llvm-project/pull/138283.diff

1 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp (+1)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp
index 247d287be2b36..e90170a6591da 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp
@@ -25,6 +25,7 @@ void RedundantFunctionPtrDereferenceCheck::registerMatchers(MatchFinder *Finder)
 
 void RedundantFunctionPtrDereferenceCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *Operator = Result.Nodes.getNodeAs<UnaryOperator>("op");
+  assert(Operator && "Operator is null");
   diag(Operator->getOperatorLoc(),
        "redundant repeated dereference of function pointer")
       << FixItHint::CreateRemoval(Operator->getOperatorLoc());

@vbvictor
Copy link
Contributor

vbvictor commented May 2, 2025

Did you run code sanitizer over all clang-tidy code or you only interested in this particular file?
I think there are many more places where such nullptr dereference can happen, e.g.

const auto *MemberCall =
Result.Nodes.getNodeAs<CXXMemberCallExpr>("erase");
const auto *EndExpr =
Result.Nodes.getNodeAs<CXXMemberCallExpr>("end");
const SourceLocation Loc = MemberCall->getBeginLoc();

const auto *CastExpr = Result.Nodes.getNodeAs<ImplicitCastExpr>("CastExpr");
diag(CastExpr->getBeginLoc(),

@zahiraam
Copy link
Contributor Author

zahiraam commented May 2, 2025

Did you run code sanitizer over all clang-tidy code or you only interested in this particular file? I think there are many more places where such nullptr dereference can happen, e.g.

const auto *MemberCall =
Result.Nodes.getNodeAs<CXXMemberCallExpr>("erase");
const auto *EndExpr =
Result.Nodes.getNodeAs<CXXMemberCallExpr>("end");
const SourceLocation Loc = MemberCall->getBeginLoc();

const auto *CastExpr = Result.Nodes.getNodeAs<ImplicitCastExpr>("CastExpr");
diag(CastExpr->getBeginLoc(),

Probably. But we usually stick to the potential issues suggested by the sanitizer.

Copy link
Contributor

@nicovank nicovank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed IMO. This is a simple matcher, op is expected to always be bound.

One might say that it can't hurt to add extra checks, but I don't think that's good justification for adding more code / bloat, even if in this case it's a single line. Still, 5% more code for this check counting non-empty non-comment lines!

Happy to disagree if any of the maintainers think otherwise.

@zahiraam
Copy link
Contributor Author

zahiraam commented May 2, 2025

This is not needed IMO. This is a simple matcher, op is expected to always be bound.

One might say that it can't hurt to add extra checks, but I don't think that's good justification for adding more code / bloat, even if in this case it's a single line. Still, 5% more code for this check counting non-empty non-comment lines!

Happy to disagree if any of the maintainers think otherwise.

The sanitizer is complaining about the possibility of having Operator be null. op might always be bound. But it might not be a UnaryOperator, no?

@vbvictor
Copy link
Contributor

vbvictor commented May 2, 2025

I don't have a strong opinion on this, but this assert may be a sign of "false safety".
In release builds, it's a no-op, so end users will experience a regular Segfault, e.g. like this issue #135665.
Debug builds with asserts are usually used in development process where tests run regularly, so all nullptr dereferences must be caught there.
TLDR, adding this assert "retrospectively" probably have no impact.

@nicovank
Copy link
Contributor

nicovank commented May 2, 2025

But it might not be a UnaryOperator, no?

unaryOperator(...).bind("op") implies op will always be a UnaryOperator.

@zahiraam
Copy link
Contributor Author

zahiraam commented May 2, 2025

Thanks for your input. I will close this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants