https://github.com/Ved235 updated https://github.com/llvm/llvm-project/pull/230869
>From 3ae1762f92c0dba16b54c337fe8341084858c34d Mon Sep 17 00:00:00 2001 From: Vedant <[email protected]> Date: Sat, 10 Oct 2026 23:29:16 +0100 Subject: [PATCH] Fix type conversion in constant evaluation of strchr --- clang/lib/AST/ByteCode/InterpBuiltin.cpp | 16 ---------------- clang/lib/AST/ExprConstant.cpp | 7 ------- clang/test/AST/ByteCode/builtin-functions.cpp | 12 ++++++++---- clang/test/SemaCXX/constexpr-string.cpp | 12 ++++++++---- 4 files changed, 16 insertions(+), 31 deletions(-) diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 4a5c691d390a71..53d543928efa3e 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2378,22 +2378,6 @@ static bool interp__builtin_memchr(InterpState &S, CodePtr OpPC, if (!isReadable(Ptr)) return false; - if (ID == Builtin::BIstrchr || ID == Builtin::BI__builtin_strchr) { - int64_t DesiredTrunc; - if (S.getASTContext().CharTy->isSignedIntegerType()) - DesiredTrunc = - Desired.trunc(S.getASTContext().getCharWidth()).getSExtValue(); - else - DesiredTrunc = - Desired.trunc(S.getASTContext().getCharWidth()).getZExtValue(); - // strchr compares directly to the passed integer, and therefore - // always fails if given an int that is not a char. - if (Desired != DesiredTrunc) { - S.Stk.push<Pointer>(); - return true; - } - } - uint64_t DesiredVal; if (ID == Builtin::BIwmemchr || ID == Builtin::BI__builtin_wmemchr || ID == Builtin::BIwcschr || ID == Builtin::BI__builtin_wcschr) { diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 8551f4c9ae279a..f5b562a4eab677 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -10877,13 +10877,6 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, switch (BuiltinOp) { case Builtin::BIstrchr: case Builtin::BI__builtin_strchr: - // strchr compares directly to the passed integer, and therefore - // always fails if given an int that is not a char. - if (!APSInt::isSameValue(HandleIntToIntCast(Info, E, CharTy, - E->getArg(1)->getType(), - Desired), - Desired)) - return ZeroInitialization(E); StopAtNull = true; [[fallthrough]]; case Builtin::BImemchr: diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index 211c3e98d161c4..ae07bae2779629 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -1825,11 +1825,15 @@ namespace Strchr { static_assert(__builtin_strchr(kStr, 'd') == nullptr); static_assert(__builtin_strchr(kStr, 'e') == nullptr); static_assert(__builtin_strchr(kStr, '\0') == kStr + 5); - static_assert(__builtin_strchr(kStr, 'a' + 256) == nullptr); - static_assert(__builtin_strchr(kStr, 'a' - 256) == nullptr); + static_assert(__builtin_strchr(kStr, 256) == kStr + 5); + static_assert(__builtin_strchr(kStr, -256) == kStr + 5); + static_assert(__builtin_strchr(kStr, 'a' + 256) == kStr); + static_assert(__builtin_strchr(kStr, 'a' - 256) == kStr); static_assert(__builtin_strchr(kStr, '\xff') == kStr + 4); - static_assert(__builtin_strchr(kStr, '\xff' + 256) == nullptr); - static_assert(__builtin_strchr(kStr, '\xff' - 256) == nullptr); + static_assert(__builtin_strchr(kStr, '\xff' + 256) == kStr + 4); + static_assert(__builtin_strchr(kStr, '\xff' - 256) == kStr + 4); + constexpr char kStr2[] = "\x80\x41"; + static_assert(__builtin_strchr(kStr2, 128) == kStr2); static_assert(__builtin_strchr(kFoo, 'o') == kFoo + 1); static_assert(__builtin_strchr(kFoo, 'x') == nullptr); // both-error {{not an integral constant}} \ // both-note {{dereferenced one-past-the-end}} diff --git a/clang/test/SemaCXX/constexpr-string.cpp b/clang/test/SemaCXX/constexpr-string.cpp index b49979bbc8ca0e..b55118ffc9e2a5 100644 --- a/clang/test/SemaCXX/constexpr-string.cpp +++ b/clang/test/SemaCXX/constexpr-string.cpp @@ -369,11 +369,15 @@ namespace StrchrEtc { static_assert(__builtin_strchr(kStr, 'd') == nullptr); static_assert(__builtin_strchr(kStr, 'e') == nullptr); static_assert(__builtin_strchr(kStr, '\0') == kStr + 5); - static_assert(__builtin_strchr(kStr, 'a' + 256) == nullptr); - static_assert(__builtin_strchr(kStr, 'a' - 256) == nullptr); + static_assert(__builtin_strchr(kStr, 256) == kStr + 5); + static_assert(__builtin_strchr(kStr, -256) == kStr + 5); + static_assert(__builtin_strchr(kStr, 'a' + 256) == kStr); + static_assert(__builtin_strchr(kStr, 'a' - 256) == kStr); static_assert(__builtin_strchr(kStr, '\xff') == kStr + 4); - static_assert(__builtin_strchr(kStr, '\xff' + 256) == nullptr); - static_assert(__builtin_strchr(kStr, '\xff' - 256) == nullptr); + static_assert(__builtin_strchr(kStr, '\xff' + 256) == kStr + 4); + static_assert(__builtin_strchr(kStr, '\xff' - 256) == kStr + 4); + constexpr char kStr2[] = "\x80\x41"; + static_assert(__builtin_strchr(kStr2, 128) == kStr2); static_assert(__builtin_strchr(kFoo, 'o') == kFoo + 1); static_assert(__builtin_strchr(kFoo, 'x') == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} static_assert(__builtin_strchr(nullptr, 'x') == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
