[clang] 944db8a - Permit constant evaluation of mixed __builtin_memcmp between char and
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 5 15:37:42 PDT 2020
Author: Richard Smith
Date: 2020-04-05T15:35:32-07:00
New Revision: 944db8a433f591e514219c12fa33b7e8fdd5e883
URL: https://github.com/llvm/llvm-project/commit/944db8a433f591e514219c12fa33b7e8fdd5e883
DIFF: https://github.com/llvm/llvm-project/commit/944db8a433f591e514219c12fa33b7e8fdd5e883.diff
LOG: Permit constant evaluation of mixed __builtin_memcmp between char and
char8_t.
Added:
Modified:
clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/constexpr-string.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index a10a4dab6dff..35232bebbb3a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8319,6 +8319,12 @@ bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) {
return visitNonBuiltinCallExpr(E);
}
+// Determine if T is a character type for which we guarantee that
+// sizeof(T) == 1.
+static bool isOneByteCharacterType(QualType T) {
+ return T->isCharType() || T->isChar8Type();
+}
+
bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
unsigned BuiltinOp) {
switch (BuiltinOp) {
@@ -8469,7 +8475,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
}
// Give up on byte-oriented matching against multibyte elements.
// FIXME: We can compare the bytes in the correct order.
- if (IsRawByte && !CharTy->isCharType() && !CharTy->isChar8Type()) {
+ if (IsRawByte && !isOneByteCharacterType(CharTy)) {
Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'")
<< CharTy;
@@ -11156,9 +11162,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
// For memcmp, allow comparing any arrays of '[[un]signed] char' or
// 'char8_t', but no other types.
- bool IsChar = CharTy1->isCharType() && CharTy2->isCharType();
- bool IsChar8 = CharTy1->isChar8Type() && CharTy2->isChar8Type();
- if (IsRawByte && !IsChar && !IsChar8) {
+ if (IsRawByte &&
+ !(isOneByteCharacterType(CharTy1) && isOneByteCharacterType(CharTy2))) {
// FIXME: Consider using our bit_cast implementation to support this.
Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'")
diff --git a/clang/test/SemaCXX/constexpr-string.cpp b/clang/test/SemaCXX/constexpr-string.cpp
index b9f90adf7b76..f33627e812b2 100644
--- a/clang/test/SemaCXX/constexpr-string.cpp
+++ b/clang/test/SemaCXX/constexpr-string.cpp
@@ -118,6 +118,9 @@ namespace StrcmpEtc {
static_assert(__builtin_memcmp(u8"abab\0banana", u8"abab\0canada", 6) == -1);
static_assert(__builtin_memcmp(u8"abab\0banana", u8"abab\0canada", 5) == 0);
+ static_assert(__builtin_memcmp(u8"\u1234", "\xE1\x88\xB4", 4) == 0);
+ static_assert(__builtin_memcmp(u8"\u1234", "\xE1\x88\xB3", 4) == 1);
+
static_assert(__builtin_bcmp("abaa", "abba", 3) != 0);
static_assert(__builtin_bcmp("abaa", "abba", 2) == 0);
static_assert(__builtin_bcmp("a\203", "a", 2) != 0);
More information about the cfe-commits
mailing list