]> granicus.if.org Git - clang/commitdiff
Pass the current SourceLocation to getAssignOperatorMethod, fixing a crash when the...
authorAnders Carlsson <andersca@mac.com>
Wed, 9 Dec 2009 03:01:51 +0000 (03:01 +0000)
committerAnders Carlsson <andersca@mac.com>
Wed, 9 Dec 2009 03:01:51 +0000 (03:01 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90935 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/default-assignment-operator.cpp
test/SemaTemplate/instantiate-default-assignment-operator.cpp [new file with mode: 0644]

index a7eb0c6d8855d7841ad1791947a532980e7a6645..d176e8b697a677e4559e45557abec127466b281c 100644 (file)
@@ -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
index 3a3bf3e9c18853614693ba5cf97effa46f8ffbc3..6f8a4f16d3bd7bbd6005207c6c136c041e5d1dca 100644 (file)
@@ -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");
index e627fefdef6ddefb0991cdbb90d20efa3e0e6bcd..0377657a82d24e198c884ffc79675211b9a2e5c4 100644 (file)
@@ -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 {{synthesized method is first required here}}
   x = cx;
   z1 = z2;
 }
diff --git a/test/SemaTemplate/instantiate-default-assignment-operator.cpp b/test/SemaTemplate/instantiate-default-assignment-operator.cpp
new file mode 100644 (file)
index 0000000..b0ac078
--- /dev/null
@@ -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}}
+}