aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-11 08:41:30 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-11 08:41:30 +0000
commitbb6e73fcf60fa5a4cc36c14744dc366b658443b5 (patch)
treeb7d1eb4dff59d4bfc4cdc805ef2b6c2008f6d01c
parent444eaa83cc2dd7904e4deed82574696b9337de02 (diff)
A DeclRefExpr that refers to a member function or a static data member
of the current instantiation is value-dependent. The C++ standard fails to enumerate this case and, therefore, we missed it. Chandler did all of the hard work of reducing the last remaining Boost.PtrContainer failure (which had to do with static initialization in the Serialization library) down to this simple little test. While I'm at it, clean up the dependence rules for template arguments that are declarations, and implement the dependence rules for template argument packs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103464 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/Expr.cpp17
-rw-r--r--lib/AST/Type.cpp12
-rw-r--r--test/SemaTemplate/instantiate-member-pointers.cpp12
3 files changed, 37 insertions, 4 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 626dbd67f5..5d0269f702 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -156,13 +156,24 @@ void DeclRefExpr::computeDependence() {
// (VD) - a constant with integral or enumeration type and is
// initialized with an expression that is value-dependent.
else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
- if (Var->getType()->isIntegralType() &&
+ if (Var->getType()->isIntegralType() && !Var->isStaticDataMember() &&
Var->getType().getCVRQualifiers() == Qualifiers::Const) {
if (const Expr *Init = Var->getAnyInitializer())
if (Init->isValueDependent())
ValueDependent = true;
- }
- }
+ }
+ // (VD) - FIXME: Missing from the standard:
+ // - a member function or a static data member of the current
+ // instantiation
+ else if (Var->isStaticDataMember() &&
+ Var->getDeclContext()->isDependentContext())
+ ValueDependent = true;
+ }
+ // (VD) - FIXME: Missing from the standard:
+ // - a member function or a static data member of the current
+ // instantiation
+ else if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext())
+ ValueDependent = true;
// (TD) - a nested-name-specifier or a qualified-id that names a
// member of an unknown specialization.
// (handled by DependentScopeDeclRefExpr)
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 05e7fdc49e..73f0e91dab 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -975,6 +975,10 @@ static bool isDependent(const TemplateArgument &Arg) {
return Arg.getAsTemplate().isDependent();
case TemplateArgument::Declaration:
+ if (DeclContext *DC = dyn_cast<DeclContext>(Arg.getAsDecl()))
+ return DC->isDependentContext();
+ return Arg.getAsDecl()->getDeclContext()->isDependentContext();
+
case TemplateArgument::Integral:
// Never dependent
return false;
@@ -984,7 +988,13 @@ static bool isDependent(const TemplateArgument &Arg) {
Arg.getAsExpr()->isValueDependent());
case TemplateArgument::Pack:
- assert(0 && "FIXME: Implement!");
+ for (TemplateArgument::pack_iterator P = Arg.pack_begin(),
+ PEnd = Arg.pack_end();
+ P != PEnd; ++P) {
+ if (isDependent(*P))
+ return true;
+ }
+
return false;
}
diff --git a/test/SemaTemplate/instantiate-member-pointers.cpp b/test/SemaTemplate/instantiate-member-pointers.cpp
index 2308ac541b..dca0f62170 100644
--- a/test/SemaTemplate/instantiate-member-pointers.cpp
+++ b/test/SemaTemplate/instantiate-member-pointers.cpp
@@ -53,3 +53,15 @@ void accept_X4(X4<Member>);
void test_accept_X4(X4<&Y::x> x4) {
accept_X4(x4);
}
+
+namespace ValueDepMemberPointer {
+ template <void (*)()> struct instantiate_function {};
+ template <typename T> struct S {
+ static void instantiate();
+ typedef instantiate_function<&S::instantiate> x; // expected-note{{instantiation}}
+ };
+ template <typename T> void S<T>::instantiate() {
+ int a[(int)sizeof(T)-42]; // expected-error{{array size is negative}}
+ }
+ S<int> s;
+}