aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-12-22 05:24:09 +0000
committerAnders Carlsson <andersca@mac.com>2009-12-22 05:24:09 +0000
commit1f24032ea28d0df9d6227e4faf89306dfa990994 (patch)
tree838d94a8afa98f2365db350f634c7053124dc296
parentbba48cbd77ff5168b32efa9b77845d45f9205e48 (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.h7
-rw-r--r--test/SemaTemplate/instantiate-member-expr.cpp27
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}}
+}