[PATCH] D42969: [Sema] Fix decltype of static data members

Mikhail Maltsev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 6 07:43:39 PST 2018


miyuki created this revision.
miyuki added reviewers: faisalv, rsmith.
miyuki edited the summary of this revision.

According to the C++11 standard [dcl.type.simple]p4:

  The type denoted by decltype(e) is defined as follows:
  - if e is an unparenthesized id-expression or an unparenthesized
    class member access (5.2.5), decltype(e) is the type of the entity
    named by e.
    

Currently Clang handles the 'member access' case incorrectly for
static data members (decltype returns T& instead of T). This patch
fixes the issue.


https://reviews.llvm.org/D42969

Files:
  lib/Sema/SemaType.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp


Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
===================================================================
--- test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
+++ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp
@@ -12,13 +12,18 @@
 
 const int&& foo();
 int i;
-struct A { double x; };
+struct A {
+  double x;
+  static int y;
+};
 const A* a = new A();
 
 static_assert(is_same<decltype(foo()), const int&&>::value, "");
 static_assert(is_same<decltype(i), int>::value, "");
 static_assert(is_same<decltype(a->x), double>::value, "");
 static_assert(is_same<decltype((a->x)), const double&>::value, "");
+static_assert(is_same<decltype(a->y), int>::value, "");
+static_assert(is_same<decltype((a->y)), int&>::value, "");
 static_assert(is_same<decltype(static_cast<int&&>(i)), int&&>::value, "");
 
 int f0(int); // expected-note{{possible target}}
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -7859,8 +7859,9 @@
     if (const ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl()))
       return VD->getType();
   } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
-    if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
-      return FD->getType();
+    if (const ValueDecl *VD = ME->getMemberDecl())
+      if (isa<FieldDecl>(VD) || isa<VarDecl>(VD))
+        return VD->getType();
   } else if (const ObjCIvarRefExpr *IR = dyn_cast<ObjCIvarRefExpr>(E)) {
     return IR->getDecl()->getType();
   } else if (const ObjCPropertyRefExpr *PR = dyn_cast<ObjCPropertyRefExpr>(E)) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42969.133001.patch
Type: text/x-patch
Size: 1677 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180206/570c9866/attachment-0001.bin>


More information about the cfe-commits mailing list