Skip to content

Commit

Permalink
[clang][Interp] Zero-init remaining string literal elements (#66862)
Browse files Browse the repository at this point in the history
  • Loading branch information
tbaederr committed Sep 30, 2023
1 parent 11fbbcb commit 4909e7c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
21 changes: 19 additions & 2 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -881,8 +881,8 @@ bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) {

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

for (unsigned I = 0; I != N; ++I) {
Expand All @@ -901,6 +901,23 @@ bool ByteCodeExprGen<Emitter>::VisitStringLiteral(const StringLiteral *E) {
llvm_unreachable("unsupported character width");
}
}

// Fill up the rest of the char array with NUL bytes.
for (unsigned I = N; I != ArraySize; ++I) {
if (CharWidth == 1) {
this->emitConstSint8(0, E);
this->emitInitElemSint8(I, E);
} else if (CharWidth == 2) {
this->emitConstUint16(0, E);
this->emitInitElemUint16(I, E);
} else if (CharWidth == 4) {
this->emitConstUint32(0, E);
this->emitInitElemUint32(I, E);
} else {
llvm_unreachable("unsupported character width");
}
}

return true;
}

Expand Down
21 changes: 21 additions & 0 deletions clang/test/AST/Interp/arrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,24 @@ namespace ArrayInitLoop {
static_assert(g() == 6); // expected-error {{failed}} \
// expected-note {{15 == 6}}
}

namespace StringZeroFill {
struct A {
char c[6];
};
constexpr A a = { "abc" };
static_assert(a.c[0] == 'a', "");
static_assert(a.c[1] == 'b', "");
static_assert(a.c[2] == 'c', "");
static_assert(a.c[3] == '\0', "");
static_assert(a.c[4] == '\0', "");
static_assert(a.c[5] == '\0', "");

constexpr char b[6] = "foo";
static_assert(b[0] == 'f', "");
static_assert(b[1] == 'o', "");
static_assert(b[2] == 'o', "");
static_assert(b[3] == '\0', "");
static_assert(b[4] == '\0', "");
static_assert(b[5] == '\0', "");
}

0 comments on commit 4909e7c

Please sign in to comment.