From 4c88e719ddaa64ea71ece335250b69e4142a74ee Mon Sep 17 00:00:00 2001 From: Mikhail Maltsev Date: Wed, 14 Feb 2018 11:34:25 +0000 Subject: [PATCH] [Sema] Fix decltype of static data members Summary: 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. Reviewers: faisalv, rsmith, rogfer01 Reviewed By: rogfer01 Subscribers: rogfer01, cfe-commits Differential Revision: https://reviews.llvm.org/D42969 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325117 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaType.cpp | 5 +++-- .../dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 8f3b359fde..e323b31f8e 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -7868,8 +7868,9 @@ static QualType getDecltypeForExpr(Sema &S, Expr *E) { if (const ValueDecl *VD = dyn_cast(DRE->getDecl())) return VD->getType(); } else if (const MemberExpr *ME = dyn_cast(E)) { - if (const FieldDecl *FD = dyn_cast(ME->getMemberDecl())) - return FD->getType(); + if (const ValueDecl *VD = ME->getMemberDecl()) + if (isa(VD) || isa(VD)) + return VD->getType(); } else if (const ObjCIvarRefExpr *IR = dyn_cast(E)) { return IR->getDecl()->getType(); } else if (const ObjCPropertyRefExpr *PR = dyn_cast(E)) { diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp index 53227ea37c..ee952aeaf0 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p4-cxx0x.cpp @@ -12,13 +12,18 @@ struct is_same { 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::value, ""); static_assert(is_same::value, ""); static_assert(is_samex), double>::value, ""); static_assert(is_samex)), const double&>::value, ""); +static_assert(is_samey), int>::value, ""); +static_assert(is_samey)), int&>::value, ""); static_assert(is_same(i)), int&&>::value, ""); int f0(int); // expected-note{{possible target}} -- 2.40.0