forked from OSchip/llvm-project
DR1213: Ignore implicit conversions when determining if an operand of an
array subscript expression is an array prvalue. Also apply DR1213 to vector prvalues for consistency. llvm-svn: 335779
This commit is contained in:
parent
1ef49be8b6
commit
becac9eb56
|
@ -4385,10 +4385,13 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
|
|||
|
||||
// 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;
|
||||
if (getLangOpts().CPlusPlus11) {
|
||||
for (auto *Op : {LHSExp, RHSExp}) {
|
||||
Op = Op->IgnoreImplicit();
|
||||
if (Op->getType()->isArrayType() && !Op->isLValue())
|
||||
VK = VK_XValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform default conversions.
|
||||
if (!LHSExp->getType()->getAs<VectorType>()) {
|
||||
|
@ -4449,6 +4452,13 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
|
|||
} else if (const VectorType *VTy = LHSTy->getAs<VectorType>()) {
|
||||
BaseExpr = LHSExp; // vectors: V[123]
|
||||
IndexExpr = RHSExp;
|
||||
// We apply C++ DR1213 to vector subscripting too.
|
||||
if (getLangOpts().CPlusPlus11 && LHSExp->getValueKind() == VK_RValue) {
|
||||
ExprResult Materialized = TemporaryMaterializationConversion(LHSExp);
|
||||
if (Materialized.isInvalid())
|
||||
return ExprError();
|
||||
LHSExp = Materialized.get();
|
||||
}
|
||||
VK = LHSExp->getValueKind();
|
||||
if (VK != VK_RValue)
|
||||
OK = OK_VectorComponent;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
||||
// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
||||
|
||||
namespace dr1213 { // dr1213: 4
|
||||
namespace dr1213 { // dr1213: 7
|
||||
#if __cplusplus >= 201103L
|
||||
using T = int[3];
|
||||
int &&r = T{}[1];
|
||||
|
@ -11,6 +11,19 @@ namespace dr1213 { // dr1213: 4
|
|||
using T = decltype((T{}));
|
||||
using U = decltype((T{}[2]));
|
||||
using U = int &&;
|
||||
|
||||
// Same thing but in a case where we consider overloaded operator[].
|
||||
struct ConvertsToInt {
|
||||
operator int();
|
||||
};
|
||||
struct X { int array[1]; };
|
||||
using U = decltype(X().array[ConvertsToInt()]);
|
||||
|
||||
// We apply the same rule to vector subscripting.
|
||||
typedef int V4Int __attribute__((__vector_size__(sizeof(int) * 4)));
|
||||
typedef int EV4Int __attribute__((__ext_vector_type__(4)));
|
||||
using U = decltype(V4Int()[0]);
|
||||
using U = decltype(EV4Int()[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue