diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2018-04-23 22:04:34 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2018-04-23 22:04:34 +0000 |
commit | 33b7092601480cd7ef8d15c702eb021307192fa2 (patch) | |
tree | 243c22be382095ef1b5d95980d9931f959f0c172 /clang/lib/AST/ExprConstant.cpp | |
parent | 403c667b4ba633eeb1772fd10759b9cc77699ae3 (diff) | |
download | bcm5719-llvm-33b7092601480cd7ef8d15c702eb021307192fa2.tar.gz bcm5719-llvm-33b7092601480cd7ef8d15c702eb021307192fa2.zip |
[AST] strcmp/memcmp always compares unsigned chars.
This makes it return the right result in a couple of edge cases. The
wide versions always do the comparison on the underlying wchar_t type.
llvm-svn: 330656
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 623cb54a6fe..81577248612 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8046,14 +8046,24 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, BuiltinOp != Builtin::BIwmemcmp && BuiltinOp != Builtin::BI__builtin_memcmp && BuiltinOp != Builtin::BI__builtin_wmemcmp); + bool IsWide = BuiltinOp == Builtin::BIwcscmp || + BuiltinOp == Builtin::BIwcsncmp || + BuiltinOp == Builtin::BIwmemcmp || + BuiltinOp == Builtin::BI__builtin_wcscmp || + BuiltinOp == Builtin::BI__builtin_wcsncmp || + BuiltinOp == Builtin::BI__builtin_wmemcmp; for (; MaxLength; --MaxLength) { APValue Char1, Char2; if (!handleLValueToRValueConversion(Info, E, CharTy, String1, Char1) || !handleLValueToRValueConversion(Info, E, CharTy, String2, Char2) || !Char1.isInt() || !Char2.isInt()) return false; - if (Char1.getInt() != Char2.getInt()) - return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, E); + if (Char1.getInt() != Char2.getInt()) { + if (IsWide) // wmemcmp compares with wchar_t signedness. + return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, E); + // memcmp always compares unsigned chars. + return Success(Char1.getInt().ult(Char2.getInt()) ? -1 : 1, E); + } if (StopAtNull && !Char1.getInt()) return Success(0, E); assert(!(StopAtNull && !Char2.getInt())); |