[clang] [clang][dataflow] Fix two null pointer dereferences in `getMemberForAccessor()`. (PR #66742)

via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 18 23:50:32 PDT 2023


https://github.com/martinboehme updated https://github.com/llvm/llvm-project/pull/66742

>From 5cdc525940af9b3b3e7432212b9e6852c6c7a602 Mon Sep 17 00:00:00 2001
From: Martin Braenne <mboehme at google.com>
Date: Tue, 19 Sep 2023 06:49:27 +0000
Subject: [PATCH] [clang][dataflow] Fix two null pointer dereferences in
 `getMemberForAccessor()`.

The additions to the test trigger crashes without the fixes.
---
 clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp | 5 ++++-
 clang/unittests/Analysis/FlowSensitive/TransferTest.cpp  | 9 +++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 26e097349057238..9dc528567038ac4 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -289,11 +289,14 @@ static void insertIfFunction(const Decl &D,
 }
 
 static MemberExpr *getMemberForAccessor(const CXXMemberCallExpr &C) {
+  if (!C.getMethodDecl())
+    return nullptr;
   auto *Body = dyn_cast_or_null<CompoundStmt>(C.getMethodDecl()->getBody());
   if (!Body || Body->size() != 1)
     return nullptr;
   if (auto *RS = dyn_cast<ReturnStmt>(*Body->body_begin()))
-    return dyn_cast<MemberExpr>(RS->getRetValue()->IgnoreParenImpCasts());
+    if (auto *Return = RS->getRetValue())
+      return dyn_cast<MemberExpr>(Return->IgnoreParenImpCasts());
   return nullptr;
 }
 
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 14188f5acd5b36e..e8cbca756460369 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -1463,6 +1463,7 @@ TEST(TransferTest, StructModeledFieldsWithAccessor) {
       int getIntNotAccessed() const { return IntNotAccessed; }
       int getIntNoDefinition() const;
       int &getIntRef() { return IntRef; }
+      void returnVoid() const { return; }
     };
 
     void target() {
@@ -1473,6 +1474,14 @@ TEST(TransferTest, StructModeledFieldsWithAccessor) {
       int i2 = s.getWithInc(1);
       int i3 = s.getIntNoDefinition();
       int &iref = s.getIntRef();
+
+      // Regression test: Don't crash on an indirect call (which doesn't have
+      // an associated `CXXMethodDecl`).
+      auto ptr_to_member_fn = &S::getPtr;
+      p1 = (s.*ptr_to_member_fn)();
+
+      // Regression test: Don't crash on a return statement without a value.
+      s.returnVoid();
       // [[p]]
     }
   )";



More information about the cfe-commits mailing list