[clang] c94c90b - [analyzer] Fix _Atomic crashes for Z3 symbolic execution (#212050)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 26 07:08:20 PDT 2026
Author: rdevshp
Date: 2026-07-26T15:08:15+01:00
New Revision: c94c90b2efaa46520024b2bc8aa2caa30114cd55
URL: https://github.com/llvm/llvm-project/commit/c94c90b2efaa46520024b2bc8aa2caa30114cd55
DIFF: https://github.com/llvm/llvm-project/commit/c94c90b2efaa46520024b2bc8aa2caa30114cd55.diff
LOG: [analyzer] Fix _Atomic crashes for Z3 symbolic execution (#212050)
This PR fixes _Atomic crashes for Z3 symbolic execution by passing the
types through getAtomicUnqualifiedType and getCanonicalType and skip
casting in fromCast if `FromTy == ToTy && FromBitWidth == ToBitWidth`.
Assisted-by: Codex
Added:
clang/test/Analysis/z3/z3-atomic.c
Modified:
clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
Removed:
################################################################################
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
index 61a71545fb1a6..975536aeb37e9 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
@@ -26,11 +26,16 @@ namespace ento {
class SMTConv {
public:
static inline uint64_t getSMTBitWidth(ASTContext &Ctx, QualType Ty) {
+ Ty = getSymbolicValueType(Ty);
if (Ty->isIntegralOrEnumerationType())
return Ctx.getIntWidth(Ty);
return Ctx.getTypeSize(Ty);
}
+ static inline QualType getSymbolicValueType(QualType Ty) {
+ return Ty.getAtomicUnqualifiedType().getCanonicalType();
+ }
+
// Returns an appropriate sort, given a QualType and it's bit width.
static inline llvm::SMTSortRef mkSort(llvm::SMTSolverRef &Solver,
const QualType &Ty, unsigned BitWidth) {
@@ -270,8 +275,14 @@ class SMTConv {
QualType ToTy, uint64_t ToBitWidth,
QualType FromTy,
uint64_t FromBitWidth) {
- if ((FromTy.getAtomicUnqualifiedType()->isIntegralOrEnumerationType() &&
- ToTy.getAtomicUnqualifiedType()->isIntegralOrEnumerationType()) ||
+ FromTy = getSymbolicValueType(FromTy);
+ ToTy = getSymbolicValueType(ToTy);
+
+ if (FromTy == ToTy && FromBitWidth == ToBitWidth)
+ return Exp;
+
+ if ((FromTy->isIntegralOrEnumerationType() &&
+ ToTy->isIntegralOrEnumerationType()) ||
(FromTy->isAnyPointerType() ^ ToTy->isAnyPointerType()) ||
(FromTy->isBlockPointerType() ^ ToTy->isBlockPointerType()) ||
(FromTy->isReferenceType() ^ ToTy->isReferenceType())) {
@@ -467,13 +478,13 @@ class SMTConv {
getSymExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym,
QualType &RetTy, bool *hasComparison) {
if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
- RetTy = Sym->getType();
+ RetTy = getSymbolicValueType(Sym->getType());
return fromData(Solver, Ctx, SD);
}
if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
- RetTy = Sym->getType();
+ RetTy = getSymbolicValueType(Sym->getType());
QualType FromTy;
std::optional<llvm::SMTExprRef> Exp =
@@ -485,11 +496,11 @@ class SMTConv {
// e.g. (signed char) (x > 0)
if (hasComparison)
*hasComparison = false;
- return getCastExpr(Solver, Ctx, Exp.value(), FromTy, Sym->getType());
+ return getCastExpr(Solver, Ctx, Exp.value(), FromTy, RetTy);
}
if (const UnarySymExpr *USE = dyn_cast<UnarySymExpr>(Sym)) {
- RetTy = Sym->getType();
+ RetTy = getSymbolicValueType(Sym->getType());
QualType OperandTy;
std::optional<llvm::SMTExprRef> OperandExp =
@@ -523,7 +534,7 @@ class SMTConv {
if (Ctx.getTypeSize(OperandTy) != Ctx.getTypeSize(Sym->getType())) {
if (hasComparison)
*hasComparison = false;
- return getCastExpr(Solver, Ctx, UnaryExp, OperandTy, Sym->getType());
+ return getCastExpr(Solver, Ctx, UnaryExp, OperandTy, RetTy);
}
return UnaryExp;
}
diff --git a/clang/test/Analysis/z3/z3-atomic.c b/clang/test/Analysis/z3/z3-atomic.c
new file mode 100644
index 0000000000000..05dd1952496c8
--- /dev/null
+++ b/clang/test/Analysis/z3/z3-atomic.c
@@ -0,0 +1,20 @@
+// RUN: %clang_analyze_cc1 \
+// RUN: -analyzer-checker=core,debug.ExprInspection \
+// RUN: -analyzer-constraints=unsupported-z3 -verify %s
+// REQUIRES: z3
+// expected-no-diagnostics
+
+void atomic_bool(_Bool input) {
+ _Atomic(_Bool) value = input;
+ if (value) { // no-crash
+ }
+}
+
+typedef _Bool B1;
+typedef _Bool B2;
+
+void atomic_bool_typedef(B1 input) {
+ _Atomic(B2) value = input;
+ if (value) { // no-crash
+ }
+}
More information about the cfe-commits
mailing list