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)) {
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)) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits