forked from OSchip/llvm-project
[C++11] Fix warning when dropping cv-qualifiers when assigning to a reference with a braced initializer list
llvm-svn: 336922
This commit is contained in:
parent
e8c3c5fe5d
commit
8217a2ab4f
|
@ -7567,6 +7567,19 @@ bool InitializationSequence::Diagnose(Sema &S,
|
|||
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(Sema &S,
|
|||
? 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(Sema &S,
|
|||
|
||||
case FK_AddressOfOverloadFailed: {
|
||||
DeclAccessPair Found;
|
||||
S.ResolveAddressOfOverloadedFunction(Args[0],
|
||||
S.ResolveAddressOfOverloadedFunction(OnlyArg,
|
||||
DestType.getNonReferenceType(),
|
||||
true,
|
||||
Found);
|
||||
|
@ -7646,9 +7659,9 @@ bool InitializationSequence::Diagnose(Sema &S,
|
|||
}
|
||||
|
||||
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(Sema &S,
|
|||
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(Sema &S,
|
|||
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(Sema &S,
|
|||
|
||||
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(Sema &S,
|
|||
: 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(Sema &S,
|
|||
|
||||
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(Sema &S,
|
|||
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);
|
||||
|
|
|
@ -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@-4{{candidate function}}
|
||||
// expected-note@-4{{candidate function}}
|
||||
// expected-note@-6{{candidate function}}
|
||||
// expected-note@-6{{candidate function}}
|
||||
#endif
|
||||
}
|
||||
|
||||
// C++ [dcl.init.ref]p3
|
||||
|
|
Loading…
Reference in New Issue