forked from OSchip/llvm-project
Pass the current SourceLocation to getAssignOperatorMethod, fixing a crash when the assign operator method needs to be instantiated. Doug, please review the updated default-assignment-operator.cpp change.
llvm-svn: 90935
This commit is contained in:
parent
0d886ca091
commit
efa4732747
|
@ -1831,7 +1831,8 @@ public:
|
|||
|
||||
/// getAssignOperatorMethod - Returns the default copy assignmment operator
|
||||
/// for the class.
|
||||
CXXMethodDecl *getAssignOperatorMethod(ParmVarDecl *Decl,
|
||||
CXXMethodDecl *getAssignOperatorMethod(SourceLocation CurrentLocation,
|
||||
ParmVarDecl *Decl,
|
||||
CXXRecordDecl *ClassDecl);
|
||||
|
||||
/// MaybeBindToTemporary - If the passed in expression has a record type with
|
||||
|
|
|
@ -3387,7 +3387,8 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
|
|||
CXXRecordDecl *BaseClassDecl
|
||||
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
|
||||
if (CXXMethodDecl *BaseAssignOpMethod =
|
||||
getAssignOperatorMethod(MethodDecl->getParamDecl(0), BaseClassDecl))
|
||||
getAssignOperatorMethod(CurrentLocation, MethodDecl->getParamDecl(0),
|
||||
BaseClassDecl))
|
||||
MarkDeclarationReferenced(CurrentLocation, BaseAssignOpMethod);
|
||||
}
|
||||
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
|
||||
|
@ -3399,7 +3400,8 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
|
|||
CXXRecordDecl *FieldClassDecl
|
||||
= cast<CXXRecordDecl>(FieldClassType->getDecl());
|
||||
if (CXXMethodDecl *FieldAssignOpMethod =
|
||||
getAssignOperatorMethod(MethodDecl->getParamDecl(0), FieldClassDecl))
|
||||
getAssignOperatorMethod(CurrentLocation, MethodDecl->getParamDecl(0),
|
||||
FieldClassDecl))
|
||||
MarkDeclarationReferenced(CurrentLocation, FieldAssignOpMethod);
|
||||
} else if (FieldType->isReferenceType()) {
|
||||
Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
|
||||
|
@ -3420,7 +3422,8 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
|
|||
}
|
||||
|
||||
CXXMethodDecl *
|
||||
Sema::getAssignOperatorMethod(ParmVarDecl *ParmDecl,
|
||||
Sema::getAssignOperatorMethod(SourceLocation CurrentLocation,
|
||||
ParmVarDecl *ParmDecl,
|
||||
CXXRecordDecl *ClassDecl) {
|
||||
QualType LHSType = Context.getTypeDeclType(ClassDecl);
|
||||
QualType RHSType(LHSType);
|
||||
|
@ -3430,18 +3433,17 @@ Sema::getAssignOperatorMethod(ParmVarDecl *ParmDecl,
|
|||
RHSType = Context.getCVRQualifiedType(RHSType,
|
||||
ParmDecl->getType().getCVRQualifiers());
|
||||
ExprOwningPtr<Expr> LHS(this, new (Context) DeclRefExpr(ParmDecl,
|
||||
LHSType,
|
||||
SourceLocation()));
|
||||
LHSType,
|
||||
SourceLocation()));
|
||||
ExprOwningPtr<Expr> RHS(this, new (Context) DeclRefExpr(ParmDecl,
|
||||
RHSType,
|
||||
SourceLocation()));
|
||||
RHSType,
|
||||
CurrentLocation));
|
||||
Expr *Args[2] = { &*LHS, &*RHS };
|
||||
OverloadCandidateSet CandidateSet;
|
||||
AddMemberOperatorCandidates(clang::OO_Equal, SourceLocation(), Args, 2,
|
||||
CandidateSet);
|
||||
OverloadCandidateSet::iterator Best;
|
||||
if (BestViableFunction(CandidateSet,
|
||||
ClassDecl->getLocation(), Best) == OR_Success)
|
||||
if (BestViableFunction(CandidateSet, CurrentLocation, Best) == OR_Success)
|
||||
return cast<CXXMethodDecl>(Best->Function);
|
||||
assert(false &&
|
||||
"getAssignOperatorMethod - copy assignment operator method not found");
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
class Base { // expected-error {{cannot define the implicit default assignment operator for 'class Base'}} \
|
||||
// expected-note {{synthesized method is first required here}}
|
||||
class Base { // expected-error {{cannot define the implicit default assignment operator for 'class Base'}}
|
||||
int &ref; // expected-note {{declared at}}
|
||||
};
|
||||
|
||||
|
@ -26,7 +25,7 @@ Z z2;
|
|||
|
||||
// Test1
|
||||
void f(X x, const X cx) {
|
||||
x = cx; // expected-note {{synthesized method is first required here}}
|
||||
x = cx; // expected-note 2 {{synthesized method is first required here}}
|
||||
x = cx;
|
||||
z1 = z2;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
template<typename> struct PassRefPtr { };
|
||||
template<typename T> struct RefPtr {
|
||||
RefPtr& operator=(const RefPtr&) { int a[sizeof(T) ? -1 : -1];} // expected-error 2 {{array size is negative}}
|
||||
RefPtr& operator=(const PassRefPtr<T>&);
|
||||
};
|
||||
|
||||
struct A { RefPtr<int> a; };
|
||||
struct B : RefPtr<float> { };
|
||||
|
||||
void f() {
|
||||
A a1, a2;
|
||||
a1 = a2; // expected-note {{instantiation of member function 'RefPtr<int>::operator=' requested here}}
|
||||
|
||||
B b1, b2;
|
||||
b1 = b2; // expected-note {{in instantiation of member function 'RefPtr<float>::operator=' requested here}}
|
||||
}
|
Loading…
Reference in New Issue