https://github.com/naoNao89 updated https://github.com/llvm/llvm-project/pull/150225
From 2d9ae771247af025d6319c044e9f8727e9bebfd8 Mon Sep 17 00:00:00 2001 From: naoNao89 <90588855+naona...@users.noreply.github.com> Date: Wed, 23 Jul 2025 20:54:02 +0700 Subject: [PATCH] [clang][StaticAnalyzer] Fix crash in SimpleSValBuilder with unsigned __int128 and negative literals Fix a crash in SimpleSValBuilder::MakeSymIntVal when processing overflow builtins like __builtin_mul_overflow with unsigned __int128 and negative literal operands. The issue occurred when converting negative values to very large unsigned types (>64 bits). The original logic would convert the negative value to the large unsigned type first (creating a very large positive number), then attempt to negate it, which could cause overflow issues. The fix adds a special case for large unsigned types where we take the absolute value of the negative operand first, then convert it to the target type, avoiding the problematic intermediate conversion. Fixes #150206 --- .../StaticAnalyzer/Core/SimpleSValBuilder.cpp | 12 +++++++++++- clang/test/Analysis/builtin_overflow.c | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 84a9c43d3572e..63c2bb785744b 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -219,7 +219,17 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS, // subtraction/addition of the negated value. APSIntType resultIntTy = BasicVals.getAPSIntType(resultTy); if (isNegationValuePreserving(RHS, resultIntTy)) { - ConvertedRHS = BasicVals.getValue(-resultIntTy.convert(RHS)); + // For large unsigned types, we need to be careful about the conversion + // to avoid issues with very large intermediate values + if (resultIntTy.isUnsigned() && resultIntTy.getBitWidth() > 64) { + // For large unsigned types, convert the absolute value directly + // instead of converting the negative value and then negating + llvm::APSInt AbsRHS = RHS; + AbsRHS.negate(); + ConvertedRHS = BasicVals.Convert(resultTy, AbsRHS); + } else { + ConvertedRHS = BasicVals.getValue(-resultIntTy.convert(RHS)); + } op = (op == BO_Add) ? BO_Sub : BO_Add; } else { ConvertedRHS = BasicVals.Convert(resultTy, RHS); diff --git a/clang/test/Analysis/builtin_overflow.c b/clang/test/Analysis/builtin_overflow.c index d290333071dc9..f2bd08d25ad1f 100644 --- a/clang/test/Analysis/builtin_overflow.c +++ b/clang/test/Analysis/builtin_overflow.c @@ -164,3 +164,22 @@ void test_bool_assign(void) // should return _Bool, but not int. _Bool ret = __builtin_mul_overflow(10, 20, &res); // no crash } + +void test_unsigned_int128_negative_literal(void) +{ + unsigned __int128 a = 42; + + // This should not crash the static analyzer. + // Reproduces issue from GitHub #150206 where __builtin_mul_overflow + // with unsigned __int128 and negative literal caused a crash in + // SimpleSValBuilder::MakeSymIntVal. + __builtin_mul_overflow(a, -16, &a); // no crash + + // Test other overflow builtins with the same pattern + __builtin_add_overflow(a, -16, &a); // no crash + __builtin_sub_overflow(a, -16, &a); // no crash + + // Test with different negative values + __builtin_mul_overflow(a, -1, &a); // no crash + __builtin_mul_overflow(a, -255, &a); // no crash +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits