Author: Shafik Yaghmour Date: 2023-08-25T13:54:50-07:00 New Revision: 33b6b674620d77e615d569f504b306aac528bab7
URL: https://github.com/llvm/llvm-project/commit/33b6b674620d77e615d569f504b306aac528bab7 DIFF: https://github.com/llvm/llvm-project/commit/33b6b674620d77e615d569f504b306aac528bab7.diff LOG: [clang] Fix crash in __builtin_strncmp and other related builtin functions The implementation of __builtin_strncmp and other related builtins function use getExtValue() to evaluate the size argument. This can cause a crash when the value does not fit into an int64_t value, which is can be expected since the type of the argument is size_t. The fix is to switch to using getZExtValue(). This fixes: https://github.com/llvm/llvm-project/issues/64876 Differential Revision: https://reviews.llvm.org/D158557 Added: clang/test/CodeGen/gh64876.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constexpr-string.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8580b2ccb20c24..0fff49c2c5108a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -179,6 +179,9 @@ Bug Fixes in This Version - Clang now prints unnamed members in diagnostic messages instead of giving an empty ''. Fixes (`#63759 <https://github.com/llvm/llvm-project/issues/63759>`_) +- Fix crash in __builtin_strncmp and related builtins when the size value + exceeded the maximum value representable by int64_t. Fixes + (`#64876 <https://github.com/llvm/llvm-project/issues/64876>`_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d77c5d3f84a8d7..c6ab3758e99c1b 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9361,7 +9361,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, APSInt N; if (!EvaluateInteger(E->getArg(2), N, Info)) return false; - MaxLength = N.getExtValue(); + MaxLength = N.getZExtValue(); } // We cannot find the value if there are no candidates to match against. if (MaxLength == 0u) @@ -12385,7 +12385,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, APSInt N; if (!EvaluateInteger(E->getArg(2), N, Info)) return false; - MaxLength = N.getExtValue(); + MaxLength = N.getZExtValue(); } // Empty substrings compare equal by definition. diff --git a/clang/test/CodeGen/gh64876.cpp b/clang/test/CodeGen/gh64876.cpp new file mode 100644 index 00000000000000..de46c4922768ae --- /dev/null +++ b/clang/test/CodeGen/gh64876.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s + +void f(const char* C, const wchar_t *WC) { + int x1 = __builtin_strncmp(C, "b", 0xffffffffffffffff); +// CHECK: {{.*}}= call i32 @strncmp{{.*}}i64 noundef -1 + int x2 = __builtin_memcmp(C, "b", 0xffffffffffffffff); +// CHECK: {{.*}}= call i32 @memcmp{{.*}}i64 noundef -1 + int x3 = __builtin_bcmp(C, "b", 0xffffffffffffffff); +// CHECK: {{.*}}= call i32 @bcmp{{.*}}i64 noundef -1 + int x4 = __builtin_wmemcmp(WC, L"b", 0xffffffffffffffff); +// CHECK: {{.*}}= call i32 @wmemcmp{{.*}}i64 noundef -1 + auto x5 = __builtin_memchr(C, (int)'a', 0xffffffffffffffff); +// CHECK: {{.*}}= call ptr @memchr{{.*}}i64 noundef -1 + auto x6 = __builtin_wmemchr(WC, (int)'a', 0xffffffffffffffff); +// CHECK: {{.*}}= call ptr @wmemchr{{.*}}i64 noundef -1 +} diff --git a/clang/test/SemaCXX/constexpr-string.cpp b/clang/test/SemaCXX/constexpr-string.cpp index cfee3566bbff71..c456740ef7551f 100644 --- a/clang/test/SemaCXX/constexpr-string.cpp +++ b/clang/test/SemaCXX/constexpr-string.cpp @@ -676,3 +676,24 @@ namespace MemcpyEtc { } static_assert(test_address_of_incomplete_struct_type()); // expected-error {{constant}} expected-note {{in call}} } + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wconstant-conversion" +namespace GH64876 { +void f() { + __builtin_strncmp(0, 0, 0xffffffffffffffff); + __builtin_memcmp(0, 0, 0xffffffffffffffff); + __builtin_bcmp(0, 0, 0xffffffffffffffff); + __builtin_wmemcmp(0, 0, 0xffffffffffffffff); + __builtin_memchr((const void*)0, 1, 0xffffffffffffffff); + __builtin_wmemchr((const wchar_t*)0, 1, 0xffffffffffffffff); + + __builtin_strncmp(0, 0, -511LL); + __builtin_memcmp(0, 0, -511LL); + __builtin_bcmp(0, 0, -511LL); + __builtin_wmemcmp(0, 0, -511LL); + __builtin_memchr((const void*)0, 1, -511LL); + __builtin_wmemchr((const wchar_t*)0, 1, -511LL); +} +} +#pragma clang diagnostic pop _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits