PR11637: implement special-case constant evaluation for char arrays initialized

by string literals.

llvm-svn: 147120
This commit is contained in:
Richard Smith 2011-12-22 01:07:19 +00:00
parent 4449b21294
commit ca2cfbf5ce
2 changed files with 40 additions and 0 deletions

View File

@ -3084,6 +3084,32 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
if (!CAT)
return Error(E);
// C++11 [dcl.init.string]p1: A char array [...] can be initialized by [...]
// an appropriately-typed string literal enclosed in braces.
if (E->getNumInits() == 1 && CAT->getElementType()->isAnyCharacterType() &&
Info.Ctx.hasSameUnqualifiedType(E->getType(), E->getInit(0)->getType())) {
LValue LV;
if (!EvaluateLValue(E->getInit(0), LV, Info))
return false;
uint64_t NumElements = CAT->getSize().getZExtValue();
Result = APValue(APValue::UninitArray(), NumElements, NumElements);
// Copy the string literal into the array. FIXME: Do this better.
LV.Designator.addIndex(0);
for (uint64_t I = 0; I < NumElements; ++I) {
CCValue Char;
if (!HandleLValueToRValueConversion(Info, E->getInit(0),
CAT->getElementType(), LV, Char))
return false;
if (!CheckConstantExpression(Info, E->getInit(0), Char,
Result.getArrayInitializedElt(I)))
return false;
if (!HandleLValueArrayAdjustment(Info, LV, CAT->getElementType(), 1))
return false;
}
return true;
}
Result = APValue(APValue::UninitArray(), E->getNumInits(),
CAT->getSize().getZExtValue());
LValue Subobject = This;

View File

@ -391,6 +391,20 @@ struct S {
int n : "foo"[4]; // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
};
struct T {
char c[6];
constexpr T() : c{"foo"} {}
};
constexpr T t;
static_assert(t.c[0] == 'f', "");
static_assert(t.c[1] == 'o', "");
static_assert(t.c[2] == 'o', "");
static_assert(t.c[3] == 0, "");
static_assert(t.c[4] == 0, "");
static_assert(t.c[5] == 0, "");
static_assert(t.c[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
}
namespace Array {