Bugfix in template instantiation in CXXPseudoDestructorExpr.

Fix for clang crash when instantiating a template with qualified lookup for members in non-class types.
Differential Revision: http://reviews.llvm.org/D5769

llvm-svn: 219897
This commit is contained in:
Alexey Bataev 2014-10-16 03:04:35 +00:00
parent 275746d768
commit 2a06681133
2 changed files with 49 additions and 4 deletions

View File

@ -10510,9 +10510,16 @@ TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
// The scope type is now known to be a valid nested name specifier
// component. Tack it on to the end of the nested name specifier.
if (ScopeType)
SS.Extend(SemaRef.Context, SourceLocation(),
ScopeType->getTypeLoc(), CCLoc);
if (ScopeType) {
if (!ScopeType->getType()->getAs<TagType>()) {
getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
diag::err_expected_class_or_namespace)
<< ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
return ExprError();
}
SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(),
CCLoc);
}
SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
return getSema().BuildMemberReferenceExpr(Base, BaseType,

View File

@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
template<typename T>
struct X1 {
static void member() { T* x = 1; } // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
@ -11,4 +12,41 @@ struct X2 {
typedef instantiate<&X1<int>::member> i; // expected-note{{in instantiation of}}
};
X2<int> x;
X2<int> x;
template <class T, class A> class C {
public:
int i;
void f(T &t) {
T *q = new T();
t.T::~T();
q->~T();
// expected-error@+2 {{'int' is not a class, namespace, or scoped enumeration}}
// expected-error@+1 {{no member named '~Colors' in 'Colors'}}
q->A::~A();
// expected-error@+2 {{no member named '~int' in 'Q'}}
// expected-error@+1 {{no member named '~Colors' in 'Q'}}
q->~A();
delete q;
}
};
class Q {
public:
Q() {}
~Q() {}
};
enum Colors {red, green, blue};
C<Q, int> dummy;
C<Q, Colors> dummyColors;
int main() {
Q qinst;
// expected-note@+1 {{in instantiation of member function 'C<Q, int>::f' requested here}}
dummy.f(qinst);
// expected-note@+1 {{in instantiation of member function 'C<Q, Colors>::f' requested here}}
dummyColors.f(qinst);
}