Skip to content

Commit f2b9dec

Browse files
committed
[clang][Interp] Zero-init remaining string literal elements
1 parent 38018ec commit f2b9dec

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -858,8 +858,8 @@ bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) {
858858

859859
// If the initializer string is too long, a diagnostic has already been
860860
// emitted. Read only the array length from the string literal.
861-
unsigned N =
862-
std::min(unsigned(CAT->getSize().getZExtValue()), E->getLength());
861+
unsigned ArraySize = CAT->getSize().getZExtValue();
862+
unsigned N = std::min(ArraySize, E->getLength());
863863
size_t CharWidth = E->getCharByteWidth();
864864

865865
for (unsigned I = 0; I != N; ++I) {
@@ -878,6 +878,23 @@ bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) {
878878
llvm_unreachable("unsupported character width");
879879
}
880880
}
881+
882+
// Fill up the rest of the char array with NUL bytes.
883+
for (unsigned I = N; I != ArraySize; ++I) {
884+
if (CharWidth == 1) {
885+
this->emitConstSint8(0, E);
886+
this->emitInitElemSint8(I, E);
887+
} else if (CharWidth == 2) {
888+
this->emitConstUint16(0, E);
889+
this->emitInitElemUint16(I, E);
890+
} else if (CharWidth == 4) {
891+
this->emitConstUint32(0, E);
892+
this->emitInitElemUint32(I, E);
893+
} else {
894+
llvm_unreachable("unsupported character width");
895+
}
896+
}
897+
881898
return true;
882899
}
883900

clang/test/AST/Interp/arrays.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,3 +371,24 @@ namespace ArrayInitLoop {
371371
// expected-note {{15 == 6}}
372372
#endif
373373
}
374+
375+
namespace StringZeroFill {
376+
struct A {
377+
char c[6];
378+
};
379+
constexpr A a = { "abc" };
380+
static_assert(a.c[0] == 'a', "");
381+
static_assert(a.c[1] == 'b', "");
382+
static_assert(a.c[2] == 'c', "");
383+
static_assert(a.c[3] == '\0', "");
384+
static_assert(a.c[4] == '\0', "");
385+
static_assert(a.c[5] == '\0', "");
386+
387+
constexpr char b[6] = "foo";
388+
static_assert(b[0] == 'f', "");
389+
static_assert(b[1] == 'o', "");
390+
static_assert(b[2] == 'o', "");
391+
static_assert(b[3] == '\0', "");
392+
static_assert(b[4] == '\0', "");
393+
static_assert(b[5] == '\0', "");
394+
}

0 commit comments

Comments
 (0)