зеркало из https://github.com/microsoft/clang-1.git
Change the way we store initialization kinds so that all direct inits can distinguish between list and parens form. This allows us to correctly diagnose the last test cases from litb.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150343 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
168319c81b
Коммит
3a45c0e61d
|
@ -334,30 +334,27 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// \brief The kind of initialization that we're storing.
|
/// \brief The context of the initialization.
|
||||||
enum StoredInitKind {
|
enum InitContext {
|
||||||
SIK_Direct = IK_Direct, ///< Direct initialization
|
IC_Normal, ///< Normal context
|
||||||
SIK_DirectList = IK_DirectList, ///< Direct list-initialization
|
IC_Implicit, ///< Implicit context (value initialization)
|
||||||
SIK_Copy = IK_Copy, ///< Copy initialization
|
IC_StaticCast, ///< Static cast context
|
||||||
SIK_Default = IK_Default, ///< Default initialization
|
IC_CStyleCast, ///< C-style cast context
|
||||||
SIK_Value = IK_Value, ///< Value initialization
|
IC_FunctionalCast ///< Functional cast context
|
||||||
SIK_ImplicitValue, ///< Implicit value initialization
|
|
||||||
SIK_DirectCast, ///< Direct initialization due to a cast
|
|
||||||
/// \brief Direct initialization due to a C-style cast.
|
|
||||||
SIK_DirectCStyleCast,
|
|
||||||
/// \brief Direct initialization due to a functional-style cast.
|
|
||||||
SIK_DirectFunctionalCast
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief The kind of initialization being performed.
|
/// \brief The kind of initialization being performed.
|
||||||
StoredInitKind Kind;
|
InitKind Kind : 8;
|
||||||
|
|
||||||
|
/// \brief The context of the initialization.
|
||||||
|
InitContext Context : 8;
|
||||||
|
|
||||||
/// \brief The source locations involved in the initialization.
|
/// \brief The source locations involved in the initialization.
|
||||||
SourceLocation Locations[3];
|
SourceLocation Locations[3];
|
||||||
|
|
||||||
InitializationKind(StoredInitKind Kind, SourceLocation Loc1,
|
InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1,
|
||||||
SourceLocation Loc2, SourceLocation Loc3)
|
SourceLocation Loc2, SourceLocation Loc3)
|
||||||
: Kind(Kind)
|
: Kind(Kind), Context(Context)
|
||||||
{
|
{
|
||||||
Locations[0] = Loc1;
|
Locations[0] = Loc1;
|
||||||
Locations[1] = Loc2;
|
Locations[1] = Loc2;
|
||||||
|
@ -369,45 +366,50 @@ public:
|
||||||
static InitializationKind CreateDirect(SourceLocation InitLoc,
|
static InitializationKind CreateDirect(SourceLocation InitLoc,
|
||||||
SourceLocation LParenLoc,
|
SourceLocation LParenLoc,
|
||||||
SourceLocation RParenLoc) {
|
SourceLocation RParenLoc) {
|
||||||
return InitializationKind(SIK_Direct, InitLoc, LParenLoc, RParenLoc);
|
return InitializationKind(IK_Direct, IC_Normal,
|
||||||
|
InitLoc, LParenLoc, RParenLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static InitializationKind CreateDirectList(SourceLocation InitLoc) {
|
static InitializationKind CreateDirectList(SourceLocation InitLoc) {
|
||||||
return InitializationKind(SIK_DirectList, InitLoc, InitLoc, InitLoc);
|
return InitializationKind(IK_DirectList, IC_Normal,
|
||||||
|
InitLoc, InitLoc, InitLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Create a direct initialization due to a cast that isn't a C-style
|
/// \brief Create a direct initialization due to a cast that isn't a C-style
|
||||||
/// or functional cast.
|
/// or functional cast.
|
||||||
static InitializationKind CreateCast(SourceRange TypeRange) {
|
static InitializationKind CreateCast(SourceRange TypeRange) {
|
||||||
return InitializationKind(SIK_DirectCast,
|
return InitializationKind(IK_Direct, IC_StaticCast, TypeRange.getBegin(),
|
||||||
TypeRange.getBegin(), TypeRange.getBegin(),
|
TypeRange.getBegin(), TypeRange.getEnd());
|
||||||
TypeRange.getEnd());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Create a direct initialization for a C-style cast.
|
/// \brief Create a direct initialization for a C-style cast.
|
||||||
static InitializationKind CreateCStyleCast(SourceLocation StartLoc,
|
static InitializationKind CreateCStyleCast(SourceLocation StartLoc,
|
||||||
SourceRange TypeRange) {
|
SourceRange TypeRange,
|
||||||
return InitializationKind(SIK_DirectCStyleCast,
|
bool InitList) {
|
||||||
StartLoc, TypeRange.getBegin(),
|
// C++ cast syntax doesn't permit init lists, but C compound literals are
|
||||||
|
// exactly that.
|
||||||
|
return InitializationKind(InitList ? IK_DirectList : IK_Direct,
|
||||||
|
IC_CStyleCast, StartLoc, TypeRange.getBegin(),
|
||||||
TypeRange.getEnd());
|
TypeRange.getEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Create a direct initialization for a functional cast.
|
/// \brief Create a direct initialization for a functional cast.
|
||||||
static InitializationKind CreateFunctionalCast(SourceRange TypeRange) {
|
static InitializationKind CreateFunctionalCast(SourceRange TypeRange,
|
||||||
return InitializationKind(SIK_DirectFunctionalCast,
|
bool InitList) {
|
||||||
TypeRange.getBegin(), TypeRange.getBegin(),
|
return InitializationKind(InitList ? IK_DirectList : IK_Direct,
|
||||||
TypeRange.getEnd());
|
IC_FunctionalCast, TypeRange.getBegin(),
|
||||||
|
TypeRange.getBegin(), TypeRange.getEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Create a copy initialization.
|
/// \brief Create a copy initialization.
|
||||||
static InitializationKind CreateCopy(SourceLocation InitLoc,
|
static InitializationKind CreateCopy(SourceLocation InitLoc,
|
||||||
SourceLocation EqualLoc) {
|
SourceLocation EqualLoc) {
|
||||||
return InitializationKind(SIK_Copy, InitLoc, EqualLoc, EqualLoc);
|
return InitializationKind(IK_Copy, IC_Normal, InitLoc, EqualLoc, EqualLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Create a default initialization.
|
/// \brief Create a default initialization.
|
||||||
static InitializationKind CreateDefault(SourceLocation InitLoc) {
|
static InitializationKind CreateDefault(SourceLocation InitLoc) {
|
||||||
return InitializationKind(SIK_Default, InitLoc, InitLoc, InitLoc);
|
return InitializationKind(IK_Default, IC_Normal, InitLoc, InitLoc, InitLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Create a value initialization.
|
/// \brief Create a value initialization.
|
||||||
|
@ -415,46 +417,39 @@ public:
|
||||||
SourceLocation LParenLoc,
|
SourceLocation LParenLoc,
|
||||||
SourceLocation RParenLoc,
|
SourceLocation RParenLoc,
|
||||||
bool isImplicit = false) {
|
bool isImplicit = false) {
|
||||||
return InitializationKind(isImplicit? SIK_ImplicitValue : SIK_Value,
|
return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal,
|
||||||
InitLoc, LParenLoc, RParenLoc);
|
InitLoc, LParenLoc, RParenLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Determine the initialization kind.
|
/// \brief Determine the initialization kind.
|
||||||
InitKind getKind() const {
|
InitKind getKind() const {
|
||||||
if (Kind > SIK_ImplicitValue)
|
return Kind;
|
||||||
return IK_Direct;
|
|
||||||
if (Kind == SIK_ImplicitValue)
|
|
||||||
return IK_Value;
|
|
||||||
|
|
||||||
return (InitKind)Kind;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Determine whether this initialization is an explicit cast.
|
/// \brief Determine whether this initialization is an explicit cast.
|
||||||
bool isExplicitCast() const {
|
bool isExplicitCast() const {
|
||||||
return Kind == SIK_DirectCast ||
|
return Context >= IC_StaticCast;
|
||||||
Kind == SIK_DirectCStyleCast ||
|
|
||||||
Kind == SIK_DirectFunctionalCast;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Determine whether this initialization is a C-style cast.
|
/// \brief Determine whether this initialization is a C-style cast.
|
||||||
bool isCStyleOrFunctionalCast() const {
|
bool isCStyleOrFunctionalCast() const {
|
||||||
return Kind == SIK_DirectCStyleCast || Kind == SIK_DirectFunctionalCast;
|
return Context >= IC_CStyleCast;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// brief Determine whether this is a C-style cast.
|
/// \brief Determine whether this is a C-style cast.
|
||||||
bool isCStyleCast() const {
|
bool isCStyleCast() const {
|
||||||
return Kind == SIK_DirectCStyleCast;
|
return Context == IC_CStyleCast;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// brief Determine whether this is a functional-style cast.
|
/// \brief Determine whether this is a functional-style cast.
|
||||||
bool isFunctionalCast() const {
|
bool isFunctionalCast() const {
|
||||||
return Kind == SIK_DirectFunctionalCast;
|
return Context == IC_FunctionalCast;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Determine whether this initialization is an implicit
|
/// \brief Determine whether this initialization is an implicit
|
||||||
/// value-initialization, e.g., as occurs during aggregate
|
/// value-initialization, e.g., as occurs during aggregate
|
||||||
/// initialization.
|
/// initialization.
|
||||||
bool isImplicitValueInit() const { return Kind == SIK_ImplicitValue; }
|
bool isImplicitValueInit() const { return Context == IC_Implicit; }
|
||||||
|
|
||||||
/// \brief Retrieve the location at which initialization is occurring.
|
/// \brief Retrieve the location at which initialization is occurring.
|
||||||
SourceLocation getLocation() const { return Locations[0]; }
|
SourceLocation getLocation() const { return Locations[0]; }
|
||||||
|
@ -467,11 +462,11 @@ public:
|
||||||
/// \brief Retrieve the location of the equal sign for copy initialization
|
/// \brief Retrieve the location of the equal sign for copy initialization
|
||||||
/// (if present).
|
/// (if present).
|
||||||
SourceLocation getEqualLoc() const {
|
SourceLocation getEqualLoc() const {
|
||||||
assert(Kind == SIK_Copy && "Only copy initialization has an '='");
|
assert(Kind == IK_Copy && "Only copy initialization has an '='");
|
||||||
return Locations[1];
|
return Locations[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isCopyInit() const { return Kind == SIK_Copy; }
|
bool isCopyInit() const { return Kind == IK_Copy; }
|
||||||
|
|
||||||
/// \brief Retrieve whether this initialization allows the use of explicit
|
/// \brief Retrieve whether this initialization allows the use of explicit
|
||||||
/// constructors.
|
/// constructors.
|
||||||
|
@ -480,7 +475,7 @@ public:
|
||||||
/// \brief Retrieve the source range containing the locations of the open
|
/// \brief Retrieve the source range containing the locations of the open
|
||||||
/// and closing parentheses for value and direct initializations.
|
/// and closing parentheses for value and direct initializations.
|
||||||
SourceRange getParenRange() const {
|
SourceRange getParenRange() const {
|
||||||
assert((getKind() == IK_Direct || Kind == SIK_Value) &&
|
assert((Kind == IK_Direct || Kind == IK_Value) &&
|
||||||
"Only direct- and value-initialization have parentheses");
|
"Only direct- and value-initialization have parentheses");
|
||||||
return SourceRange(Locations[1], Locations[2]);
|
return SourceRange(Locations[1], Locations[2]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,11 +320,13 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,
|
||||||
if (!destType->isRecordType() && !srcType->isRecordType())
|
if (!destType->isRecordType() && !srcType->isRecordType())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
bool initList = isa<InitListExpr>(src);
|
||||||
InitializedEntity entity = InitializedEntity::InitializeTemporary(destType);
|
InitializedEntity entity = InitializedEntity::InitializeTemporary(destType);
|
||||||
InitializationKind initKind
|
InitializationKind initKind
|
||||||
= (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(),
|
= (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(),
|
||||||
range)
|
range, initList)
|
||||||
: (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range)
|
: (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range,
|
||||||
|
initList)
|
||||||
: InitializationKind::CreateCast(/*type range?*/ range);
|
: InitializationKind::CreateCast(/*type range?*/ range);
|
||||||
InitializationSequence sequence(S, entity, initKind, &src, 1);
|
InitializationSequence sequence(S, entity, initKind, &src, 1);
|
||||||
|
|
||||||
|
@ -1302,12 +1304,15 @@ TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: doesn't correctly identify T({1})
|
||||||
|
bool InitList = isa<InitListExpr>(SrcExpr.get());
|
||||||
InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
|
InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
|
||||||
InitializationKind InitKind
|
InitializationKind InitKind
|
||||||
= (CCK == Sema::CCK_CStyleCast)
|
= (CCK == Sema::CCK_CStyleCast)
|
||||||
? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange)
|
? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange,
|
||||||
|
InitList)
|
||||||
: (CCK == Sema::CCK_FunctionalCast)
|
: (CCK == Sema::CCK_FunctionalCast)
|
||||||
? InitializationKind::CreateFunctionalCast(OpRange)
|
? InitializationKind::CreateFunctionalCast(OpRange, InitList)
|
||||||
: InitializationKind::CreateCast(OpRange);
|
: InitializationKind::CreateCast(OpRange);
|
||||||
Expr *SrcExprRaw = SrcExpr.get();
|
Expr *SrcExprRaw = SrcExpr.get();
|
||||||
InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExprRaw, 1);
|
InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExprRaw, 1);
|
||||||
|
|
|
@ -2150,18 +2150,22 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init,
|
||||||
// any of the arguments are type-dependent expressions.
|
// any of the arguments are type-dependent expressions.
|
||||||
DiscardCleanupsInEvaluationContext();
|
DiscardCleanupsInEvaluationContext();
|
||||||
} else {
|
} else {
|
||||||
|
bool InitList = false;
|
||||||
|
if (isa<InitListExpr>(Init)) {
|
||||||
|
InitList = true;
|
||||||
|
Args = &Init;
|
||||||
|
NumArgs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the member.
|
// Initialize the member.
|
||||||
InitializedEntity MemberEntity =
|
InitializedEntity MemberEntity =
|
||||||
DirectMember ? InitializedEntity::InitializeMember(DirectMember, 0)
|
DirectMember ? InitializedEntity::InitializeMember(DirectMember, 0)
|
||||||
: InitializedEntity::InitializeMember(IndirectMember, 0);
|
: InitializedEntity::InitializeMember(IndirectMember, 0);
|
||||||
InitializationKind Kind =
|
InitializationKind Kind =
|
||||||
InitializationKind::CreateDirect(IdLoc, InitRange.getBegin(),
|
InitList ? InitializationKind::CreateDirectList(IdLoc)
|
||||||
|
: InitializationKind::CreateDirect(IdLoc, InitRange.getBegin(),
|
||||||
InitRange.getEnd());
|
InitRange.getEnd());
|
||||||
|
|
||||||
if (isa<InitListExpr>(Init)) {
|
|
||||||
Args = &Init;
|
|
||||||
NumArgs = 1;
|
|
||||||
}
|
|
||||||
InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
|
InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
|
||||||
ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind,
|
ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind,
|
||||||
MultiExprArg(*this, Args, NumArgs),
|
MultiExprArg(*this, Args, NumArgs),
|
||||||
|
@ -2214,20 +2218,23 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init,
|
||||||
<< TInfo->getTypeLoc().getLocalSourceRange();
|
<< TInfo->getTypeLoc().getLocalSourceRange();
|
||||||
Diag(NameLoc, diag::warn_cxx98_compat_delegating_ctor);
|
Diag(NameLoc, diag::warn_cxx98_compat_delegating_ctor);
|
||||||
|
|
||||||
|
bool InitList = true;
|
||||||
|
Expr **Args = &Init;
|
||||||
|
unsigned NumArgs = 1;
|
||||||
|
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
|
||||||
|
InitList = false;
|
||||||
|
Args = ParenList->getExprs();
|
||||||
|
NumArgs = ParenList->getNumExprs();
|
||||||
|
}
|
||||||
|
|
||||||
SourceRange InitRange = Init->getSourceRange();
|
SourceRange InitRange = Init->getSourceRange();
|
||||||
// Initialize the object.
|
// Initialize the object.
|
||||||
InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation(
|
InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation(
|
||||||
QualType(ClassDecl->getTypeForDecl(), 0));
|
QualType(ClassDecl->getTypeForDecl(), 0));
|
||||||
InitializationKind Kind =
|
InitializationKind Kind =
|
||||||
InitializationKind::CreateDirect(NameLoc, InitRange.getBegin(),
|
InitList ? InitializationKind::CreateDirectList(NameLoc)
|
||||||
|
: InitializationKind::CreateDirect(NameLoc, InitRange.getBegin(),
|
||||||
InitRange.getEnd());
|
InitRange.getEnd());
|
||||||
|
|
||||||
Expr **Args = &Init;
|
|
||||||
unsigned NumArgs = 1;
|
|
||||||
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
|
|
||||||
Args = ParenList->getExprs();
|
|
||||||
NumArgs = ParenList->getNumExprs();
|
|
||||||
}
|
|
||||||
InitializationSequence InitSeq(*this, DelegationEntity, Kind, Args, NumArgs);
|
InitializationSequence InitSeq(*this, DelegationEntity, Kind, Args, NumArgs);
|
||||||
ExprResult DelegationInit = InitSeq.Perform(*this, DelegationEntity, Kind,
|
ExprResult DelegationInit = InitSeq.Perform(*this, DelegationEntity, Kind,
|
||||||
MultiExprArg(*this, Args,NumArgs),
|
MultiExprArg(*this, Args,NumArgs),
|
||||||
|
@ -2341,18 +2348,21 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
|
||||||
BaseSpec = const_cast<CXXBaseSpecifier *>(VirtualBaseSpec);
|
BaseSpec = const_cast<CXXBaseSpecifier *>(VirtualBaseSpec);
|
||||||
|
|
||||||
// Initialize the base.
|
// Initialize the base.
|
||||||
InitializedEntity BaseEntity =
|
bool InitList = true;
|
||||||
InitializedEntity::InitializeBase(Context, BaseSpec, VirtualBaseSpec);
|
|
||||||
InitializationKind Kind =
|
|
||||||
InitializationKind::CreateDirect(BaseLoc, InitRange.getBegin(),
|
|
||||||
InitRange.getEnd());
|
|
||||||
|
|
||||||
Expr **Args = &Init;
|
Expr **Args = &Init;
|
||||||
unsigned NumArgs = 1;
|
unsigned NumArgs = 1;
|
||||||
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
|
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
|
||||||
|
InitList = false;
|
||||||
Args = ParenList->getExprs();
|
Args = ParenList->getExprs();
|
||||||
NumArgs = ParenList->getNumExprs();
|
NumArgs = ParenList->getNumExprs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitializedEntity BaseEntity =
|
||||||
|
InitializedEntity::InitializeBase(Context, BaseSpec, VirtualBaseSpec);
|
||||||
|
InitializationKind Kind =
|
||||||
|
InitList ? InitializationKind::CreateDirectList(BaseLoc)
|
||||||
|
: InitializationKind::CreateDirect(BaseLoc, InitRange.getBegin(),
|
||||||
|
InitRange.getEnd());
|
||||||
InitializationSequence InitSeq(*this, BaseEntity, Kind, Args, NumArgs);
|
InitializationSequence InitSeq(*this, BaseEntity, Kind, Args, NumArgs);
|
||||||
ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind,
|
ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind,
|
||||||
MultiExprArg(*this, Args, NumArgs),
|
MultiExprArg(*this, Args, NumArgs),
|
||||||
|
|
|
@ -3809,7 +3809,8 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
|
||||||
= InitializedEntity::InitializeTemporary(literalType);
|
= InitializedEntity::InitializeTemporary(literalType);
|
||||||
InitializationKind Kind
|
InitializationKind Kind
|
||||||
= InitializationKind::CreateCStyleCast(LParenLoc,
|
= InitializationKind::CreateCStyleCast(LParenLoc,
|
||||||
SourceRange(LParenLoc, RParenLoc));
|
SourceRange(LParenLoc, RParenLoc),
|
||||||
|
/*InitList=*/true);
|
||||||
InitializationSequence InitSeq(*this, Entity, Kind, &LiteralExpr, 1);
|
InitializationSequence InitSeq(*this, Entity, Kind, &LiteralExpr, 1);
|
||||||
ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
|
ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
|
||||||
MultiExprArg(*this, &LiteralExpr, 1),
|
MultiExprArg(*this, &LiteralExpr, 1),
|
||||||
|
|
|
@ -3970,12 +3970,14 @@ InitializationSequence::InitializationSequence(Sema &S,
|
||||||
SourceType = Initializer->getType();
|
SourceType = Initializer->getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - If the initializer is a braced-init-list, the object is
|
// - If the initializer is a (non-parenthesized) braced-init-list, the
|
||||||
// list-initialized (8.5.4).
|
// object is list-initialized (8.5.4).
|
||||||
|
if (Kind.getKind() != InitializationKind::IK_Direct) {
|
||||||
if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
|
if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
|
||||||
TryListInitialization(S, Entity, Kind, InitList, *this);
|
TryListInitialization(S, Entity, Kind, InitList, *this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// - If the destination type is a reference type, see 8.5.3.
|
// - If the destination type is a reference type, see 8.5.3.
|
||||||
if (DestType->isReferenceType()) {
|
if (DestType->isReferenceType()) {
|
||||||
|
|
|
@ -56,4 +56,6 @@ namespace aggregate {
|
||||||
// String is not default-constructible
|
// String is not default-constructible
|
||||||
static_assert(sizeof(overloaded({1})) == sizeof(one), "bad overload");
|
static_assert(sizeof(overloaded({1})) == sizeof(one), "bad overload");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct C { int a[2]; C():a({1, 2}) { } }; // expected-error {{array initializer must be an initializer list}}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,4 +71,9 @@ namespace reference {
|
||||||
static_assert(sizeof(h({1, 2})) == sizeof(two), "bad overload resolution");
|
static_assert(sizeof(h({1, 2})) == sizeof(two), "bad overload resolution");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void edge_cases() {
|
||||||
|
// FIXME: very poor error message
|
||||||
|
int const &b({0}); // expected-error {{could not bind}}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,4 +55,9 @@ namespace integral {
|
||||||
emptylist({});
|
emptylist({});
|
||||||
emptylist({}, {}, {});
|
emptylist({}, {}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void edge_cases() {
|
||||||
|
// FIXME: very poor error message
|
||||||
|
int a({0}); // expected-error {{cannot initialize}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
|
|
||||||
// XFAIL: *
|
|
||||||
|
|
||||||
template <typename T, typename U>
|
|
||||||
struct same_type { static const bool value = false; };
|
|
||||||
template <typename T>
|
|
||||||
struct same_type<T, T> { static const bool value = true; };
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
typedef decltype(sizeof(int)) size_t;
|
|
||||||
|
|
||||||
// libc++'s implementation
|
|
||||||
template <class _E>
|
|
||||||
class initializer_list
|
|
||||||
{
|
|
||||||
const _E* __begin_;
|
|
||||||
size_t __size_;
|
|
||||||
|
|
||||||
initializer_list(const _E* __b, size_t __s)
|
|
||||||
: __begin_(__b),
|
|
||||||
__size_(__s)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef _E value_type;
|
|
||||||
typedef const _E& reference;
|
|
||||||
typedef const _E& const_reference;
|
|
||||||
typedef size_t size_type;
|
|
||||||
|
|
||||||
typedef const _E* iterator;
|
|
||||||
typedef const _E* const_iterator;
|
|
||||||
|
|
||||||
initializer_list() : __begin_(nullptr), __size_(0) {}
|
|
||||||
|
|
||||||
size_t size() const {return __size_;}
|
|
||||||
const _E* begin() const {return __begin_;}
|
|
||||||
const _E* end() const {return __begin_ + __size_;}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace litb {
|
|
||||||
|
|
||||||
// invalid
|
|
||||||
struct A { int a[2]; A():a({1, 2}) { } }; // expected-error {{}}
|
|
||||||
|
|
||||||
// invalid
|
|
||||||
int a({0}); // expected-error {{}}
|
|
||||||
|
|
||||||
// invalid
|
|
||||||
int const &b({0}); // expected-error {{}}
|
|
||||||
|
|
||||||
}
|
|
Загрузка…
Ссылка в новой задаче