Index: test/FixIt/fixit-function-call.cpp
===================================================================
--- test/FixIt/fixit-function-call.cpp	(revision 0)
+++ test/FixIt/fixit-function-call.cpp	(revision 0)
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fdiagnostics-parseable-fixits -x c++ %s 2> %t  || true > FileCheck %s
+// PR5941
+// END.
+
+/* Test fixits for * and & mismatch in function arguments.
+ * Since fixits are on the notes, they cannot be applied automatically. */
+
+typedef int intTy;
+typedef int intTy2;
+
+void f0(int *a);
+void f1(double *a);
+void f1(intTy &a);
+
+void f2(intTy2 *a) {
+// CHECK: error: no matching function for call to 'f1
+// CHECK: did you miss * or & operator?
+// CHECK: fix-it{{.*}}*(
+// CHECK-NEXT: fix-it{{.*}})
+  f1(a);
+}
+
+void f3(int &a) {
+// CHECK: error: no matching function for call to 'f0
+// CHECK: did you miss * or & operator?
+// CHECK: fix-it{{.*}}&(
+// CHECK-NEXT: fix-it{{.*}})
+  f0(a);
+}
+
+
+void m(int *a, const int *b); // match 2
+void m(double *a, int *b); // no match
+void m(int *a, double *b); // no match
+void m(intTy &a, int *b); // match 1
+
+void mcaller(intTy2 a, int b) {
+// CHECK: error: no matching function for call to 'm
+// CHECK: did you miss * or & operator?
+// CHECK: fix-it{{.*}}&(
+// CHECK: did you miss * or & operators?
+// CHECK: fix-it{{.*}}&(
+// CHECK: fix-it{{.*}}&(
+  m(a, b);
+}
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 135234)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -1593,6 +1593,18 @@
     "constructor (inherited)}0%1"
     " not viable: no known conversion from %2 to %3 for "
     "%select{%ordinal5 argument|object argument}4">;
+def note_ovl_candidate_bad_conv_fixit : Note<"candidate "
+    "%select{function|function|constructor|"
+    "function |function |constructor |"
+    "constructor (the implicit default constructor)|"
+    "constructor (the implicit copy constructor)|"
+    "constructor (the implicit move constructor)|"
+    "function (the implicit copy assignment operator)|"
+    "function (the implicit move assignment operator)|"
+    "constructor (inherited)}0%1"
+    " not viable: no known conversion from %2 to %3 for "
+    "%select{%ordinal5 argument|object argument}4; "
+    "did you miss * or & operator%s6?">;
 def note_ovl_candidate_bad_addrspace : Note<"candidate "
     "%select{function|function|constructor|"
     "function |function |constructor |"
Index: include/clang/Basic/Diagnostic.h
===================================================================
--- include/clang/Basic/Diagnostic.h	(revision 135234)
+++ include/clang/Basic/Diagnostic.h	(working copy)
@@ -614,7 +614,7 @@
   /// only support 10 ranges, could easily be extended if needed.
   CharSourceRange DiagRanges[10];
 
-  enum { MaxFixItHints = 3 };
+  enum { MaxFixItHints = 6 };
 
   /// FixItHints - If valid, provides a hint with some code
   /// to insert, remove, or modify at a particular position.
Index: include/clang/Sema/Overload.h
===================================================================
--- include/clang/Sema/Overload.h	(revision 135234)
+++ include/clang/Sema/Overload.h	(working copy)
@@ -556,6 +556,9 @@
     /// function arguments to the function parameters.
     llvm::SmallVector<ImplicitConversionSequence, 4> Conversions;
 
