summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2018-04-23 22:04:34 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2018-04-23 22:04:34 +0000
commit33b7092601480cd7ef8d15c702eb021307192fa2 (patch)
tree243c22be382095ef1b5d95980d9931f959f0c172 /clang/lib/AST/ExprConstant.cpp
parent403c667b4ba633eeb1772fd10759b9cc77699ae3 (diff)
downloadbcm5719-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.cpp14
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()));
OpenPOWER on IntegriCloud