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

Nicolas Lesser via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 12 10:43:49 PDT 2018


Author: rakete1111
Date: Thu Jul 12 10:43:49 2018
New Revision: 336922

URL: http://llvm.org/viewvc/llvm-project?rev=336922&view=rev
Log:
[C++11] Fix warning when dropping cv-qualifiers when assigning to a reference with a braced initializer list

Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/SemaCXX/references.cpp

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=336922&r1=336921&r2=336922&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Jul 12 10:43:49 2018
@@ -7567,6 +7567,19 @@ bool InitializationSequence::Diagnose(Se
   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 @@ bool InitializationSequence::Diagnose(Se
               ? 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 @@ bool InitializationSequence::Diagnose(Se
 
   case FK_AddressOfOverloadFailed: {
     DeclAccessPair Found;
-    S.ResolveAddressOfOverloadedFunction(Args[0],
+    S.ResolveAddressOfOverloadedFunction(OnlyArg,
                                          DestType.getNonReferenceType(),
                                          true,
                                          Found);
@@ -7646,9 +7659,9 @@ bool InitializationSequence::Diagnose(Se
   }
 
   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 @@ bool InitializationSequence::Diagnose(Se
     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 @@ bool InitializationSequence::Diagnose(Se
       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 @@ bool InitializationSequence::Diagnose(Se
 
     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 @@ bool InitializationSequence::Diagnose(Se
              : 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 @@ bool InitializationSequence::Diagnose(Se
 
   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 @@ bool InitializationSequence::Diagnose(Se
   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);

Modified: cfe/trunk/test/SemaCXX/references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/references.cpp?rev=336922&r1=336921&r2=336922&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/references.cpp (original)
+++ cfe/trunk/test/SemaCXX/references.cpp Thu Jul 12 10:43:49 2018
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 
 int g(int);
 
 void f() {
@@ -55,6 +56,24 @@ void test5() {
   //  const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
   const volatile int cvi = 1;
   const int& r = cvi; // expected-error{{binding value of type 'const volatile int' to reference to type 'const int' drops 'volatile' qualifier}}
+
+#if __cplusplus >= 201103L
+  const int& r2{cvi}; // expected-error{{binding value of type 'const volatile int' to reference to type 'const int' drops 'volatile' qualifier}}
+
+  const int a = 2;
+  int& r3{a}; // expected-error{{binding value of type 'const int' to reference to type 'int' drops 'const'}}
+
+  const int&& r4{a}; // expected-error{{rvalue reference to type 'const int' cannot bind to lvalue of type 'const int'}}
+
+  void func();
+  void func(int);
+  int &ptr1 = {func}; // expected-error{{address of overloaded function 'func' does not match required type 'int'}}
+  int &&ptr2{func}; // expected-error{{address of overloaded function 'func' does not match required type 'int'}}
+  // expected-note at -4{{candidate function}}
+  // expected-note at -4{{candidate function}}
+  // expected-note at -6{{candidate function}}
+  // expected-note at -6{{candidate function}}
+#endif
 }
 
 // C++ [dcl.init.ref]p3




More information about the cfe-commits mailing list