]> granicus.if.org Git - clang/commitdiff
DR1213: Ignore implicit conversions when determining if an operand of an
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 27 Jun 2018 20:29:32 +0000 (20:29 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 27 Jun 2018 20:29:32 +0000 (20:29 +0000)
array subscript expression is an array prvalue.

Also apply DR1213 to vector prvalues for consistency.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@335779 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/CXX/drs/dr12xx.cpp

index 88059e9466723816d616b32b6f7aa0d116f93cff..74f84862e6ddbe5180e45adffcd13910e5984381 100644 (file)
@@ -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;
index 24039a1cd240399b01e87ccf4b1b44898e121320..1bc4c397344355b4446ebde676ce6e41d76471ef 100644 (file)
@@ -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
 }