+    /// If non-empty, these FixIts can be used to fix the Bad candidate.
+    llvm::SmallVector<FixItHint, 4> ConversionFixes;
+
     /// Viable - True to indicate that this overload candidate is viable.
     bool Viable;
 
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp	(revision 135234)
+++ lib/Sema/SemaOverload.cpp	(working copy)
@@ -6730,6 +6730,54 @@
 
 namespace {
 
+/// Update the Hints with FixIts to correct the given conversion. Return true
+/// on success.
+static bool TryToFixBadConversion(const Sema &S,
+                                  const ImplicitConversionSequence &Conv,
+                                  llvm::SmallVector<FixItHint, 4> &Hints) {
+  assert(Conv.isBad());
+  const Expr *Arg = Conv.Bad.FromExpr;
+  if (!Arg)
+    return false;
+
+  // The conversion is from argument type to parameter type.
+  const CanQualType FromQTy = S.Context.getCanonicalType(Conv.Bad
+                                                         .getFromType());
+  const CanQualType ToQTy = S.Context.getCanonicalType(Conv.Bad.getToType());
+
+  const SourceLocation Begin = Arg->getSourceRange().getBegin();
+  const SourceLocation End = S.PP.getLocForEndOfToken(Arg->getSourceRange()
+                                                      .getEnd());
+
+  // Check if the argument needs to be dereferenced
+  // (type * -> type) or (type * -> type &).
+  if (const CanQual<PointerType> FromPtrTy = FromQTy->getAs<PointerType>()) {
+    const CanQualType ToTy = ToQTy.getNonReferenceType();
+    const CanQualType FromTy = FromPtrTy->getPointeeType();
+    if (ToTy.getUnqualifiedType() == FromTy.getUnqualifiedType() &&
+        ToTy.isAtLeastAsQualifiedAs(FromTy)) {
+      Hints.push_back(FixItHint::CreateInsertion(Begin, "*("));
+      Hints.push_back(FixItHint::CreateInsertion(End, ")"));
+      return true;
+    }
+  }
+
+  // Check if the pointer to the argument needs to be passed
+  // (type -> type *) or (type & -> type *).
+  if (const CanQual<PointerType> ToPtrTy = ToQTy->getAs<PointerType>()) {
+    const CanQualType FromTy = FromQTy.getNonReferenceType();
+    const CanQualType ToTy = ToPtrTy->getPointeeType();
+    if (FromTy.getUnqualifiedType() == ToTy.getUnqualifiedType() &&
+        ToTy.isAtLeastAsQualifiedAs(FromTy)) {
+      Hints.push_back(FixItHint::CreateInsertion(Begin, "&("));
+      Hints.push_back(FixItHint::CreateInsertion(End, ")"));
+      return true;
+    }
+  }
+
+  return false;
+}
+
 void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) {
   const ImplicitConversionSequence &Conv = Cand->Conversions[I];
   assert(Conv.isBad());
@@ -6900,6 +6948,23 @@
     return;
   }
 
+  // If we can fix the conversion, suggest the FixIts.
+  if (!Cand->ConversionFixes.empty()) {
+    Sema::SemaDiagnosticBuilder FDiag = S.Diag(Fn->getLocation(),
+                                       diag::note_ovl_candidate_bad_conv_fixit);
+    FDiag << (unsigned) FnKind << FnDesc
+      << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+      << FromTy << ToTy << (unsigned) isObjectArgument << I + 1
+      << (unsigned) (Cand->ConversionFixes.size() == 2);
+    for (llvm::SmallVector<FixItHint, 4>::iterator
+         HI = Cand->ConversionFixes.begin(), HE = Cand->ConversionFixes.end();
+         HI != HE; ++HI)
+      FDiag << *HI;
+    MaybeEmitInheritedConstructorNote(S, Fn);
+    return;
+  }
+
+  // Otherwise, print the generic message.
   // TODO: specialize more based on the kind of mismatch
   S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv)
     << (unsigned) FnKind << FnDesc
@@ -7298,7 +7363,7 @@
 };
 
 /// CompleteNonViableCandidate - Normally, overload resolution only
-/// computes up to the first
+/// computes up to the first. Produces the FixIt set if possible.
 void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
                                 Expr **Args, unsigned NumArgs) {
   assert(!Cand->Viable);
@@ -7306,14 +7371,22 @@
   // Don't do anything on failures other than bad conversion.
   if (Cand->FailureKind != ovl_fail_bad_conversion) return;
 
+  // We only want the FixIts if all the arguments can be corrected.
+  bool Unfixable = false;
+
   // Skip forward to the first bad conversion.
   unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0);
   unsigned ConvCount = Cand->Conversions.size();
   while (true) {
     assert(ConvIdx != ConvCount && "no bad conversion in candidate");
     ConvIdx++;
-    if (Cand->Conversions[ConvIdx - 1].isBad())
+    if (Cand->Conversions[ConvIdx - 1].isBad()) {
+      if ((Unfixable = !TryToFixBadConversion(S, Cand->Conversions[ConvIdx - 1],
+                                                 Cand->ConversionFixes))){
+        Cand->ConversionFixes.clear();
+      }
       break;
+    }
   }
 
   if (ConvIdx == ConvCount)
@@ -7358,16 +7431,24 @@
   // Fill in the rest of the conversions.
   unsigned NumArgsInProto = Proto->getNumArgs();
   for (; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
-    if (ArgIdx < NumArgsInProto)
+    if (ArgIdx < NumArgsInProto) {
       Cand->Conversions[ConvIdx]
         = TryCopyInitialization(S, Args[ArgIdx], Proto->getArgType(ArgIdx),
                                 SuppressUserConversions,
                                 /*InOverloadResolution=*/true,
                                 /*AllowObjCWritebackConversion=*/
                                   S.getLangOptions().ObjCAutoRefCount);
+      // Store the fixit in the candidate if it exists.
+      if (!Unfixable && Cand->Conversions[ConvIdx].isBad())
+        Unfixable = !TryToFixBadConversion(S, Cand->Conversions[ConvIdx],
+                                           Cand->ConversionFixes);
+    }
     else
       Cand->Conversions[ConvIdx].setEllipsis();
   }
+
+  if (Unfixable)
+    Cand->ConversionFixes.clear();
 }
 
 } // end anonymous namespace
