[C++11] Fix warning when dropping cv-qualifiers when assigning to a reference with a braced initializer list

llvm-svn: 336922
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 6e695ff..320d93a 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7567,6 +7567,19 @@
   if (!Failed())
     return false;
 
+  // When we want to diagnose only one element of a braced-init-list,
+  // we need to factor it out.
+  Expr *OnlyArg;
+  if (Args.size() == 1) {
+    auto *List = dyn_cast<InitListExpr>(Args[0]);
+    if (List && List->getNumInits() == 1)
+      OnlyArg = List->getInit(0);
+    else
+      OnlyArg = Args[0];
+  }
+  else
+    OnlyArg = nullptr;
+
   QualType DestType = Entity.getType();
   switch (Failure) {
   case FK_TooManyInitsForReference:
@@ -7627,7 +7640,7 @@
               ? diag::err_array_init_different_type
               : diag::err_array_init_non_constant_array))
       << DestType.getNonReferenceType()
-      << Args[0]->getType()
+      << OnlyArg->getType()
       << Args[0]->getSourceRange();
     break;
 
@@ -7638,7 +7651,7 @@
 
   case FK_AddressOfOverloadFailed: {
     DeclAccessPair Found;
-    S.ResolveAddressOfOverloadedFunction(Args[0],
+    S.ResolveAddressOfOverloadedFunction(OnlyArg,
                                          DestType.getNonReferenceType(),
                                          true,
                                          Found);
@@ -7646,9 +7659,9 @@
   }
 
   case FK_AddressOfUnaddressableFunction: {
-    auto *FD = cast<FunctionDecl>(cast<DeclRefExpr>(Args[0])->getDecl());
+    auto *FD = cast<FunctionDecl>(cast<DeclRefExpr>(OnlyArg)->getDecl());
     S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true,
-                                        Args[0]->getLocStart());
+                                        OnlyArg->getLocStart());
     break;
   }
 
@@ -7658,11 +7671,11 @@
     case OR_Ambiguous:
       if (Failure == FK_UserConversionOverloadFailed)
         S.Diag(Kind.getLocation(), diag::err_typecheck_ambiguous_condition)
-          << Args[0]->getType() << DestType
+          << OnlyArg->getType() << DestType
           << Args[0]->getSourceRange();
       else
         S.Diag(Kind.getLocation(), diag::err_ref_init_ambiguous)
-          << DestType << Args[0]->getType()
+          << DestType << OnlyArg->getType()
           << Args[0]->getSourceRange();
 
       FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args);
@@ -7672,10 +7685,10 @@
       if (!S.RequireCompleteType(Kind.getLocation(),
                                  DestType.getNonReferenceType(),
                           diag::err_typecheck_nonviable_condition_incomplete,
-                               Args[0]->getType(), Args[0]->getSourceRange()))
+                               OnlyArg->getType(), Args[0]->getSourceRange()))
         S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
           << (Entity.getKind() == InitializedEntity::EK_Result)
-          << Args[0]->getType() << Args[0]->getSourceRange()
+          << OnlyArg->getType() << Args[0]->getSourceRange()
           << DestType.getNonReferenceType();
 
       FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args);
@@ -7683,7 +7696,7 @@
 
     case OR_Deleted: {
       S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function)
-        << Args[0]->getType() << DestType.getNonReferenceType()
+        << OnlyArg->getType() << DestType.getNonReferenceType()
         << Args[0]->getSourceRange();
       OverloadCandidateSet::iterator Best;
       OverloadingResult Ovl
@@ -7719,7 +7732,7 @@
              : diag::err_lvalue_reference_bind_to_unrelated)
       << DestType.getNonReferenceType().isVolatileQualified()
       << DestType.getNonReferenceType()
-      << Args[0]->getType()
+      << OnlyArg->getType()
       << Args[0]->getSourceRange();
     break;
 
@@ -7744,12 +7757,12 @@
 
   case FK_RValueReferenceBindingToLValue:
     S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref)
-      << DestType.getNonReferenceType() << Args[0]->getType()
+      << DestType.getNonReferenceType() << OnlyArg->getType()
       << Args[0]->getSourceRange();
     break;
 
   case FK_ReferenceInitDropsQualifiers: {
-    QualType SourceType = Args[0]->getType();
+    QualType SourceType = OnlyArg->getType();
     QualType NonRefType = DestType.getNonReferenceType();
     Qualifiers DroppedQualifiers =
         SourceType.getQualifiers() - NonRefType.getQualifiers();
@@ -7765,18 +7778,18 @@
   case FK_ReferenceInitFailed:
     S.Diag(Kind.getLocation(), diag::err_reference_bind_failed)
       << DestType.getNonReferenceType()
-      << Args[0]->isLValue()
-      << Args[0]->getType()
+      << OnlyArg->isLValue()
+      << OnlyArg->getType()
       << Args[0]->getSourceRange();
     emitBadConversionNotes(S, Entity, Args[0]);
     break;
 
   case FK_ConversionFailed: {
-    QualType FromType = Args[0]->getType();
+    QualType FromType = OnlyArg->getType();
     PartialDiagnostic PDiag = S.PDiag(diag::err_init_conversion_failed)
       << (int)Entity.getKind()
       << DestType
-      << Args[0]->isLValue()
+      << OnlyArg->isLValue()
       << FromType
       << Args[0]->getSourceRange();
     S.HandleFunctionTypeMismatch(PDiag, FromType, DestType);