Skip to content

Conversation

@boomanaiden154
Copy link
Contributor

After the landing of #169320, the clang CFG analyses are able to do slightly more analysis around destructors. This results in thread safety also seeing slightly more destructors. This exposed a bug in ThreadSafety, where we would call getDestructorDecl, which can return nullptr for base class destructors, but not do a null pointer check, resulting in a segmentation fault.

This patch fixes the issue by adding a null pointer check and adds a regression test so this gets caught before downstream integration testing in the future.

After the landing of llvm#169320,
the clang CFG analyses are able to do slightly more analysis around
destructors. This results in thread safety also seeing slightly more
destructors. This exposed a bug in ThreadSafety, where we would call
getDestructorDecl, which can return nullptr for base class destructors,
but not do a null pointer check, resulting in a segmentation fault.

This patch fixes the issue by adding a null pointer check and adds a
regression test so this gets caught before downstream integration
testing in the future.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:analysis labels Nov 26, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 26, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-analysis

Author: Aiden Grossman (boomanaiden154)

Changes

After the landing of #169320, the clang CFG analyses are able to do slightly more analysis around destructors. This results in thread safety also seeing slightly more destructors. This exposed a bug in ThreadSafety, where we would call getDestructorDecl, which can return nullptr for base class destructors, but not do a null pointer check, resulting in a segmentation fault.

This patch fixes the issue by adding a null pointer check and adds a regression test so this gets caught before downstream integration testing in the future.


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

2 Files Affected:

  • (modified) clang/lib/Analysis/ThreadSafety.cpp (+1-1)
  • (added) clang/test/SemaCXX/no-warn-thread-safety-analysis.cpp (+12)
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index 77750cf89d7a7..a25bd6007d5ed 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -2820,7 +2820,7 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
         case CFGElement::AutomaticObjectDtor: {
           CFGAutomaticObjDtor AD = BI.castAs<CFGAutomaticObjDtor>();
           const auto *DD = AD.getDestructorDecl(AC.getASTContext());
-          if (!DD->hasAttrs())
+          if (!DD || !DD->hasAttrs())
             break;
 
           LocksetBuilder.handleCall(
diff --git a/clang/test/SemaCXX/no-warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/no-warn-thread-safety-analysis.cpp
new file mode 100644
index 0000000000000..5b1964301fce7
--- /dev/null
+++ b/clang/test/SemaCXX/no-warn-thread-safety-analysis.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-pointer -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-pointer -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-pointer -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-pointer -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=1 %s
+// expected-no-diagnostics
+
+struct foo {
+  ~foo();
+};
+struct bar : foo {};
+struct baz : bar {};
+baz foobar(baz a) { return a; }

Copy link
Contributor

@usx95 usx95 left a comment

Choose a reason for hiding this comment

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

Thanks for the quick fix !

@boomanaiden154 boomanaiden154 merged commit 175168c into llvm:main Nov 26, 2025
11 of 12 checks passed
@boomanaiden154 boomanaiden154 deleted the fix-clang-crash-base-class-destructor-thread-safety branch November 26, 2025 02:50
@@ -0,0 +1,12 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-pointer -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_CAPABILITY=0 %s
Copy link
Contributor

Choose a reason for hiding this comment

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

Why was a new test file created for this and not just added to the existing suite: https://github.com/llvm/llvm-project/blob/main/clang/test/SemaCXX/warn-thread-safety-analysis.cpp ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There weren't any existing cases in there that used expected-no-diagnostics, and I've seen similar cases split similarly between positive and negative checks like this.

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

Labels

clang:analysis clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants