[clang] [analyzer] Canonicalize _Atomic pointers in makeNullWithType (PR #190131)
Carson Radtke via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 8 12:16:57 PDT 2026
https://github.com/carsonRadtke updated https://github.com/llvm/llvm-project/pull/190131
>From 9978eee4cf618ac54aa8407b69f664286114b348 Mon Sep 17 00:00:00 2001
From: Carson Radtke <nosrac925 at gmail.com>
Date: Thu, 2 Apr 2026 02:08:39 -0600
Subject: [PATCH 1/2] [clang:static-analyze] fix: allow construction of atomic
pointers from nullptr.
fixes: https://github.com/llvm/llvm-project/issues/187925
Previous code did not handle passing AtomicType to `makeNullWithType`
and this led to an assertion failure.
This change updates `makeNullWithType` to allow for atomic types to be
passed in and to "unwrap" them in order to get the correct
pointer/reference type for constructing the nullptr.
---
.../clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h | 7 ++++---
.../clang/StaticAnalyzer/Core/PathSensitive/SVals.h | 1 +
clang/test/Analysis/atomics.c | 5 +++++
3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 2911554de9d97..4ee21f4a637e8 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -346,11 +346,12 @@ class SValBuilder {
/// \param type pointer type.
loc::ConcreteInt makeNullWithType(QualType type) {
// We cannot use the `isAnyPointerType()`.
- assert((type->isPointerType() || type->isObjCObjectPointerType() ||
- type->isBlockPointerType() || type->isNullPtrType() ||
- type->isReferenceType()) &&
+ assert((type->isObjCObjectPointerType() || Loc::isLocType(type)) &&
"makeNullWithType must use pointer type");
+ type =
+ type->isAtomicType() ? type->getAs<AtomicType>()->getValueType() : type;
+
// The `sizeof(T&)` is `sizeof(T)`, thus we replace the reference with a
// pointer. Here we assume that references are actually implemented by
// pointers under-the-hood.
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index aeb57b28077c6..d7644645b1c15 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -260,6 +260,7 @@ class Loc : public DefinedSVal {
void dumpToStream(raw_ostream &Out) const;
static bool isLocType(QualType T) {
+ T = T->isAtomicType() ? T->getAs<AtomicType>()->getValueType() : T;
return T->isAnyPointerType() || T->isBlockPointerType() ||
T->isReferenceType() || T->isNullPtrType();
}
diff --git a/clang/test/Analysis/atomics.c b/clang/test/Analysis/atomics.c
index ef1a216c7d577..fc5ab5f589a00 100644
--- a/clang/test/Analysis/atomics.c
+++ b/clang/test/Analysis/atomics.c
@@ -101,3 +101,8 @@ void test_atomic_compare(int input) {
// no crash
}
}
+
+void test_atomic_gh187925(void) {
+ void foo(_Atomic(void*));
+ foo(0); // no assertion failure
+}
>From e02b5de265daee26c7cbae3fe577da69218ec3f2 Mon Sep 17 00:00:00 2001
From: Carson Radtke <nosrac925 at gmail.com>
Date: Wed, 8 Apr 2026 12:39:57 -0600
Subject: [PATCH 2/2] address PR feedback
---
.../clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h | 6 +++---
.../include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h | 1 -
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 4ee21f4a637e8..5e6d8c51867b3 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -345,13 +345,13 @@ class SValBuilder {
/// space.
/// \param type pointer type.
loc::ConcreteInt makeNullWithType(QualType type) {
+ type =
+ type->isAtomicType() ? type->getAs<AtomicType>()->getValueType() : type;
+
// We cannot use the `isAnyPointerType()`.
assert((type->isObjCObjectPointerType() || Loc::isLocType(type)) &&
"makeNullWithType must use pointer type");
- type =
- type->isAtomicType() ? type->getAs<AtomicType>()->getValueType() : type;
-
// The `sizeof(T&)` is `sizeof(T)`, thus we replace the reference with a
// pointer. Here we assume that references are actually implemented by
// pointers under-the-hood.
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index d7644645b1c15..aeb57b28077c6 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -260,7 +260,6 @@ class Loc : public DefinedSVal {
void dumpToStream(raw_ostream &Out) const;
static bool isLocType(QualType T) {
- T = T->isAtomicType() ? T->getAs<AtomicType>()->getValueType() : T;
return T->isAnyPointerType() || T->isBlockPointerType() ||
T->isReferenceType() || T->isNullPtrType();
}
More information about the cfe-commits
mailing list