aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/InterpBuiltin.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-04-16 17:08:10 +0200
committerGitHub <noreply@github.com>2025-04-16 17:08:10 +0200
commitab7e0c0fc00b2c0ccae735cb0def103831d15b3b (patch)
treed558b11690c81e6d3b08850f4b00f16cc6da21fc /clang/lib/AST/ByteCode/InterpBuiltin.cpp
parent99c08ff1cb96fc4f471aca0dd253060b3f32e8bc (diff)
downloadllvm-ab7e0c0fc00b2c0ccae735cb0def103831d15b3b.zip
llvm-ab7e0c0fc00b2c0ccae735cb0def103831d15b3b.tar.gz
llvm-ab7e0c0fc00b2c0ccae735cb0def103831d15b3b.tar.bz2
[clang][bytecode] Implement __builtin_wmem{cpy,move} (#135969)
Diffstat (limited to 'clang/lib/AST/ByteCode/InterpBuiltin.cpp')
-rw-r--r--clang/lib/AST/ByteCode/InterpBuiltin.cpp30
1 files changed, 22 insertions, 8 deletions
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index d06941b..b694a34 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -1788,14 +1788,18 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
Pointer DestPtr = getParam<Pointer>(Frame, 0);
const ASTContext &ASTCtx = S.getASTContext();
const Pointer &SrcPtr = getParam<Pointer>(Frame, 1);
- const APSInt &Size =
- peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2)));
+ APSInt Size = peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2)));
assert(!Size.isSigned() && "memcpy and friends take an unsigned size");
if (ID == Builtin::BImemcpy || ID == Builtin::BImemmove)
diagnoseNonConstexprBuiltin(S, OpPC, ID);
- bool Move = (ID == Builtin::BI__builtin_memmove || ID == Builtin::BImemmove);
+ bool Move =
+ (ID == Builtin::BI__builtin_memmove || ID == Builtin::BImemmove ||
+ ID == Builtin::BI__builtin_wmemmove || ID == Builtin::BIwmemmove);
+ bool WChar = ID == Builtin::BIwmemcpy || ID == Builtin::BIwmemmove ||
+ ID == Builtin::BI__builtin_wmemcpy ||
+ ID == Builtin::BI__builtin_wmemmove;
// If the size is zero, we treat this as always being a valid no-op.
if (Size.isZero()) {
@@ -1806,7 +1810,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
if (SrcPtr.isZero() || DestPtr.isZero()) {
Pointer DiagPtr = (SrcPtr.isZero() ? SrcPtr : DestPtr);
S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_null)
- << /*IsMove=*/Move << /*IsWchar=*/false << !SrcPtr.isZero()
+ << /*IsMove=*/Move << /*IsWchar=*/WChar << !SrcPtr.isZero()
<< DiagPtr.toDiagnosticString(ASTCtx);
return false;
}
@@ -1818,7 +1822,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
? std::to_string(SrcPtr.getIntegerRepresentation())
: std::to_string(DestPtr.getIntegerRepresentation());
S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_null)
- << Move << false << DestPtr.isIntegralPointer() << DiagVal;
+ << Move << WChar << DestPtr.isIntegralPointer() << DiagVal;
return false;
}
@@ -1837,11 +1841,17 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
}
unsigned DestElemSize = ASTCtx.getTypeSizeInChars(DestElemType).getQuantity();
+ if (WChar) {
+ uint64_t WCharSize =
+ ASTCtx.getTypeSizeInChars(ASTCtx.getWCharType()).getQuantity();
+ Size *= APSInt(APInt(Size.getBitWidth(), WCharSize, /*IsSigned=*/false),
+ /*IsUnsigend=*/true);
+ }
+
if (Size.urem(DestElemSize) != 0) {
S.FFDiag(S.Current->getSource(OpPC),
diag::note_constexpr_memcpy_unsupported)
- << Move << /*IsWchar=*/false << 0 << DestElemType << Size
- << DestElemSize;
+ << Move << WChar << 0 << DestElemType << Size << DestElemSize;
return false;
}
@@ -1869,7 +1879,7 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
APInt N = Size.udiv(DestElemSize);
S.FFDiag(S.Current->getSource(OpPC),
diag::note_constexpr_memcpy_unsupported)
- << Move << /*IsWChar*/ false << (Size.ugt(RemainingSrcBytes) ? 1 : 2)
+ << Move << WChar << (Size.ugt(RemainingSrcBytes) ? 1 : 2)
<< DestElemType << toString(N, 10, /*Signed=*/false);
return false;
}
@@ -2587,8 +2597,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
case Builtin::BI__builtin_memcpy:
case Builtin::BImemcpy:
+ case Builtin::BI__builtin_wmemcpy:
+ case Builtin::BIwmemcpy:
case Builtin::BI__builtin_memmove:
case Builtin::BImemmove:
+ case Builtin::BI__builtin_wmemmove:
+ case Builtin::BIwmemmove:
if (!interp__builtin_memcpy(S, OpPC, Frame, F, Call))
return false;
break;