[PATCH] D57135: [ExprConstant] Unify handling of array init with lvalues.
Eli Friedman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 23 19:19:18 PST 2019
efriedma created this revision.
efriedma added a reviewer: rsmith.
This should have no functional effect; evaluation is still generating the same result. But the assertions and comments should make it more clear what's actually happening. Part of a fix to https://bugs.llvm.org/show_bug.cgi?id=40430.
It's possible that instead of doing this, we should fix the AST so we don't have "lvalues" which aren't really lvalues.
Repository:
rC Clang
https://reviews.llvm.org/D57135
Files:
lib/AST/ExprConstant.cpp
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -3381,7 +3381,7 @@
return false;
}
APValue Lit;
- if (!Evaluate(Lit, Info, CLE->getInitializer()))
+ if (!EvaluateInPlace(Lit, Info, LVal, CLE->getInitializer()))
return false;
CompleteObject LitObj(&Lit, Base->getType(), false);
return extractSubobject(Info, Conv, LitObj, LVal.Designator, RVal);
@@ -5360,6 +5360,11 @@
return HandleBaseToDerivedCast(Info, E, Result);
}
}
+ bool VisitInitListExpr(const InitListExpr *E) {
+ // Initialization for string literals should go through EvaluateInPlace.
+ assert(!E->isStringLiteralInit());
+ return LValueExprEvaluatorBaseTy::VisitInitListExpr(E);
+ }
};
} // end anonymous namespace
@@ -7182,6 +7187,11 @@
bool VisitCXXConstructExpr(const CXXConstructExpr *E,
const LValue &Subobject,
APValue *Value, QualType Type);
+ bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
+ // Compound literals are always lvalues in C.
+ assert(Info.getLangOpts().CPlusPlus && "Unexpected compound literal");
+ return EvaluateInPlace(Result, Info, This, E->getInitializer());
+ }
};
} // end anonymous namespace
@@ -7212,15 +7222,10 @@
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->isStringLiteralInit()) {
- LValue LV;
- if (!EvaluateLValue(E->getInit(0), LV, Info))
- return false;
- APValue Val;
- LV.moveInto(Val);
- return Success(Val, E);
+ // In C++11 mode, init lists for string literal inits are lvalues.
+ assert(!Info.getLangOpts().CPlusPlus11 && "Unexpected init list");
+ return EvaluateInPlace(Result, Info, This, E->getInit(0));
}
bool Success = true;
@@ -10921,6 +10926,35 @@
}
}
+ if (This.getLValueDesignator().MostDerivedType->isArrayType()) {
+ // We're initializing a value with "lvalue" array. It isn't really
+ // an lvalue, though. There are a few ways to land in this situation,
+ // currently:
+ //
+ // 1. String literal initialization ([dcl.init.string]).
+ // 2. @encode literal initialization (essentially the same as string
+ // literal initialization).
+ // 3. The GNU compound literal initialization extension:
+ // "char x[] = (char[]){0}". (Only allowed in C.)
+ //
+ // Bail out for now if we see a compound literal.
+ if (auto *CLE = dyn_cast<CompoundLiteralExpr>(E->IgnoreParens()))
+ return false;
+ // Otherwise, we have some sort of literal we can evaluate as a
+ // constant array.
+ assert(isa<StringLiteral>(E->IgnoreParens()) ||
+ isa<ObjCEncodeExpr>(E->IgnoreParens()) ||
+ isa<InitListExpr>(E->IgnoreParens()));
+ LValue LV;
+ if (!EvaluateLValue(E, LV, Info))
+ llvm_unreachable("String literal init can't fail");
+
+ // Semantically, we should convert the LValue into an array, but currently
+ // we skip that step, and expect users to convert if necessary.
+ LV.moveInto(Result);
+ return true;
+ }
+
// For any other type, in-place evaluation is unimportant.
return Evaluate(Result, Info, E);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D57135.183232.patch
Type: text/x-patch
Size: 3424 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190124/97943de3/attachment.bin>
More information about the cfe-commits
mailing list