Skip to content

Commit 0778f47

Browse files
committed
[clang][bytecode] Reject memcpy sizes with element size remainder
1 parent 37cb9bd commit 0778f47

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
@@ -1846,6 +1846,21 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC,
18461846
return false;
18471847
}
18481848

1849+
QualType ElemType;
1850+
if (SrcPtr.getFieldDesc()->isArray())
1851+
ElemType = SrcPtr.getFieldDesc()->getElemQualType();
1852+
else
1853+
ElemType = SrcPtr.getType();
1854+
1855+
unsigned ElemSize =
1856+
S.getASTContext().getTypeSizeInChars(ElemType).getQuantity();
1857+
if (Size.urem(ElemSize) != 0) {
1858+
S.FFDiag(S.Current->getSource(OpPC),
1859+
diag::note_constexpr_memcpy_unsupported)
1860+
<< Move << /*IsWchar=*/false << 0 << ElemType << Size << ElemSize;
1861+
return false;
1862+
}
1863+
18491864
// As a last resort, reject dummy pointers.
18501865
if (DestPtr.isDummy() || SrcPtr.isDummy())
18511866
return false;

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,4 +1188,14 @@ namespace BuiltinMemcpy {
11881188
return b;
11891189
}
11901190
static_assert(simpleMove() == 12);
1191+
1192+
constexpr int memcpyTypeRem() { // ref-error {{never produces a constant expression}}
1193+
int a = 12;
1194+
int b = 0;
1195+
__builtin_memmove(&b, &a, 1); // both-note {{'memmove' not supported: size to copy (1) is not a multiple of size of element type 'int'}} \
1196+
// ref-note {{not supported}}
1197+
return b;
1198+
}
1199+
static_assert(memcpyTypeRem() == 12); // both-error {{not an integral constant expression}} \
1200+
// both-note {{in call to}}
11911201
}

0 commit comments

Comments
 (0)