From 84393619eb09be1516b52b09efb6ac30ee63d625 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Sun, 8 Apr 2018 05:11:59 +0000 Subject: [PATCH] [Sema] Fix PR22637 - IndirectFieldDecl's discard qualifiers during template instantiation. Summary: Currently Clang fails to propagate qualifiers from the `CXXThisExpr` to the rebuilt `FieldDecl` for IndirectFieldDecls. For example: ``` template struct Foo { struct { int x; }; int y; void foo() const { static_assert(__is_same(int const&, decltype((y)))); static_assert(__is_same(int const&, decltype((x)))); // assertion fails } }; template struct Foo; ``` The fix is to delegate rebuilding of the MemberExpr to `BuildFieldReferenceExpr` which correctly propagates the qualifiers. Reviewers: rsmith, lebedev.ri, aaron.ballman, bkramer, rjmccall Reviewed By: rjmccall Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D45412 llvm-svn: 329517 --- clang/lib/Sema/TreeTransform.h | 10 +++---- clang/test/SemaCXX/PR22637.cpp | 40 +++++++++++++++++++++++++++ clang/test/SemaCXX/cxx0x-nontrivial-union.cpp | 2 +- 3 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 clang/test/SemaCXX/PR22637.cpp diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index cab1b19..1a35c9d 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2250,11 +2250,11 @@ public: if (BaseResult.isInvalid()) return ExprError(); Base = BaseResult.get(); - ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind(); - MemberExpr *ME = new (getSema().Context) - MemberExpr(Base, isArrow, OpLoc, Member, MemberNameInfo, - cast(Member)->getType(), VK, OK_Ordinary); - return ME; + + CXXScopeSpec EmptySS; + return getSema().BuildFieldReferenceExpr( + Base, isArrow, OpLoc, EmptySS, cast(Member), + DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()), MemberNameInfo); } CXXScopeSpec SS; diff --git a/clang/test/SemaCXX/PR22637.cpp b/clang/test/SemaCXX/PR22637.cpp new file mode 100644 index 0000000..1a9bf1d --- /dev/null +++ b/clang/test/SemaCXX/PR22637.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// expected-no-diagnostics + +void check(int&) = delete; +void check(int const&) { } + +template +struct A { + union { + int b; + }; + struct { + int c; + }; + union { + struct { + union { + struct { + struct { + int d; + }; + }; + }; + }; + }; + int e; + void foo() const { + check(b); + check(c); + check(d); + check(d); + check(e); + } +}; + +int main(){ + A a; + a.foo(); +} diff --git a/clang/test/SemaCXX/cxx0x-nontrivial-union.cpp b/clang/test/SemaCXX/cxx0x-nontrivial-union.cpp index db296bd..f092776 100644 --- a/clang/test/SemaCXX/cxx0x-nontrivial-union.cpp +++ b/clang/test/SemaCXX/cxx0x-nontrivial-union.cpp @@ -110,7 +110,7 @@ namespace optional { } explicit operator bool() const { return has; } - T &operator*() const { return value; } + T &operator*() { return value; } }; optional o1; -- 2.7.4