[PATCH] D107275: [Sema] a[x] has type T when a has type T* or T[], even when T is dependent

Sam McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 2 06:56:15 PDT 2021


sammccall created this revision.
sammccall added reviewers: kadircet, rsmith.
Herald added a subscriber: usaxena95.
sammccall requested review of this revision.
Herald added subscribers: cfe-commits, ilya-biryukov.
Herald added a project: clang.

This more precise type is useful for tools, e.g.
fixes https://github.com/clangd/clangd/issues/831


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D107275

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/AST/ast-dump-array.cpp


Index: clang/test/AST/ast-dump-array.cpp
===================================================================
--- clang/test/AST/ast-dump-array.cpp
+++ clang/test/AST/ast-dump-array.cpp
@@ -25,3 +25,32 @@
   // CHECK: `-DependentSizedArrayType 0x{{[^ ]*}} 'T [Size]' dependent   <col:25, col:30>
 };
 
+template <typename U, typename Idx>
+void testDependentSubscript() {
+  U* a;
+  U b[5];
+  Idx i{};
+
+  // Can types of subscript expressions can be determined?
+  // LHS is a type-dependent array
+  a[1];
+  // CHECK: ArraySubscriptExpr {{.*}} 'U' lvalue
+  b[1];
+  // CHECK: ArraySubscriptExpr {{.*}} 'U' lvalue
+
+  // LHS is a type-dependent array, RHS is type-dependent.
+  a[i];
+  // CHECK: ArraySubscriptExpr {{.*}} 'U' lvalue
+  b[i];
+  // CHECK: ArraySubscriptExpr {{.*}} 'U' lvalue
+
+  struct V;
+  V *a2;
+  V b2[5];
+
+  // LHS is a known array, RHS is type-dependent.
+  a2[i];
+  // CHECK: ArraySubscriptExpr {{.*}} 'V' lvalue
+  b2[i];
+  // CHECK: ArraySubscriptExpr {{.*}} 'V' lvalue
+};
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -4785,8 +4785,17 @@
   // Build an unanalyzed expression if either operand is type-dependent.
   if (getLangOpts().CPlusPlus &&
       (base->isTypeDependent() || idx->isTypeDependent())) {
-    return new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy,
-                                            VK_LValue, OK_Ordinary, rbLoc);
+    QualType Type = Context.DependentTy;
+    // Refine type if LHS is an array or pointer.
+    // This is safe because overloading is not possible in this case, and
+    // arrays/pointers can't be the index of of a builtin subscript.
+    // Don't bother for RHS, that case is very rare.
+    if (const PointerType *PT = base->getType()->getAs<PointerType>())
+      Type = PT->getPointeeType();
+    else if (const ArrayType *AT = base->getType()->getAsArrayTypeUnsafe())
+      Type = AT->getElementType();
+    return new (Context)
+        ArraySubscriptExpr(base, idx, Type, VK_LValue, OK_Ordinary, rbLoc);
   }
 
   // MSDN, property (C++)
@@ -5541,6 +5550,13 @@
     BaseExpr = LHSExp;
     IndexExpr = RHSExp;
     ResultType = Context.DependentTy;
+    // One of LHS and RHS must be pointer, the other must be array.
+    // We don't know in general, but determine a more specific type if we can.
+    // Don't bother for the uncommon case where the index is on the left.
+    if (const PointerType *PT = LHSTy->getAs<PointerType>())
+      ResultType = PT->getPointeeType();
+    else if (const ArrayType *AT = LHSTy->getAsArrayTypeUnsafe())
+      ResultType = AT->getElementType();
   } else if (const PointerType *PTy = LHSTy->getAs<PointerType>()) {
     BaseExpr = LHSExp;
     IndexExpr = RHSExp;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D107275.363469.patch
Type: text/x-patch
Size: 2844 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210802/dfb45fe9/attachment-0001.bin>


More information about the cfe-commits mailing list