From 9b31df4acdeeb61bb084a03fc37bc5bd570a659e Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Thu, 9 Jul 2009 00:05:08 +0000 Subject: [PATCH] Store the isAddressOfOperand in the UnresolvedDeclRefExpr, so that we can pass it when instantiating the expr. Fixes another member pointer bug. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75075 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprCXX.h | 12 ++++++++++-- lib/Sema/SemaExpr.cpp | 3 ++- lib/Sema/SemaTemplateInstantiateExpr.cpp | 2 +- test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp | 8 +++++++- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 7d76a49d12..6956e58c82 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -985,11 +985,16 @@ class UnresolvedDeclRefExpr : public Expr { /// declaration name. NestedNameSpecifier *NNS; + /// \brief Whether this expr is an address of (&) operand. + bool IsAddressOfOperand; + public: UnresolvedDeclRefExpr(DeclarationName N, QualType T, SourceLocation L, - SourceRange R, NestedNameSpecifier *NNS) + SourceRange R, NestedNameSpecifier *NNS, + bool IsAddressOfOperand) : Expr(UnresolvedDeclRefExprClass, T, true, true), - Name(N), Loc(L), QualifierRange(R), NNS(NNS) { } + Name(N), Loc(L), QualifierRange(R), NNS(NNS), + IsAddressOfOperand(IsAddressOfOperand) { } /// \brief Retrieve the name that this expression refers to. DeclarationName getDeclName() const { return Name; } @@ -1004,6 +1009,9 @@ public: /// declaration. NestedNameSpecifier *getQualifier() const { return NNS; } + /// \brief Retrieve whether this is an address of (&) operand. + + bool isAddressOfOperand() const { return IsAddressOfOperand; } virtual SourceRange getSourceRange() const { return SourceRange(QualifierRange.getBegin(), getLocation()); } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index df7e5afb17..820c1775ae 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -849,7 +849,8 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, if (SS && isDependentScopeSpecifier(*SS)) { return Owned(new (Context) UnresolvedDeclRefExpr(Name, Context.DependentTy, Loc, SS->getRange(), - static_cast(SS->getScopeRep()))); + static_cast(SS->getScopeRep()), + isAddressOfOperand)); } LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName, diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp index c82e1a7da3..5e664add5c 100644 --- a/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -798,7 +798,7 @@ TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) { E->getDeclName(), /*HasTrailingLParen=*/false, &SS, - /*FIXME:isAddressOfOperand=*/false); + E->isAddressOfOperand()); } Sema::OwningExprResult diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp index ee3cbeae4e..101d75fc0f 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp @@ -8,13 +8,19 @@ public: static int s; }; +template void ft(T& t) { + t.*&T::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}} +} + void f() { int b; A a(b); int A::*ip = &A::s; // expected-error {{incompatible type initializing 'int *', expected 'int class A::*'}} a.*&A::s = 10; // expected-error{{right hand operand to .* has non pointer-to-member type 'int *'}} + a.*&A::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}} - + ft(a); // expected-note{{in instantiation of function template specialization 'ft' requested here}} + void A::*p = 0; // expected-error{{'p' declared as a member pointer to void}} } -- 2.40.0