r191146 - Rearrange narrowing checks in initialization to be a different form of step
Richard Smith
richard-llvm at metafoo.co.uk
Sat Sep 21 14:19:19 PDT 2013
Author: rsmith
Date: Sat Sep 21 16:19:19 2013
New Revision: 191146
URL: http://llvm.org/viewvc/llvm-project?rev=191146&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Sema/Initialization.h
cfe/trunk/lib/Sema/SemaInit.cpp
Modified: cfe/trunk/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=191146&r1=191145&r2=191146&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Initialization.h (original)
+++ cfe/trunk/include/clang/Sema/Initialization.h Sat Sep 21 16:19:19 2013
@@ -652,6 +652,8 @@ public:
SK_LValueToRValue,
/// \brief Perform an implicit conversion sequence.
SK_ConversionSequence,
+ /// \brief Perform an implicit conversion sequence without narrowing.
+ SK_ConversionSequenceNoNarrowing,
/// \brief Perform list-initialization without a constructor
SK_ListInitialization,
/// \brief Perform list-initialization with a constructor.
@@ -840,11 +842,15 @@ public:
/// \param Kind the kind of initialization being performed.
///
/// \param Args the argument(s) provided for initialization.
+ ///
+ /// \param InInitList true if we are initializing from an expression within
+ /// an initializer list. This disallows narrowing conversions in C++11
+ /// onwards.
InitializationSequence(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
- MultiExprArg Args);
-
+ MultiExprArg Args,
+ bool InInitList = false);
~InitializationSequence();
/// \brief Perform the actual initialization of the given entity based on
@@ -979,7 +985,7 @@ public:
/// \brief Add a new step that applies an implicit conversion sequence.
void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
- QualType T);
+ QualType T, bool TopLevelOfInitList = false);
/// \brief Add a list-initialization step.
void AddListInitializationStep(QualType T);
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=191146&r1=191145&r2=191146&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sat Sep 21 16:19:19 2013
@@ -2643,6 +2643,7 @@ void InitializationSequence::Step::Destr
break;
case SK_ConversionSequence:
+ case SK_ConversionSequenceNoNarrowing:
delete ICS;
}
}
@@ -2782,10 +2783,11 @@ void InitializationSequence::AddLValueTo
}
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(Sem
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(Sem
ImplicitConversionSequence ICS;
ICS.setStandard();
ICS.Standard = Best->FinalConversion;
- Sequence.AddConversionSequenceStep(ICS, DestType);
+ Sequence.AddConversionSequenceStep(ICS, DestType, TopLevelOfInitList);
}
}
@@ -4353,7 +4356,8 @@ static bool TryOCLZeroEventInitializatio
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::InitializationSe
// 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::InitializationSe
// - 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::InitializationSe
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
}
}
+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_os
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() cons
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(
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 In
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;
}
More information about the cfe-commits
mailing list