summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-09-21 21:19:19 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-09-21 21:19:19 +0000
commitaaa0ec45fe0dafedf73944db349118481a94e000 (patch)
treeb1e8df60fced0eb8c4a0124f0b529a28830e19ab /clang/lib/Sema/SemaInit.cpp
parent7a828034c6cb65b846b8f7b18d730dd109f65b9e (diff)
downloadbcm5719-llvm-aaa0ec45fe0dafedf73944db349118481a94e000.tar.gz
bcm5719-llvm-aaa0ec45fe0dafedf73944db349118481a94e000.zip
Rearrange narrowing checks in initialization to be a different form of step
rather than a post-processing action, so we can support inserting these checks at stages other than the end of the initialization. No functionality change intended. llvm-svn: 191146
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r--clang/lib/Sema/SemaInit.cpp75
1 files changed, 40 insertions, 35 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 5319f404f39..baf81006593 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2643,6 +2643,7 @@ void InitializationSequence::Step::Destroy() {
break;
case SK_ConversionSequence:
+ case SK_ConversionSequenceNoNarrowing:
delete ICS;
}
}
@@ -2782,10 +2783,11 @@ void InitializationSequence::AddLValueToRValueStep(QualType Ty) {
}
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);
@@ -3991,7 +3993,8 @@ static void TryUserDefinedConversion(Sema &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();
@@ -4142,7 +4145,7 @@ static void TryUserDefinedConversion(Sema &S,
ImplicitConversionSequence ICS;
ICS.setStandard();
ICS.Standard = Best->FinalConversion;
- Sequence.AddConversionSequenceStep(ICS, DestType);
+ Sequence.AddConversionSequenceStep(ICS, DestType, TopLevelOfInitList);
}
}
@@ -4353,7 +4356,8 @@ static bool TryOCLZeroEventInitialization(Sema &S,
InitializationSequence::InitializationSequence(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
- MultiExprArg Args)
+ MultiExprArg Args,
+ bool TopLevelOfInitList)
: FailedCandidateSet(Kind.getLocation()) {
ASTContext &Context = S.Context;
@@ -4544,7 +4548,8 @@ InitializationSequence::InitializationSequence(Sema &S,
// 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;
}
@@ -4557,7 +4562,8 @@ InitializationSequence::InitializationSequence(Sema &S,
// - 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;
}
@@ -4609,7 +4615,7 @@ InitializationSequence::InitializationSequence(Sema &S,
else
SetFailed(InitializationSequence::FK_ConversionFailed);
} else {
- AddConversionSequenceStep(ICS, Entity.getType());
+ AddConversionSequenceStep(ICS, Entity.getType(), TopLevelOfInitList);
MaybeProduceObjCObject(S, *this, Entity);
}
@@ -5438,6 +5444,12 @@ static void warnOnLifetimeExtension(Sema &S, const InitializedEntity &Entity,
}
}
+static void DiagnoseNarrowingInInitList(Sema &S,
+ const ImplicitConversionSequence &ICS,
+ QualType PreNarrowingType,
+ QualType EntityType,
+ const Expr *PostInit);
+
ExprResult
InitializationSequence::Perform(Sema &S,
const InitializedEntity &Entity,
@@ -5555,6 +5567,7 @@ InitializationSequence::Perform(Sema &S,
case SK_QualificationConversionRValue:
case SK_LValueToRValue:
case SK_ConversionSequence:
+ case SK_ConversionSequenceNoNarrowing:
case SK_ListInitialization:
case SK_UnwrapInitList:
case SK_RewrapInitList:
@@ -5853,8 +5866,9 @@ InitializationSequence::Perform(Sema &S,
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
@@ -5865,6 +5879,11 @@ InitializationSequence::Perform(Sema &S,
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;
}
@@ -6780,6 +6799,12 @@ void InitializationSequence::dump(raw_ostream &OS) const {
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;
@@ -6859,20 +6884,11 @@ void InitializationSequence::dump() const {
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:
@@ -6887,13 +6903,6 @@ static void DiagnoseNarrowingInInitList(Sema &S, InitializationSequence &Seq,
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;
@@ -7006,14 +7015,10 @@ Sema::PerformCopyInitialization(const InitializedEntity &Entity,
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;
}
OpenPOWER on IntegriCloud