diff options
author | Anders Carlsson <andersca@mac.com> | 2009-12-22 05:24:09 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-12-22 05:24:09 +0000 |
commit | 1f24032ea28d0df9d6227e4faf89306dfa990994 (patch) | |
tree | 838d94a8afa98f2365db350f634c7053124dc296 | |
parent | bba48cbd77ff5168b32efa9b77845d45f9205e48 (diff) |
When we simply return a retained member expression when instantiating, we must also mark the member decl as referenced.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91887 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/TreeTransform.h | 7 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-member-expr.cpp | 27 |
2 files changed, 33 insertions, 1 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 03169bf380..8c84d4a95a 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -3688,8 +3688,13 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { Base.get() == E->getBase() && Qualifier == E->getQualifier() && Member == E->getMemberDecl() && - !E->hasExplicitTemplateArgumentList()) + !E->hasExplicitTemplateArgumentList()) { + + // Mark it referenced in the new context regardless. + // FIXME: this is a bit instantiation-specific. + SemaRef.MarkDeclarationReferenced(E->getMemberLoc(), Member); return SemaRef.Owned(E->Retain()); + } TemplateArgumentListInfo TransArgs; if (E->hasExplicitTemplateArgumentList()) { diff --git a/test/SemaTemplate/instantiate-member-expr.cpp b/test/SemaTemplate/instantiate-member-expr.cpp new file mode 100644 index 0000000000..db13624d44 --- /dev/null +++ b/test/SemaTemplate/instantiate-member-expr.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +template<typename T> +struct S { + S() { } +}; + +template<typename T> +struct vector { + void push_back(const T&) { int a[sizeof(T) ? -1: -1]; } // expected-error {{array size is negative}} +}; + +class GRExprEngine { +public: + typedef vector<S<void *> >CheckersOrdered; + CheckersOrdered Checkers; + + template <typename CHECKER> + void registerCheck(CHECKER *check) { + Checkers.push_back(S<void *>()); // expected-note {{in instantiation of member function 'vector<struct S<void *> >::push_back' requested here}} + } +}; + +class RetainReleaseChecker { }; + +void f(GRExprEngine& Eng) { + Eng.registerCheck(new RetainReleaseChecker); // expected-note {{in instantiation of function template specialization 'GRExprEngine::registerCheck<class RetainReleaseChecker>' requested here}} +} |