diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-05 07:49:14 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-05 07:49:14 +0000 |
commit | b3189a1802e493fd819b766c2051bda04f18617c (patch) | |
tree | f2f4135e179e717581ffdc0ad34d708376db62bd /clang/lib/Sema/SemaExpr.cpp | |
parent | 215ff84b4082bea94dbf065d5fbac3cdd7f69516 (diff) | |
download | bcm5719-llvm-b3189a1802e493fd819b766c2051bda04f18617c.tar.gz bcm5719-llvm-b3189a1802e493fd819b766c2051bda04f18617c.zip |
DR1213: element access on an array xvalue or prvalue produces an xvalue. In the
latter case, a temporary array object is materialized, and can be
lifetime-extended by binding a reference to the member access. Likewise, in an
array-to-pointer decay, an rvalue array is materialized before being converted
into a pointer.
This caused IR generation to stop treating file-scope array compound literals
as having static storage duration in some cases in C++; that has been rectified
by modeling such a compound literal as an lvalue. This also improves clang's
compatibility with GCC for those cases.
llvm-svn: 288654
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4415100ab45..5182e164538 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4376,6 +4376,16 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *LHSExp = Base; Expr *RHSExp = Idx; + ExprValueKind VK = VK_LValue; + ExprObjectKind OK = OK_Ordinary; + + // Per C++ core issue 1213, the result is an xvalue if either operand is + // a non-lvalue array, and an lvalue otherwise. + if (getLangOpts().CPlusPlus11 && + ((LHSExp->getType()->isArrayType() && !LHSExp->isLValue()) || + (RHSExp->getType()->isArrayType() && !RHSExp->isLValue()))) + VK = VK_XValue; + // Perform default conversions. if (!LHSExp->getType()->getAs<VectorType>()) { ExprResult Result = DefaultFunctionArrayLvalueConversion(LHSExp); @@ -4389,8 +4399,6 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, RHSExp = Result.get(); QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType(); - ExprValueKind VK = VK_LValue; - ExprObjectKind OK = OK_Ordinary; // C99 6.5.2.1p2: the expression e1[e2] is by definition precisely equivalent // to the expression *((e1)+(e2)). This means the array "Base" may actually be @@ -5587,11 +5595,31 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, } // In C, compound literals are l-values for some reason. - ExprValueKind VK = getLangOpts().CPlusPlus ? VK_RValue : VK_LValue; + // For GCC compatibility, in C++, file-scope array compound literals with + // constant initializers are also l-values, and compound literals are + // otherwise prvalues. + // + // (GCC also treats C++ list-initialized file-scope array prvalues with + // constant initializers as l-values, but that's non-conforming, so we don't + // follow it there.) + // + // FIXME: It would be better to handle the lvalue cases as materializing and + // lifetime-extending a temporary object, but our materialized temporaries + // representation only supports lifetime extension from a variable, not "out + // of thin air". + // FIXME: For C++, we might want to instead lifetime-extend only if a pointer + // is bound to the result of applying array-to-pointer decay to the compound + // literal. + // FIXME: GCC supports compound literals of reference type, which should + // obviously have a value kind derived from the kind of reference involved. + ExprValueKind VK = + (getLangOpts().CPlusPlus && !(isFileScope && literalType->isArrayType())) + ? VK_RValue + : VK_LValue; return MaybeBindToTemporary( - new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, - VK, LiteralExpr, isFileScope)); + new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, + VK, LiteralExpr, isFileScope)); } ExprResult |