forked from OSchip/llvm-project
PR11637: implement special-case constant evaluation for char arrays initialized
by string literals. llvm-svn: 147120
This commit is contained in:
parent
4449b21294
commit
ca2cfbf5ce
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue