Skip to content

Commit 6168739

Browse files
authored
[clang][bytecode] Reject memcpy sizes with element size remainder (#119209)
1 parent 664a226 commit 6168739

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,6 +1860,21 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18601860
return false;
18611861
}
18621862

1863+
QualType ElemType;
1864+
if (SrcPtr.getFieldDesc()->isArray())
1865+
ElemType = SrcPtr.getFieldDesc()->getElemQualType();
1866+
else
1867+
ElemType = SrcPtr.getType();
1868+
1869+
unsigned ElemSize =
1870+
S.getASTContext().getTypeSizeInChars(ElemType).getQuantity();
1871+
if (Size.urem(ElemSize) != 0) {
1872+
S.FFDiag(S.Current->getSource(OpPC),
1873+
diag::note_constexpr_memcpy_unsupported)
1874+
<< Move << /*IsWchar=*/false << 0 << ElemType << Size << ElemSize;
1875+
return false;
1876+
}
1877+
18631878
// As a last resort, reject dummy pointers.
18641879
if (DestPtr.isDummy() || SrcPtr.isDummy())
18651880
return false;

clang/test/AST/ByteCode/builtin-functions.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,4 +1197,14 @@ namespace BuiltinMemcpy {
11971197
return b;
11981198
}
11991199
static_assert(simpleMove() == 12);
1200+
1201+
constexpr int memcpyTypeRem() { // ref-error {{never produces a constant expression}}
1202+
int a = 12;
1203+
int b = 0;
1204+
__builtin_memmove(&b, &a, 1); // both-note {{'memmove' not supported: size to copy (1) is not a multiple of size of element type 'int'}} \
1205+
// ref-note {{not supported}}
1206+
return b;
1207+
}
1208+
static_assert(memcpyTypeRem() == 12); // both-error {{not an integral constant expression}} \
1209+
// both-note {{in call to}}
12001210
}

0 commit comments

Comments
 (0)