break;
case SK_ConversionSequence:
+ case SK_ConversionSequenceNoNarrowing:
delete ICS;
}
}
}
void InitializationSequence::AddConversionSequenceStep(
- const ImplicitConversionSequence &ICS,
- QualType T) {
+ const ImplicitConversionSequence &ICS, QualType T,
+ bool TopLevelOfInitList) {
Step S;
- S.Kind = SK_ConversionSequence;
+ S.Kind = TopLevelOfInitList ? SK_ConversionSequenceNoNarrowing
+ : SK_ConversionSequence;
S.Type = T;
S.ICS = new ImplicitConversionSequence(ICS);
Steps.push_back(S);
const InitializedEntity &Entity,
const InitializationKind &Kind,
Expr *Initializer,
- InitializationSequence &Sequence) {
+ InitializationSequence &Sequence,
+ bool TopLevelOfInitList) {
QualType DestType = Entity.getType();
assert(!DestType->isReferenceType() && "References are handled elsewhere");
QualType SourceType = Initializer->getType();
ImplicitConversionSequence ICS;
ICS.setStandard();
ICS.Standard = Best->FinalConversion;
- Sequence.AddConversionSequenceStep(ICS, DestType);
+ Sequence.AddConversionSequenceStep(ICS, DestType, TopLevelOfInitList);
}
}
InitializationSequence::InitializationSequence(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
- MultiExprArg Args)
+ MultiExprArg Args,
+ bool TopLevelOfInitList)
: FailedCandidateSet(Kind.getLocation()) {
ASTContext &Context = S.Context;
// 13.3.1.4, and the best one is chosen through overload resolution
// (13.3).
else
- TryUserDefinedConversion(S, Entity, Kind, Initializer, *this);
+ TryUserDefinedConversion(S, Entity, Kind, Initializer, *this,
+ TopLevelOfInitList);
return;
}
// - Otherwise, if the source type is a (possibly cv-qualified) class
// type, conversion functions are considered.
if (!SourceType.isNull() && SourceType->isRecordType()) {
- TryUserDefinedConversion(S, Entity, Kind, Initializer, *this);
+ TryUserDefinedConversion(S, Entity, Kind, Initializer, *this,
+ TopLevelOfInitList);
MaybeProduceObjCObject(S, *this, Entity);
return;
}
else
SetFailed(InitializationSequence::FK_ConversionFailed);
} else {
- AddConversionSequenceStep(ICS, Entity.getType());
+ AddConversionSequenceStep(ICS, Entity.getType(), TopLevelOfInitList);
MaybeProduceObjCObject(S, *this, Entity);
}
}
}
+static void DiagnoseNarrowingInInitList(Sema &S,
+ const ImplicitConversionSequence &ICS,
+ QualType PreNarrowingType,
+ QualType EntityType,
+ const Expr *PostInit);
+
ExprResult
InitializationSequence::Perform(Sema &S,
const InitializedEntity &Entity,
case SK_QualificationConversionRValue:
case SK_LValueToRValue:
case SK_ConversionSequence:
+ case SK_ConversionSequenceNoNarrowing:
case SK_ListInitialization:
case SK_UnwrapInitList:
case SK_RewrapInitList:
break;
}
- case SK_ConversionSequence: {
- Sema::CheckedConversionKind CCK
+ case SK_ConversionSequence:
+ case SK_ConversionSequenceNoNarrowing: {
+ Sema::CheckedConversionKind CCK
= Kind.isCStyleCast()? Sema::CCK_CStyleCast
: Kind.isFunctionalCast()? Sema::CCK_FunctionalCast
: Kind.isExplicitCast()? Sema::CCK_OtherCast
if (CurInitExprRes.isInvalid())
return ExprError();
CurInit = CurInitExprRes;
+
+ if (Step->Kind == SK_ConversionSequenceNoNarrowing &&
+ S.getLangOpts().CPlusPlus && !CurInit.get()->isValueDependent())
+ DiagnoseNarrowingInInitList(S, *Step->ICS, SourceType, Entity.getType(),
+ CurInit.get());
break;
}
OS << ")";
break;
+ case SK_ConversionSequenceNoNarrowing:
+ OS << "implicit conversion sequence with narrowing prohibited (";
+ S->ICS->DebugPrint(); // FIXME: use OS
+ OS << ")";
+ break;
+
case SK_ListInitialization:
OS << "list aggregate initialization";
break;
dump(llvm::errs());
}
-static void DiagnoseNarrowingInInitList(Sema &S, InitializationSequence &Seq,
+static void DiagnoseNarrowingInInitList(Sema &S,
+ const ImplicitConversionSequence &ICS,
+ QualType PreNarrowingType,
QualType EntityType,
- const Expr *PreInit,
const Expr *PostInit) {
- if (Seq.step_begin() == Seq.step_end() || PreInit->isValueDependent())
- return;
-
- // A narrowing conversion can only appear as the final implicit conversion in
- // an initialization sequence.
- const InitializationSequence::Step &LastStep = Seq.step_end()[-1];
- if (LastStep.Kind != InitializationSequence::SK_ConversionSequence)
- return;
-
- const ImplicitConversionSequence &ICS = *LastStep.ICS;
const StandardConversionSequence *SCS = 0;
switch (ICS.getKind()) {
case ImplicitConversionSequence::StandardConversion:
return;
}
- // Determine the type prior to the narrowing conversion. If a conversion
- // operator was used, this may be different from both the type of the entity
- // and of the pre-initialization expression.
- QualType PreNarrowingType = PreInit->getType();
- if (Seq.step_begin() + 1 != Seq.step_end())
- PreNarrowingType = Seq.step_end()[-2].Type;
-
// C++11 [dcl.init.list]p7: Check whether this is a narrowing conversion.
APValue ConstantValue;
QualType ConstantType;
InitializationKind Kind = InitializationKind::CreateCopy(InitE->getLocStart(),
EqualLoc,
AllowExplicit);
- InitializationSequence Seq(*this, Entity, Kind, InitE);
+ InitializationSequence Seq(*this, Entity, Kind, InitE, TopLevelOfInitList);
Init.release();
ExprResult Result = Seq.Perform(*this, Entity, Kind, InitE);
- if (!Result.isInvalid() && TopLevelOfInitList)
- DiagnoseNarrowingInInitList(*this, Seq, Entity.getType(),
- InitE, Result.get());
-
return Result;
}