diff options
author | dim <dim@FreeBSD.org> | 2017-04-02 17:24:58 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2017-04-02 17:24:58 +0000 |
commit | 60b571e49a90d38697b3aca23020d9da42fc7d7f (patch) | |
tree | 99351324c24d6cb146b6285b6caffa4d26fce188 /contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp | |
parent | bea1b22c7a9bce1dfdd73e6e5b65bc4752215180 (diff) | |
download | FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.zip FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.tar.gz |
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release:
MFC r309142 (by emaste):
Add WITH_LLD_AS_LD build knob
If set it installs LLD as /usr/bin/ld. LLD (as of version 3.9) is not
capable of linking the world and kernel, but can self-host and link many
substantial applications. GNU ld continues to be used for the world and
kernel build, regardless of how this knob is set.
It is on by default for arm64, and off for all other CPU architectures.
Sponsored by: The FreeBSD Foundation
MFC r310840:
Reapply 310775, now it also builds correctly if lldb is disabled:
Move llvm-objdump from CLANG_EXTRAS to installed by default
We currently install three tools from binutils 2.17.50: as, ld, and
objdump. Work is underway to migrate to a permissively-licensed
tool-chain, with one goal being the retirement of binutils 2.17.50.
LLVM's llvm-objdump is intended to be compatible with GNU objdump
although it is currently missing some options and may have formatting
differences. Enable it by default for testing and further investigation.
It may later be changed to install as /usr/bin/objdump, it becomes a
fully viable replacement.
Reviewed by: emaste
Differential Revision: https://reviews.freebsd.org/D8879
MFC r312855 (by emaste):
Rename LLD_AS_LD to LLD_IS_LD, for consistency with CLANG_IS_CC
Reported by: Dan McGregor <dan.mcgregor usask.ca>
MFC r313559 | glebius | 2017-02-10 18:34:48 +0100 (Fri, 10 Feb 2017) | 5 lines
Don't check struct rtentry on FreeBSD, it is an internal kernel structure.
On other systems it may be API structure for SIOCADDRT/SIOCDELRT.
Reviewed by: emaste, dim
MFC r314152 (by jkim):
Remove an assembler flag, which is redundant since r309124. The upstream
took care of it by introducing a macro NO_EXEC_STACK_DIRECTIVE.
http://llvm.org/viewvc/llvm-project?rev=273500&view=rev
Reviewed by: dim
MFC r314564:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
4.0.0 (branches/release_40 296509). The release will follow soon.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Also note that as of 4.0.0, lld should be able to link the base system
on amd64 and aarch64. See the WITH_LLD_IS_LLD setting in src.conf(5).
Though please be aware that this is work in progress.
Release notes for llvm, clang and lld will be available here:
<http://releases.llvm.org/4.0.0/docs/ReleaseNotes.html>
<http://releases.llvm.org/4.0.0/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/4.0.0/tools/lld/docs/ReleaseNotes.html>
Thanks to Ed Maste, Jan Beich, Antoine Brodin and Eric Fiselier for
their help.
Relnotes: yes
Exp-run: antoine
PR: 215969, 216008
MFC r314708:
For now, revert r287232 from upstream llvm trunk (by Daniil Fukalov):
[SCEV] limit recursion depth of CompareSCEVComplexity
Summary:
CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled
loop) and runs almost infinite time.
Added cache of "equal" SCEV pairs to earlier cutoff of further
estimation. Recursion depth limit was also introduced as a parameter.
Reviewers: sanjoy
Subscribers: mzolotukhin, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D26389
This commit is the cause of excessive compile times on skein_block.c
(and possibly other files) during kernel builds on amd64.
We never saw the problematic behavior described in this upstream commit,
so for now it is better to revert it. An upstream bug has been filed
here: https://bugs.llvm.org/show_bug.cgi?id=32142
Reported by: mjg
MFC r314795:
Reapply r287232 from upstream llvm trunk (by Daniil Fukalov):
[SCEV] limit recursion depth of CompareSCEVComplexity
Summary:
CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled
loop) and runs almost infinite time.
Added cache of "equal" SCEV pairs to earlier cutoff of further
estimation. Recursion depth limit was also introduced as a parameter.
Reviewers: sanjoy
Subscribers: mzolotukhin, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D26389
Pull in r296992 from upstream llvm trunk (by Sanjoy Das):
[SCEV] Decrease the recursion threshold for CompareValueComplexity
Fixes PR32142.
r287232 accidentally increased the recursion threshold for
CompareValueComplexity from 2 to 32. This change reverses that
change by introducing a separate flag for CompareValueComplexity's
threshold.
The latter revision fixes the excessive compile times for skein_block.c.
MFC r314907 | mmel | 2017-03-08 12:40:27 +0100 (Wed, 08 Mar 2017) | 7 lines
Unbreak ARMv6 world.
The new compiler_rt library imported with clang 4.0.0 have several fatal
issues (non-functional __udivsi3 for example) with ARM specific instrict
functions. As temporary workaround, until upstream solve these problems,
disable all thumb[1][2] related feature.
MFC r315016:
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release.
We were already very close to the last release candidate, so this is a
pretty minor update.
Relnotes: yes
MFC r316005:
Revert r314907, and pull in r298713 from upstream compiler-rt trunk (by
Weiming Zhao):
builtins: Select correct code fragments when compiling for Thumb1/Thum2/ARM ISA.
Summary:
Value of __ARM_ARCH_ISA_THUMB isn't based on the actual compilation
mode (-mthumb, -marm), it reflect's capability of given CPU.
Due to this:
- use __tbumb__ and __thumb2__ insteand of __ARM_ARCH_ISA_THUMB
- use '.thumb' directive consistently in all affected files
- decorate all thumb functions using
DEFINE_COMPILERRT_THUMB_FUNCTION()
---------
Note: This patch doesn't fix broken Thumb1 variant of __udivsi3 !
Reviewers: weimingz, rengolin, compnerd
Subscribers: aemerson, dim
Differential Revision: https://reviews.llvm.org/D30938
Discussed with: mmel
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp | 1201 |
1 files changed, 784 insertions, 417 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp index 060ee3e..b053c83 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/Sema/Initialization.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprCXX.h" @@ -19,13 +18,13 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Designator.h" +#include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/SemaInternal.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include <map> using namespace clang; @@ -470,9 +469,14 @@ ExprResult InitListChecker::PerformEmptyInit(Sema &SemaRef, SemaRef.Diag(Entity.getDecl()->getLocation(), diag::note_in_omitted_aggregate_initializer) << /*field*/1 << Entity.getDecl(); - else if (Entity.getKind() == InitializedEntity::EK_ArrayElement) + else if (Entity.getKind() == InitializedEntity::EK_ArrayElement) { + bool IsTrailingArrayNewMember = + Entity.getParent() && + Entity.getParent()->isVariableLengthArrayNew(); SemaRef.Diag(Loc, diag::note_in_omitted_aggregate_initializer) - << /*array element*/0 << Entity.getElementIndex(); + << (IsTrailingArrayNewMember ? 2 : /*array element*/0) + << Entity.getElementIndex(); + } } return ExprError(); } @@ -686,8 +690,12 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity, unsigned NumElements = NumInits; if (const ArrayType *AType = SemaRef.Context.getAsArrayType(ILE->getType())) { ElementType = AType->getElementType(); - if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(AType)) + if (const auto *CAType = dyn_cast<ConstantArrayType>(AType)) NumElements = CAType->getSize().getZExtValue(); + // For an array new with an unknown bound, ask for one additional element + // in order to populate the array filler. + if (Entity.isVariableLengthArrayNew()) + ++NumElements; ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); } else if (const VectorType *VType = ILE->getType()->getAs<VectorType>()) { @@ -937,6 +945,7 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity, case InitializedEntity::EK_Base: case InitializedEntity::EK_Delegating: case InitializedEntity::EK_BlockElement: + case InitializedEntity::EK_Binding: llvm_unreachable("unexpected braced scalar init"); } @@ -1229,8 +1238,9 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, // subaggregate, brace elision is assumed and the initializer is // considered for the initialization of the first member of // the subaggregate. - if (!SemaRef.getLangOpts().OpenCL && - (ElemType->isAggregateType() || ElemType->isVectorType())) { + // OpenCL vector initializer is handled elsewhere. + if ((!SemaRef.getLangOpts().OpenCL && ElemType->isVectorType()) || + ElemType->isAggregateType()) { CheckImplicitInitList(Entity, IList, ElemType, Index, StructuredList, StructuredIndex); ++StructuredIndex; @@ -1674,7 +1684,7 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity, // If this is an incomplete array type, the actual type needs to // be calculated here. llvm::APSInt Zero(maxElements.getBitWidth(), maxElements.isUnsigned()); - if (maxElements == Zero) { + if (maxElements == Zero && !Entity.isVariableLengthArrayNew()) { // Sizing an array implicitly to zero is not allowed by ISO C, // but is supported by GNU. SemaRef.Diag(IList->getLocStart(), @@ -1685,10 +1695,13 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity, ArrayType::Normal, 0); } if (!hadError && VerifyOnly) { - // Check if there are any members of the array that get value-initialized. - // If so, check if doing that is possible. + // If there are any members of the array that get value-initialized, check + // that is possible. That happens if we know the bound and don't have + // enough elements, or if we're performing an array new with an unknown + // bound. // FIXME: This needs to detect holes left by designated initializers too. - if (maxElementsKnown && elementIndex < maxElements) + if ((maxElementsKnown && elementIndex < maxElements) || + Entity.isVariableLengthArrayNew()) CheckEmptyInitializable(InitializedEntity::InitializeElement( SemaRef.Context, 0, Entity), IList->getLocEnd()); @@ -2896,7 +2909,8 @@ DeclarationName InitializedEntity::getName() const { case EK_Variable: case EK_Member: - return VariableOrMember->getDeclName(); + case EK_Binding: + return Variable.VariableOrMember->getDeclName(); case EK_LambdaCapture: return DeclarationName(Capture.VarID); @@ -2919,11 +2933,12 @@ DeclarationName InitializedEntity::getName() const { llvm_unreachable("Invalid EntityKind!"); } -DeclaratorDecl *InitializedEntity::getDecl() const { +ValueDecl *InitializedEntity::getDecl() const { switch (getKind()) { case EK_Variable: case EK_Member: - return VariableOrMember; + case EK_Binding: + return Variable.VariableOrMember; case EK_Parameter: case EK_Parameter_CF_Audited: @@ -2958,6 +2973,7 @@ bool InitializedEntity::allowsNRVO() const { case EK_Parameter: case EK_Parameter_CF_Audited: case EK_Member: + case EK_Binding: case EK_New: case EK_Temporary: case EK_CompoundLiteralInit: @@ -2989,6 +3005,7 @@ unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const { case EK_Result: OS << "Result"; break; case EK_Exception: OS << "Exception"; break; case EK_Member: OS << "Member"; break; + case EK_Binding: OS << "Binding"; break; case EK_New: OS << "New"; break; case EK_Temporary: OS << "Temporary"; break; case EK_CompoundLiteralInit: OS << "CompoundLiteral";break; @@ -3005,9 +3022,9 @@ unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const { break; } - if (Decl *D = getDecl()) { + if (auto *D = getDecl()) { OS << " "; - cast<NamedDecl>(D)->printQualifiedName(OS); + D->printQualifiedName(OS); } OS << " '" << getType().getAsString() << "'\n"; @@ -3031,6 +3048,7 @@ void InitializationSequence::Step::Destroy() { case SK_CastDerivedToBaseLValue: case SK_BindReference: case SK_BindReferenceToTemporary: + case SK_FinalCopy: case SK_ExtraneousCopyToTemporary: case SK_UserConversion: case SK_QualificationConversionRValue: @@ -3047,7 +3065,10 @@ void InitializationSequence::Step::Destroy() { case SK_CAssignment: case SK_StringInit: case SK_ObjCObjectConversion: + case SK_ArrayLoopIndex: + case SK_ArrayLoopInit: case SK_ArrayInit: + case SK_GNUArrayInit: case SK_ParenthesizedArrayInit: case SK_PassByIndirectCopyRestore: case SK_PassByIndirectRestore: @@ -3056,6 +3077,7 @@ void InitializationSequence::Step::Destroy() { case SK_StdInitializerListConstructorCall: case SK_OCLSamplerInit: case SK_OCLZeroEvent: + case SK_OCLZeroQueue: break; case SK_ConversionSequence: @@ -3065,7 +3087,14 @@ void InitializationSequence::Step::Destroy() { } bool InitializationSequence::isDirectReferenceBinding() const { - return !Steps.empty() && Steps.back().Kind == SK_BindReference; + // There can be some lvalue adjustments after the SK_BindReference step. + for (auto I = Steps.rbegin(); I != Steps.rend(); ++I) { + if (I->Kind == SK_BindReference) + return true; + if (I->Kind == SK_BindReferenceToTemporary) + return false; + } + return false; } bool InitializationSequence::isAmbiguous() const { @@ -3082,6 +3111,8 @@ bool InitializationSequence::isAmbiguous() const { case FK_IncompatWideStringIntoWideChar: case FK_AddressOfOverloadFailed: // FIXME: Could do better case FK_NonConstLValueReferenceBindingToTemporary: + case FK_NonConstLValueReferenceBindingToBitfield: + case FK_NonConstLValueReferenceBindingToVectorElement: case FK_NonConstLValueReferenceBindingToUnrelated: case FK_RValueReferenceBindingToLValue: case FK_ReferenceInitDropsQualifiers: @@ -3150,6 +3181,13 @@ void InitializationSequence::AddReferenceBindingStep(QualType T, Steps.push_back(S); } +void InitializationSequence::AddFinalCopy(QualType T) { + Step S; + S.Kind = SK_FinalCopy; + S.Type = T; + Steps.push_back(S); +} + void InitializationSequence::AddExtraneousCopyToTemporary(QualType T) { Step S; S.Kind = SK_ExtraneousCopyToTemporary; @@ -3266,9 +3304,20 @@ void InitializationSequence::AddObjCObjectConversionStep(QualType T) { Steps.push_back(S); } -void InitializationSequence::AddArrayInitStep(QualType T) { +void InitializationSequence::AddArrayInitStep(QualType T, bool IsGNUExtension) { Step S; - S.Kind = SK_ArrayInit; + S.Kind = IsGNUExtension ? SK_GNUArrayInit : SK_ArrayInit; + S.Type = T; + Steps.push_back(S); +} + +void InitializationSequence::AddArrayInitLoopStep(QualType T, QualType EltT) { + Step S; + S.Kind = SK_ArrayLoopIndex; + S.Type = EltT; + Steps.insert(Steps.begin(), S); + + S.Kind = SK_ArrayLoopInit; S.Type = T; Steps.push_back(S); } @@ -3317,6 +3366,13 @@ void InitializationSequence::AddOCLZeroEventStep(QualType T) { Steps.push_back(S); } +void InitializationSequence::AddOCLZeroQueueStep(QualType T) { + Step S; + S.Kind = SK_OCLZeroQueue; + S.Type = T; + Steps.push_back(S); +} + void InitializationSequence::RewrapReferenceInitList(QualType T, InitListExpr *Syntactic) { assert(Syntactic->getNumInits() == 1 && @@ -3434,6 +3490,23 @@ static bool TryInitializerListConstruction(Sema &S, return true; } +/// Determine if the constructor has the signature of a copy or move +/// constructor for the type T of the class in which it was found. That is, +/// determine if its first parameter is of type T or reference to (possibly +/// cv-qualified) T. +static bool hasCopyOrMoveCtorParam(ASTContext &Ctx, + const ConstructorInfo &Info) { + if (Info.Constructor->getNumParams() == 0) + return false; + + QualType ParmT = + Info.Constructor->getParamDecl(0)->getType().getNonReferenceType(); + QualType ClassT = + Ctx.getRecordType(cast<CXXRecordDecl>(Info.FoundDecl->getDeclContext())); + + return Ctx.hasSameUnqualifiedType(ParmT, ClassT); +} + static OverloadingResult ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc, MultiExprArg Args, @@ -3441,59 +3514,56 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc, DeclContext::lookup_result Ctors, OverloadCandidateSet::iterator &Best, bool CopyInitializing, bool AllowExplicit, - bool OnlyListConstructors, bool IsListInit) { + bool OnlyListConstructors, bool IsListInit, + bool SecondStepOfCopyInit = false) { CandidateSet.clear(); for (NamedDecl *D : Ctors) { auto Info = getConstructorInfo(D); - if (!Info.Constructor) + if (!Info.Constructor || Info.Constructor->isInvalidDecl()) continue; - bool SuppressUserConversions = false; - - if (!Info.ConstructorTmpl) { - // C++11 [over.best.ics]p4: - // ... and the constructor or user-defined conversion function is a - // candidate by - // - 13.3.1.3, when the argument is the temporary in the second step - // of a class copy-initialization, or - // - 13.3.1.4, 13.3.1.5, or 13.3.1.6 (in all cases), - // user-defined conversion sequences are not considered. - // FIXME: This breaks backward compatibility, e.g. PR12117. As a - // temporary fix, let's re-instate the third bullet above until - // there is a resolution in the standard, i.e., - // - 13.3.1.7 when the initializer list has exactly one element that is - // itself an initializer list and a conversion to some class X or - // reference to (possibly cv-qualified) X is considered for the first - // parameter of a constructor of X. - if ((CopyInitializing || - (IsListInit && Args.size() == 1 && isa<InitListExpr>(Args[0]))) && - Info.Constructor->isCopyOrMoveConstructor()) - SuppressUserConversions = true; - } - - if (!Info.Constructor->isInvalidDecl() && - (AllowExplicit || !Info.Constructor->isExplicit()) && - (!OnlyListConstructors || S.isInitListConstructor(Info.Constructor))) { - if (Info.ConstructorTmpl) - S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl, - /*ExplicitArgs*/ nullptr, Args, - CandidateSet, SuppressUserConversions); - else { - // C++ [over.match.copy]p1: - // - When initializing a temporary to be bound to the first parameter - // of a constructor that takes a reference to possibly cv-qualified - // T as its first argument, called with a single argument in the - // context of direct-initialization, explicit conversion functions - // are also considered. - bool AllowExplicitConv = AllowExplicit && !CopyInitializing && - Args.size() == 1 && - Info.Constructor->isCopyOrMoveConstructor(); - S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, Args, - CandidateSet, SuppressUserConversions, - /*PartialOverloading=*/false, - /*AllowExplicit=*/AllowExplicitConv); - } + if (!AllowExplicit && Info.Constructor->isExplicit()) + continue; + + if (OnlyListConstructors && !S.isInitListConstructor(Info.Constructor)) + continue; + + // C++11 [over.best.ics]p4: + // ... and the constructor or user-defined conversion function is a + // candidate by + // - 13.3.1.3, when the argument is the temporary in the second step + // of a class copy-initialization, or + // - 13.3.1.4, 13.3.1.5, or 13.3.1.6 (in all cases), [not handled here] + // - the second phase of 13.3.1.7 when the initializer list has exactly + // one element that is itself an initializer list, and the target is + // the first parameter of a constructor of class X, and the conversion + // is to X or reference to (possibly cv-qualified X), + // user-defined conversion sequences are not considered. + bool SuppressUserConversions = + SecondStepOfCopyInit || + (IsListInit && Args.size() == 1 && isa<InitListExpr>(Args[0]) && + hasCopyOrMoveCtorParam(S.Context, Info)); + + if (Info.ConstructorTmpl) + S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl, + /*ExplicitArgs*/ nullptr, Args, + CandidateSet, SuppressUserConversions); + else { + // C++ [over.match.copy]p1: + // - When initializing a temporary to be bound to the first parameter + // of a constructor [for type T] that takes a reference to possibly + // cv-qualified T as its first argument, called with a single + // argument in the context of direct-initialization, explicit + // conversion functions are also considered. + // FIXME: What if a constructor template instantiates to such a signature? + bool AllowExplicitConv = AllowExplicit && !CopyInitializing && + Args.size() == 1 && + hasCopyOrMoveCtorParam(S.Context, Info); + S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, Args, + CandidateSet, SuppressUserConversions, + /*PartialOverloading=*/false, + /*AllowExplicit=*/AllowExplicitConv); } } @@ -3504,6 +3574,9 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc, /// \brief Attempt initialization by constructor (C++ [dcl.init]), which /// enumerates the constructors of the initialized entity and performs overload /// resolution to select the best. +/// \param DestType The destination class type. +/// \param DestArrayType The destination type, which is either DestType or +/// a (possibly multidimensional) array of DestType. /// \param IsListInit Is this list-initialization? /// \param IsInitListCopy Is this non-list-initialization resulting from a /// list-initialization from {x} where x is the same @@ -3512,11 +3585,18 @@ static void TryConstructorInitialization(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType DestType, + QualType DestArrayType, InitializationSequence &Sequence, bool IsListInit = false, bool IsInitListCopy = false) { - assert((!IsListInit || (Args.size() == 1 && isa<InitListExpr>(Args[0]))) && - "IsListInit must come with a single initializer list argument."); + assert(((!IsListInit && !IsInitListCopy) || + (Args.size() == 1 && isa<InitListExpr>(Args[0]))) && + "IsListInit/IsInitListCopy must come with a single initializer list " + "argument."); + InitListExpr *ILE = + (IsListInit || IsInitListCopy) ? cast<InitListExpr>(Args[0]) : nullptr; + MultiExprArg UnwrappedArgs = + ILE ? MultiExprArg(ILE->getInits(), ILE->getNumInits()) : Args; // The type we're constructing needs to be complete. if (!S.isCompleteType(Kind.getLocation(), DestType)) { @@ -3524,6 +3604,25 @@ static void TryConstructorInitialization(Sema &S, return; } + // C++1z [dcl.init]p17: + // - If the initializer expression is a prvalue and the cv-unqualified + // version of the source type is the same class as the class of the + // destination, the initializer expression is used to initialize the + // destination object. + // Per DR (no number yet), this does not apply when initializing a base + // class or delegating to another constructor from a mem-initializer. + if (S.getLangOpts().CPlusPlus1z && + Entity.getKind() != InitializedEntity::EK_Base && + Entity.getKind() != InitializedEntity::EK_Delegating && + UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isRValue() && + S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) { + // Convert qualifications if necessary. + Sequence.AddQualificationConversionStep(DestType, VK_RValue); + if (ILE) + Sequence.RewrapReferenceInitList(DestType, ILE); + return; + } + const RecordType *DestRecordType = DestType->getAs<RecordType>(); assert(DestRecordType && "Constructor initialization requires record type"); CXXRecordDecl *DestRecordDecl @@ -3557,20 +3656,16 @@ static void TryConstructorInitialization(Sema &S, // constructors of the class T and the argument list consists of the // initializer list as a single argument. if (IsListInit) { - InitListExpr *ILE = cast<InitListExpr>(Args[0]); AsInitializerList = true; // If the initializer list has no elements and T has a default constructor, // the first phase is omitted. - if (ILE->getNumInits() != 0 || !DestRecordDecl->hasDefaultConstructor()) + if (!(UnwrappedArgs.empty() && DestRecordDecl->hasDefaultConstructor())) Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, CandidateSet, Ctors, Best, CopyInitialization, AllowExplicit, /*OnlyListConstructor=*/true, IsListInit); - - // Time to unwrap the init list. - Args = MultiExprArg(ILE->getInits(), ILE->getNumInits()); } // C++11 [over.match.list]p1: @@ -3580,7 +3675,7 @@ static void TryConstructorInitialization(Sema &S, // elements of the initializer list. if (Result == OR_No_Viable_Function) { AsInitializerList = false; - Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, + Result = ResolveConstructorOverload(S, Kind.getLocation(), UnwrappedArgs, CandidateSet, Ctors, Best, CopyInitialization, AllowExplicit, /*OnlyListConstructors=*/false, @@ -3624,7 +3719,7 @@ static void TryConstructorInitialization(Sema &S, // subsumed by the initialization. bool HadMultipleCandidates = (CandidateSet.size() > 1); Sequence.AddConstructorInitializationStep( - Best->FoundDecl, CtorDecl, DestType, HadMultipleCandidates, + Best->FoundDecl, CtorDecl, DestArrayType, HadMultipleCandidates, IsListInit | IsInitListCopy, AsInitializerList); } @@ -3790,10 +3885,11 @@ static void TryListInitialization(Sema &S, QualType InitType = InitList->getInit(0)->getType(); if (S.Context.hasSameUnqualifiedType(InitType, DestType) || S.IsDerivedFrom(InitList->getLocStart(), InitType, DestType)) { - Expr *InitAsExpr = InitList->getInit(0); - TryConstructorInitialization(S, Entity, Kind, InitAsExpr, DestType, - Sequence, /*InitListSyntax*/ false, - /*IsInitListCopy*/ true); + Expr *InitListAsExpr = InitList; + TryConstructorInitialization(S, Entity, Kind, InitListAsExpr, DestType, + DestType, Sequence, + /*InitListSyntax*/false, + /*IsInitListCopy*/true); return; } } @@ -3848,7 +3944,7 @@ static void TryListInitialization(Sema &S, // - Otherwise, if T is a class type, constructors are considered. Expr *InitListAsExpr = InitList; TryConstructorInitialization(S, Entity, Kind, InitListAsExpr, DestType, - Sequence, /*InitListSyntax*/ true); + DestType, Sequence, /*InitListSyntax*/true); } else Sequence.SetFailed(InitializationSequence::FK_InitListBadDestinationType); return; @@ -3940,12 +4036,10 @@ static void TryListInitialization(Sema &S, /// \brief Try a reference initialization that involves calling a conversion /// function. -static OverloadingResult TryRefInitWithConversionFunction(Sema &S, - const InitializedEntity &Entity, - const InitializationKind &Kind, - Expr *Initializer, - bool AllowRValues, - InitializationSequence &Sequence) { +static OverloadingResult TryRefInitWithConversionFunction( + Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, + Expr *Initializer, bool AllowRValues, bool IsLValueRef, + InitializationSequence &Sequence) { QualType DestType = Entity.getType(); QualType cv1T1 = DestType->getAs<ReferenceType>()->getPointeeType(); QualType T1 = cv1T1.getUnqualifiedType(); @@ -4061,58 +4155,68 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, // use this initialization. Mark it as referenced. Function->setReferenced(); - // Compute the returned type of the conversion. + // Compute the returned type and value kind of the conversion. + QualType cv3T3; if (isa<CXXConversionDecl>(Function)) - T2 = Function->getReturnType(); + cv3T3 = Function->getReturnType(); else - T2 = cv1T1; - - // Add the user-defined conversion step. - bool HadMultipleCandidates = (CandidateSet.size() > 1); - Sequence.AddUserConversionStep(Function, Best->FoundDecl, - T2.getNonLValueExprType(S.Context), - HadMultipleCandidates); + cv3T3 = T1; - // Determine whether we need to perform derived-to-base or - // cv-qualification adjustments. ExprValueKind VK = VK_RValue; - if (T2->isLValueReferenceType()) + if (cv3T3->isLValueReferenceType()) VK = VK_LValue; - else if (const RValueReferenceType *RRef = T2->getAs<RValueReferenceType>()) + else if (const auto *RRef = cv3T3->getAs<RValueReferenceType>()) VK = RRef->getPointeeType()->isFunctionType() ? VK_LValue : VK_XValue; + cv3T3 = cv3T3.getNonLValueExprType(S.Context); + + // Add the user-defined conversion step. + bool HadMultipleCandidates = (CandidateSet.size() > 1); + Sequence.AddUserConversionStep(Function, Best->FoundDecl, cv3T3, + HadMultipleCandidates); + // Determine whether we'll need to perform derived-to-base adjustments or + // other conversions. bool NewDerivedToBase = false; bool NewObjCConversion = false; bool NewObjCLifetimeConversion = false; Sema::ReferenceCompareResult NewRefRelationship - = S.CompareReferenceRelationship(DeclLoc, T1, - T2.getNonLValueExprType(S.Context), + = S.CompareReferenceRelationship(DeclLoc, T1, cv3T3, NewDerivedToBase, NewObjCConversion, NewObjCLifetimeConversion); + + // Add the final conversion sequence, if necessary. if (NewRefRelationship == Sema::Ref_Incompatible) { - // If the type we've converted to is not reference-related to the - // type we're looking for, then there is another conversion step - // we need to perform to produce a temporary of the right type - // that we'll be binding to. + assert(!isa<CXXConstructorDecl>(Function) && + "should not have conversion after constructor"); + ImplicitConversionSequence ICS; ICS.setStandard(); ICS.Standard = Best->FinalConversion; - T2 = ICS.Standard.getToType(2); - Sequence.AddConversionSequenceStep(ICS, T2); - } else if (NewDerivedToBase) - Sequence.AddDerivedToBaseCastStep( - S.Context.getQualifiedType(T1, - T2.getNonReferenceType().getQualifiers()), - VK); - else if (NewObjCConversion) - Sequence.AddObjCObjectConversionStep( - S.Context.getQualifiedType(T1, - T2.getNonReferenceType().getQualifiers())); + Sequence.AddConversionSequenceStep(ICS, ICS.Standard.getToType(2)); + + // Every implicit conversion results in a prvalue, except for a glvalue + // derived-to-base conversion, which we handle below. + cv3T3 = ICS.Standard.getToType(2); + VK = VK_RValue; + } - if (cv1T1.getQualifiers() != T2.getNonReferenceType().getQualifiers()) - Sequence.AddQualificationConversionStep(cv1T1, VK); + // If the converted initializer is a prvalue, its type T4 is adjusted to + // type "cv1 T4" and the temporary materialization conversion is applied. + // + // We adjust the cv-qualifications to match the reference regardless of + // whether we have a prvalue so that the AST records the change. In this + // case, T4 is "cv3 T3". + QualType cv1T4 = S.Context.getQualifiedType(cv3T3, cv1T1.getQualifiers()); + if (cv1T4.getQualifiers() != cv3T3.getQualifiers()) + Sequence.AddQualificationConversionStep(cv1T4, VK); + Sequence.AddReferenceBindingStep(cv1T4, VK == VK_RValue); + VK = IsLValueRef ? VK_LValue : VK_XValue; + + if (NewDerivedToBase) + Sequence.AddDerivedToBaseCastStep(cv1T1, VK); + else if (NewObjCConversion) + Sequence.AddObjCObjectConversionStep(cv1T1); - Sequence.AddReferenceBindingStep(cv1T1, !T2->isReferenceType()); return OR_Success; } @@ -4146,54 +4250,11 @@ static void TryReferenceInitialization(Sema &S, T1Quals, cv2T2, T2, T2Quals, Sequence); } -/// Converts the target of reference initialization so that it has the -/// appropriate qualifiers and value kind. -/// -/// In this case, 'x' is an 'int' lvalue, but it needs to be 'const int'. -/// \code -/// int x; -/// const int &r = x; -/// \endcode -/// -/// In this case the reference is binding to a bitfield lvalue, which isn't -/// valid. Perform a load to create a lifetime-extended temporary instead. -/// \code -/// const int &r = someStruct.bitfield; -/// \endcode -static ExprValueKind -convertQualifiersAndValueKindIfNecessary(Sema &S, - InitializationSequence &Sequence, - Expr *Initializer, - QualType cv1T1, - Qualifiers T1Quals, - Qualifiers T2Quals, - bool IsLValueRef) { - bool IsNonAddressableType = Initializer->refersToBitField() || - Initializer->refersToVectorElement(); - - if (IsNonAddressableType) { - // C++11 [dcl.init.ref]p5: [...] Otherwise, the reference shall be an - // lvalue reference to a non-volatile const type, or the reference shall be - // an rvalue reference. - // - // If not, we can't make a temporary and bind to that. Give up and allow the - // error to be diagnosed later. - if (IsLValueRef && (!T1Quals.hasConst() || T1Quals.hasVolatile())) { - assert(Initializer->isGLValue()); - return Initializer->getValueKind(); - } - - // Force a load so we can materialize a temporary. - Sequence.AddLValueToRValueStep(cv1T1.getUnqualifiedType()); - return VK_RValue; - } - - if (T1Quals != T2Quals) { - Sequence.AddQualificationConversionStep(cv1T1, - Initializer->getValueKind()); - } - - return Initializer->getValueKind(); +/// Determine whether an expression is a non-referenceable glvalue (one to +/// which a reference can never bind). Attemting to bind a reference to +/// such a glvalue will always create a temporary. +static bool isNonReferenceableGLValue(Expr *E) { + return E->refersToBitField() || E->refersToVectorElement(); } /// \brief Reference initialization without resolving overloaded functions. @@ -4231,31 +4292,28 @@ static void TryReferenceInitializationCore(Sema &S, OverloadingResult ConvOvlResult = OR_Success; bool T1Function = T1->isFunctionType(); if (isLValueRef || T1Function) { - if (InitCategory.isLValue() && - (RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification || + if (InitCategory.isLValue() && !isNonReferenceableGLValue(Initializer) && + (RefRelationship == Sema::Ref_Compatible || (Kind.isCStyleOrFunctionalCast() && RefRelationship == Sema::Ref_Related))) { // - is an lvalue (but is not a bit-field), and "cv1 T1" is // reference-compatible with "cv2 T2," or - // - // Per C++ [over.best.ics]p2, we don't diagnose whether the lvalue is a - // bit-field when we're determining whether the reference initialization - // can occur. However, we do pay attention to whether it is a bit-field - // to decide whether we're actually binding to a temporary created from - // the bit-field. + if (T1Quals != T2Quals) + // Convert to cv1 T2. This should only add qualifiers unless this is a + // c-style cast. The removal of qualifiers in that case notionally + // happens after the reference binding, but that doesn't matter. + Sequence.AddQualificationConversionStep( + S.Context.getQualifiedType(T2, T1Quals), + Initializer->getValueKind()); if (DerivedToBase) - Sequence.AddDerivedToBaseCastStep( - S.Context.getQualifiedType(T1, T2Quals), - VK_LValue); + Sequence.AddDerivedToBaseCastStep(cv1T1, VK_LValue); else if (ObjCConversion) - Sequence.AddObjCObjectConversionStep( - S.Context.getQualifiedType(T1, T2Quals)); - - ExprValueKind ValueKind = - convertQualifiersAndValueKindIfNecessary(S, Sequence, Initializer, - cv1T1, T1Quals, T2Quals, - isLValueRef); - Sequence.AddReferenceBindingStep(cv1T1, ValueKind == VK_RValue); + Sequence.AddObjCObjectConversionStep(cv1T1); + + // We only create a temporary here when binding a reference to a + // bit-field or vector element. Those cases are't supposed to be + // handled by this bullet, but the outcome is the same either way. + Sequence.AddReferenceBindingStep(cv1T1, false); return; } @@ -4270,7 +4328,8 @@ static void TryReferenceInitializationCore(Sema &S, if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() && (isLValueRef || InitCategory.isRValue())) { ConvOvlResult = TryRefInitWithConversionFunction( - S, Entity, Kind, Initializer, /*AllowRValues*/isRValueRef, Sequence); + S, Entity, Kind, Initializer, /*AllowRValues*/ isRValueRef, + /*IsLValueRef*/ isLValueRef, Sequence); if (ConvOvlResult == OR_Success) return; if (ConvOvlResult != OR_No_Viable_Function) @@ -4290,28 +4349,51 @@ static void TryReferenceInitializationCore(Sema &S, Sequence.SetOverloadFailure( InitializationSequence::FK_ReferenceInitOverloadFailed, ConvOvlResult); - else - Sequence.SetFailed(InitCategory.isLValue() - ? (RefRelationship == Sema::Ref_Related - ? InitializationSequence::FK_ReferenceInitDropsQualifiers - : InitializationSequence::FK_NonConstLValueReferenceBindingToUnrelated) - : InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary); - + else if (!InitCategory.isLValue()) + Sequence.SetFailed( + InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary); + else { + InitializationSequence::FailureKind FK; + switch (RefRelationship) { + case Sema::Ref_Compatible: + if (Initializer->refersToBitField()) + FK = InitializationSequence:: + FK_NonConstLValueReferenceBindingToBitfield; + else if (Initializer->refersToVectorElement()) + FK = InitializationSequence:: + FK_NonConstLValueReferenceBindingToVectorElement; + else + llvm_unreachable("unexpected kind of compatible initializer"); + break; + case Sema::Ref_Related: + FK = InitializationSequence::FK_ReferenceInitDropsQualifiers; + break; + case Sema::Ref_Incompatible: + FK = InitializationSequence:: + FK_NonConstLValueReferenceBindingToUnrelated; + break; + } + Sequence.SetFailed(FK); + } return; } // - If the initializer expression - // - is an xvalue, class prvalue, array prvalue, or function lvalue and - // "cv1 T1" is reference-compatible with "cv2 T2" - // Note: functions are handled below. + // - is an + // [<=14] xvalue (but not a bit-field), class prvalue, array prvalue, or + // [1z] rvalue (but not a bit-field) or + // function lvalue and "cv1 T1" is reference-compatible with "cv2 T2" + // + // Note: functions are handled above and below rather than here... if (!T1Function && - (RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification || + (RefRelationship == Sema::Ref_Compatible || (Kind.isCStyleOrFunctionalCast() && RefRelationship == Sema::Ref_Related)) && - (InitCategory.isXValue() || - (InitCategory.isPRValue() && T2->isRecordType()) || - (InitCategory.isPRValue() && T2->isArrayType()))) { - ExprValueKind ValueKind = InitCategory.isXValue()? VK_XValue : VK_RValue; + ((InitCategory.isXValue() && !isNonReferenceableGLValue(Initializer)) || + (InitCategory.isPRValue() && + (S.getLangOpts().CPlusPlus1z || T2->isRecordType() || + T2->isArrayType())))) { + ExprValueKind ValueKind = InitCategory.isXValue() ? VK_XValue : VK_RValue; if (InitCategory.isPRValue() && T2->isRecordType()) { // The corresponding bullet in C++03 [dcl.init.ref]p5 gives the // compiler the freedom to perform a copy here or bind to the @@ -4328,19 +4410,22 @@ static void TryReferenceInitializationCore(Sema &S, CheckCXX98CompatAccessibleCopy(S, Entity, Initializer); } + // C++1z [dcl.init.ref]/5.2.1.2: + // If the converted initializer is a prvalue, its type T4 is adjusted + // to type "cv1 T4" and the temporary materialization conversion is + // applied. + QualType cv1T4 = S.Context.getQualifiedType(cv2T2, T1Quals); + if (T1Quals != T2Quals) + Sequence.AddQualificationConversionStep(cv1T4, ValueKind); + Sequence.AddReferenceBindingStep(cv1T4, ValueKind == VK_RValue); + ValueKind = isLValueRef ? VK_LValue : VK_XValue; + + // In any case, the reference is bound to the resulting glvalue (or to + // an appropriate base class subobject). if (DerivedToBase) - Sequence.AddDerivedToBaseCastStep(S.Context.getQualifiedType(T1, T2Quals), - ValueKind); + Sequence.AddDerivedToBaseCastStep(cv1T1, ValueKind); else if (ObjCConversion) - Sequence.AddObjCObjectConversionStep( - S.Context.getQualifiedType(T1, T2Quals)); - - ValueKind = convertQualifiersAndValueKindIfNecessary(S, Sequence, - Initializer, cv1T1, - T1Quals, T2Quals, - isLValueRef); - - Sequence.AddReferenceBindingStep(cv1T1, ValueKind == VK_RValue); + Sequence.AddObjCObjectConversionStep(cv1T1); return; } @@ -4353,7 +4438,8 @@ static void TryReferenceInitializationCore(Sema &S, if (T2->isRecordType()) { if (RefRelationship == Sema::Ref_Incompatible) { ConvOvlResult = TryRefInitWithConversionFunction( - S, Entity, Kind, Initializer, /*AllowRValues*/true, Sequence); + S, Entity, Kind, Initializer, /*AllowRValues*/ true, + /*IsLValueRef*/ isLValueRef, Sequence); if (ConvOvlResult) Sequence.SetOverloadFailure( InitializationSequence::FK_ReferenceInitOverloadFailed, @@ -4362,8 +4448,7 @@ static void TryReferenceInitializationCore(Sema &S, return; } - if ((RefRelationship == Sema::Ref_Compatible || - RefRelationship == Sema::Ref_Compatible_With_Added_Qualification) && + if (RefRelationship == Sema::Ref_Compatible && isRValueRef && InitCategory.isLValue()) { Sequence.SetFailed( InitializationSequence::FK_RValueReferenceBindingToLValue); @@ -4462,23 +4547,21 @@ static void TryValueInitialization(Sema &S, if (const RecordType *RT = T->getAs<RecordType>()) { if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) { bool NeedZeroInitialization = true; - if (!S.getLangOpts().CPlusPlus11) { - // C++98: - // -- if T is a class type (clause 9) with a user-declared constructor - // (12.1), then the default constructor for T is called (and the - // initialization is ill-formed if T has no accessible default - // constructor); - if (ClassDecl->hasUserDeclaredConstructor()) - NeedZeroInitialization = false; - } else { - // C++11: - // -- if T is a class type (clause 9) with either no default constructor - // (12.1 [class.ctor]) or a default constructor that is user-provided - // or deleted, then the object is default-initialized; - CXXConstructorDecl *CD = S.LookupDefaultConstructor(ClassDecl); - if (!CD || !CD->getCanonicalDecl()->isDefaulted() || CD->isDeleted()) - NeedZeroInitialization = false; - } + // C++98: + // -- if T is a class type (clause 9) with a user-declared constructor + // (12.1), then the default constructor for T is called (and the + // initialization is ill-formed if T has no accessible default + // constructor); + // C++11: + // -- if T is a class type (clause 9) with either no default constructor + // (12.1 [class.ctor]) or a default constructor that is user-provided + // or deleted, then the object is default-initialized; + // + // Note that the C++11 rule is the same as the C++98 rule if there are no + // defaulted or deleted constructors, so we just use it unconditionally. + CXXConstructorDecl *CD = S.LookupDefaultConstructor(ClassDecl); + if (!CD || !CD->getCanonicalDecl()->isDefaulted() || CD->isDeleted()) + NeedZeroInitialization = false; // -- if T is a (possibly cv-qualified) non-union class type without a // user-provided or deleted default constructor, then the object is @@ -4512,8 +4595,10 @@ static void TryValueInitialization(Sema &S, MultiExprArg Args(&InitListAsExpr, InitList ? 1 : 0); bool InitListSyntax = InitList; - return TryConstructorInitialization(S, Entity, Kind, Args, T, Sequence, - InitListSyntax); + // FIXME: Instead of creating a CXXConstructExpr of array type here, + // wrap a class-typed CXXConstructExpr in an ArrayInitLoopExpr. + return TryConstructorInitialization( + S, Entity, Kind, Args, T, Entity.getType(), Sequence, InitListSyntax); } } @@ -4536,7 +4621,8 @@ static void TryDefaultInitialization(Sema &S, // constructor for T is called (and the initialization is ill-formed if // T has no accessible default constructor); if (DestType->isRecordType() && S.getLangOpts().CPlusPlus) { - TryConstructorInitialization(S, Entity, Kind, None, DestType, Sequence); + TryConstructorInitialization(S, Entity, Kind, None, DestType, + Entity.getType(), Sequence); return; } @@ -4680,26 +4766,55 @@ static void TryUserDefinedConversion(Sema &S, Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType.getUnqualifiedType(), HadMultipleCandidates); + + // C++14 and before: + // - if the function is a constructor, the call initializes a temporary + // of the cv-unqualified version of the destination type. The [...] + // temporary [...] is then used to direct-initialize, according to the + // rules above, the object that is the destination of the + // copy-initialization. + // Note that this just performs a simple object copy from the temporary. + // + // C++1z: + // - if the function is a constructor, the call is a prvalue of the + // cv-unqualified version of the destination type whose return object + // is initialized by the constructor. The call is used to + // direct-initialize, according to the rules above, the object that + // is the destination of the copy-initialization. + // Therefore we need to do nothing further. + // + // FIXME: Mark this copy as extraneous. + if (!S.getLangOpts().CPlusPlus1z) + Sequence.AddFinalCopy(DestType); + else if (DestType.hasQualifiers()) + Sequence.AddQualificationConversionStep(DestType, VK_RValue); return; } // Add the user-defined conversion step that calls the conversion function. QualType ConvType = Function->getCallResultType(); + Sequence.AddUserConversionStep(Function, Best->FoundDecl, ConvType, + HadMultipleCandidates); + if (ConvType->getAs<RecordType>()) { - // If we're converting to a class type, there may be an copy of - // the resulting temporary object (possible to create an object of - // a base class type). That copy is not a separate conversion, so - // we just make a note of the actual destination type (possibly a - // base class of the type returned by the conversion function) and - // let the user-defined conversion step handle the conversion. - Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType, - HadMultipleCandidates); + // The call is used to direct-initialize [...] the object that is the + // destination of the copy-initialization. + // + // In C++1z, this does not call a constructor if we enter /17.6.1: + // - If the initializer expression is a prvalue and the cv-unqualified + // version of the source type is the same as the class of the + // destination [... do not make an extra copy] + // + // FIXME: Mark this copy as extraneous. + if (!S.getLangOpts().CPlusPlus1z || + Function->getReturnType()->isReferenceType() || + !S.Context.hasSameUnqualifiedType(ConvType, DestType)) + Sequence.AddFinalCopy(DestType); + else if (!S.Context.hasSameType(ConvType, DestType)) + Sequence.AddQualificationConversionStep(DestType, VK_RValue); return; } - Sequence.AddUserConversionStep(Function, Best->FoundDecl, ConvType, - HadMultipleCandidates); - // If the conversion following the call to the conversion function // is interesting, add it as a separate step. if (Best->FinalConversion.First || Best->FinalConversion.Second || @@ -4886,7 +5001,8 @@ static bool TryOCLSamplerInitialization(Sema &S, QualType DestType, Expr *Initializer) { if (!S.getLangOpts().OpenCL || !DestType->isSamplerT() || - !Initializer->isIntegerConstantExpr(S.getASTContext())) + (!Initializer->isIntegerConstantExpr(S.Context) && + !Initializer->getType()->isSamplerT())) return false; Sequence.AddOCLSamplerInitStep(DestType); @@ -4914,6 +5030,20 @@ static bool TryOCLZeroEventInitialization(Sema &S, return true; } +static bool TryOCLZeroQueueInitialization(Sema &S, + InitializationSequence &Sequence, + QualType DestType, + Expr *Initializer) { + if (!S.getLangOpts().OpenCL || S.getLangOpts().OpenCLVersion < 200 || + !DestType->isQueueT() || + !Initializer->isIntegerConstantExpr(S.getASTContext()) || + (Initializer->EvaluateKnownConstInt(S.getASTContext()) != 0)) + return false; + + Sequence.AddOCLZeroQueueStep(DestType); + return true; +} + InitializationSequence::InitializationSequence(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, @@ -4936,6 +5066,42 @@ static bool isExprAnUnaddressableFunction(Sema &S, const Expr *E) { cast<FunctionDecl>(DRE->getDecl())); } +/// Determine whether we can perform an elementwise array copy for this kind +/// of entity. +static bool canPerformArrayCopy(const InitializedEntity &Entity) { + switch (Entity.getKind()) { + case InitializedEntity::EK_LambdaCapture: + // C++ [expr.prim.lambda]p24: + // For array members, the array elements are direct-initialized in + // increasing subscript order. + return true; + + case InitializedEntity::EK_Variable: + // C++ [dcl.decomp]p1: + // [...] each element is copy-initialized or direct-initialized from the + // corresponding element of the assignment-expression [...] + return isa<DecompositionDecl>(Entity.getDecl()); + + case InitializedEntity::EK_Member: + // C++ [class.copy.ctor]p14: + // - if the member is an array, each element is direct-initialized with + // the corresponding subobject of x + return Entity.isImplicitMemberInitializer(); + + case InitializedEntity::EK_ArrayElement: + // All the above cases are intended to apply recursively, even though none + // of them actually say that. + if (auto *E = Entity.getParent()) + return canPerformArrayCopy(*E); + break; + + default: + break; + } + + return false; +} + void InitializationSequence::InitializeFrom(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, @@ -5058,6 +5224,34 @@ void InitializationSequence::InitializeFrom(Sema &S, } } + // Some kinds of initialization permit an array to be initialized from + // another array of the same type, and perform elementwise initialization. + if (Initializer && isa<ConstantArrayType>(DestAT) && + S.Context.hasSameUnqualifiedType(Initializer->getType(), + Entity.getType()) && + canPerformArrayCopy(Entity)) { + // If source is a prvalue, use it directly. + if (Initializer->getValueKind() == VK_RValue) { + AddArrayInitStep(DestType, /*IsGNUExtension*/false); + return; + } + + // Emit element-at-a-time copy loop. + InitializedEntity Element = + InitializedEntity::InitializeElement(S.Context, 0, Entity); + QualType InitEltT = + Context.getAsArrayType(Initializer->getType())->getElementType(); + OpaqueValueExpr OVE(Initializer->getExprLoc(), InitEltT, + Initializer->getValueKind(), + Initializer->getObjectKind()); + Expr *OVEAsExpr = &OVE; + InitializeFrom(S, Element, Kind, OVEAsExpr, TopLevelOfInitList, + TreatUnavailableAsInvalid); + if (!Failed()) + AddArrayInitLoopStep(Entity.getType(), InitEltT); + return; + } + // Note: as an GNU C extension, we allow initialization of an // array from a compound literal that creates an array of the same // type, so long as the initializer has no side effects. @@ -5071,7 +5265,7 @@ void InitializationSequence::InitializeFrom(Sema &S, else if (Initializer->HasSideEffects(S.Context)) SetFailed(FK_NonConstantArrayInit); else { - AddArrayInitStep(DestType); + AddArrayInitStep(DestType, /*IsGNUExtension*/true); } } // Note: as a GNU C++ extension, we allow list-initialization of a @@ -5112,6 +5306,9 @@ void InitializationSequence::InitializeFrom(Sema &S, if (TryOCLZeroEventInitialization(S, *this, DestType, Initializer)) return; + if (TryOCLZeroQueueInitialization(S, *this, DestType, Initializer)) + return; + // Handle initialization in C AddCAssignmentStep(DestType); MaybeProduceObjCObject(S, *this, Entity); @@ -5131,7 +5328,7 @@ void InitializationSequence::InitializeFrom(Sema &S, (Context.hasSameUnqualifiedType(SourceType, DestType) || S.IsDerivedFrom(Initializer->getLocStart(), SourceType, DestType)))) TryConstructorInitialization(S, Entity, Kind, Args, - DestType, *this); + DestType, DestType, *this); // - Otherwise (i.e., for the remaining copy-initialization cases), // user-defined conversion sequences that can convert from the source // type to the destination type or (when a conversion function is @@ -5270,6 +5467,7 @@ getAssignmentAction(const InitializedEntity &Entity, bool Diagnose = false) { return Sema::AA_Casting; case InitializedEntity::EK_Member: + case InitializedEntity::EK_Binding: case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_VectorElement: case InitializedEntity::EK_ComplexElement: @@ -5305,6 +5503,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) { case InitializedEntity::EK_Parameter_CF_Audited: case InitializedEntity::EK_Temporary: case InitializedEntity::EK_RelatedResult: + case InitializedEntity::EK_Binding: return true; } @@ -5313,7 +5512,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) { /// \brief Whether the given entity, when initialized with an object /// created for that initialization, requires destruction. -static bool shouldDestroyTemporary(const InitializedEntity &Entity) { +static bool shouldDestroyEntity(const InitializedEntity &Entity) { switch (Entity.getKind()) { case InitializedEntity::EK_Result: case InitializedEntity::EK_New: @@ -5326,6 +5525,7 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) { return false; case InitializedEntity::EK_Member: + case InitializedEntity::EK_Binding: case InitializedEntity::EK_Variable: case InitializedEntity::EK_Parameter: case InitializedEntity::EK_Parameter_CF_Audited: @@ -5340,50 +5540,6 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) { llvm_unreachable("missed an InitializedEntity kind?"); } -/// \brief Look for copy and move constructors and constructor templates, for -/// copying an object via direct-initialization (per C++11 [dcl.init]p16). -static void LookupCopyAndMoveConstructors(Sema &S, - OverloadCandidateSet &CandidateSet, - CXXRecordDecl *Class, - Expr *CurInitExpr) { - DeclContext::lookup_result R = S.LookupConstructors(Class); - // The container holding the constructors can under certain conditions - // be changed while iterating (e.g. because of deserialization). - // To be safe we copy the lookup results to a new container. - SmallVector<NamedDecl*, 16> Ctors(R.begin(), R.end()); - for (SmallVectorImpl<NamedDecl *>::iterator - CI = Ctors.begin(), CE = Ctors.end(); CI != CE; ++CI) { - NamedDecl *D = *CI; - auto Info = getConstructorInfo(D); - if (!Info.Constructor) - continue; - - if (!Info.ConstructorTmpl) { - // Handle copy/move constructors, only. - if (Info.Constructor->isInvalidDecl() || - !Info.Constructor->isCopyOrMoveConstructor() || - !Info.Constructor->isConvertingConstructor(/*AllowExplicit=*/true)) - continue; - - S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, - CurInitExpr, CandidateSet); - continue; - } - - // Handle constructor templates. - if (Info.ConstructorTmpl->isInvalidDecl()) - continue; - - if (!Info.Constructor->isConvertingConstructor(/*AllowExplicit=*/true)) - continue; - - // FIXME: Do we need to limit this to copy-constructor-like - // candidates? - S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl, - nullptr, CurInitExpr, CandidateSet, true); - } -} - /// \brief Get the location at which initialization diagnostics should appear. static SourceLocation getInitializationLoc(const InitializedEntity &Entity, Expr *Initializer) { @@ -5395,6 +5551,7 @@ static SourceLocation getInitializationLoc(const InitializedEntity &Entity, return Entity.getThrowLoc(); case InitializedEntity::EK_Variable: + case InitializedEntity::EK_Binding: return Entity.getDecl()->getLocation(); case InitializedEntity::EK_LambdaCapture: @@ -5453,39 +5610,24 @@ static ExprResult CopyObject(Sema &S, if (!Class) return CurInit; - // C++0x [class.copy]p32: - // When certain criteria are met, an implementation is allowed to - // omit the copy/move construction of a class object, even if the - // copy/move constructor and/or destructor for the object have - // side effects. [...] - // - when a temporary class object that has not been bound to a - // reference (12.2) would be copied/moved to a class object - // with the same cv-unqualified type, the copy/move operation - // can be omitted by constructing the temporary object - // directly into the target of the omitted copy/move - // - // Note that the other three bullets are handled elsewhere. Copy - // elision for return statements and throw expressions are handled as part - // of constructor initialization, while copy elision for exception handlers - // is handled by the run-time. - bool Elidable = CurInitExpr->isTemporaryObject(S.Context, Class); SourceLocation Loc = getInitializationLoc(Entity, CurInit.get()); // Make sure that the type we are copying is complete. if (S.RequireCompleteType(Loc, T, diag::err_temp_copy_incomplete)) return CurInit; - // Perform overload resolution using the class's copy/move constructors. - // Only consider constructors and constructor templates. Per - // C++0x [dcl.init]p16, second bullet to class types, this initialization + // Perform overload resolution using the class's constructors. Per + // C++11 [dcl.init]p16, second bullet for class types, this initialization // is direct-initialization. OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); - LookupCopyAndMoveConstructors(S, CandidateSet, Class, CurInitExpr); - - bool HadMultipleCandidates = (CandidateSet.size() > 1); + DeclContext::lookup_result Ctors = S.LookupConstructors(Class); OverloadCandidateSet::iterator Best; - switch (CandidateSet.BestViableFunction(S, Loc, Best)) { + switch (ResolveConstructorOverload( + S, Loc, CurInitExpr, CandidateSet, Ctors, Best, + /*CopyInitializing=*/false, /*AllowExplicit=*/true, + /*OnlyListConstructors=*/false, /*IsListInit=*/false, + /*SecondStepOfCopyInit=*/true)) { case OR_Success: break; @@ -5515,6 +5657,8 @@ static ExprResult CopyObject(Sema &S, return ExprError(); } + bool HadMultipleCandidates = CandidateSet.size() > 1; + CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function); SmallVector<Expr*, 8> ConstructorArgs; CurInit.get(); // Ownership transferred into MultiExprArg, below. @@ -5554,6 +5698,31 @@ static ExprResult CopyObject(Sema &S, if (S.CompleteConstructorCall(Constructor, CurInitExpr, Loc, ConstructorArgs)) return ExprError(); + // C++0x [class.copy]p32: + // When certain criteria are met, an implementation is allowed to + // omit the copy/move construction of a class object, even if the + // copy/move constructor and/or destructor for the object have + // side effects. [...] + // - when a temporary class object that has not been bound to a + // reference (12.2) would be copied/moved to a class object + // with the same cv-unqualified type, the copy/move operation + // can be omitted by constructing the temporary object + // directly into the target of the omitted copy/move + // + // Note that the other three bullets are handled elsewhere. Copy + // elision for return statements and throw expressions are handled as part + // of constructor initialization, while copy elision for exception handlers + // is handled by the run-time. + // + // FIXME: If the function parameter is not the same type as the temporary, we + // should still be able to elide the copy, but we don't have a way to + // represent in the AST how much should be elided in this case. + bool Elidable = + CurInitExpr->isTemporaryObject(S.Context, Class) && + S.Context.hasSameUnqualifiedType( + Best->Function->getParamDecl(0)->getType().getNonReferenceType(), + CurInitExpr->getType()); + // Actually perform the constructor call. CurInit = S.BuildCXXConstructExpr(Loc, T, Best->FoundDecl, Constructor, Elidable, @@ -5589,12 +5758,16 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S, // Find constructors which would have been considered. OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); - LookupCopyAndMoveConstructors( - S, CandidateSet, cast<CXXRecordDecl>(Record->getDecl()), CurInitExpr); + DeclContext::lookup_result Ctors = + S.LookupConstructors(cast<CXXRecordDecl>(Record->getDecl())); // Perform overload resolution. OverloadCandidateSet::iterator Best; - OverloadingResult OR = CandidateSet.BestViableFunction(S, Loc, Best); + OverloadingResult OR = ResolveConstructorOverload( + S, Loc, CurInitExpr, CandidateSet, Ctors, Best, + /*CopyInitializing=*/false, /*AllowExplicit=*/true, + /*OnlyListConstructors=*/false, /*IsListInit=*/false, + /*SecondStepOfCopyInit=*/true); PartialDiagnostic Diag = S.PDiag(diag::warn_cxx98_compat_temp_copy) << OR << (int)Entity.getKind() << CurInitExpr->getType() @@ -5643,11 +5816,6 @@ void InitializationSequence::PrintInitLocationNote(Sema &S, << Entity.getMethodDecl()->getDeclName(); } -static bool isReferenceBinding(const InitializationSequence::Step &s) { - return s.Kind == InitializationSequence::SK_BindReference || - s.Kind == InitializationSequence::SK_BindReferenceToTemporary; -} - /// Returns true if the parameters describe a constructor initialization of /// an explicit temporary object, e.g. "Point(x, y)". static bool isExplicitTemporary(const InitializedEntity &Entity, @@ -5714,9 +5882,10 @@ PerformConstructorInitialization(Sema &S, // T as its first argument, called with a single argument in the // context of direct-initialization, explicit conversion functions // are also considered. - bool AllowExplicitConv = Kind.AllowExplicit() && !Kind.isCopyInit() && - Args.size() == 1 && - Constructor->isCopyOrMoveConstructor(); + bool AllowExplicitConv = + Kind.AllowExplicit() && !Kind.isCopyInit() && Args.size() == 1 && + hasCopyOrMoveCtorParam(S.Context, + getConstructorInfo(Step.Function.FoundDecl)); // Determine the arguments required to actually perform the constructor // call. @@ -5776,7 +5945,7 @@ PerformConstructorInitialization(Sema &S, // If the entity allows NRVO, mark the construction as elidable // unconditionally. if (Entity.allowsNRVO()) - CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(), + CurInit = S.BuildCXXConstructExpr(Loc, Step.Type, Step.Function.FoundDecl, Constructor, /*Elidable=*/true, ConstructorArgs, @@ -5787,7 +5956,7 @@ PerformConstructorInitialization(Sema &S, ConstructKind, ParenOrBraceRange); else - CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(), + CurInit = S.BuildCXXConstructExpr(Loc, Step.Type, Step.Function.FoundDecl, Constructor, ConstructorArgs, @@ -5826,6 +5995,7 @@ InitializedEntityOutlivesFullExpression(const InitializedEntity &Entity) { case InitializedEntity::EK_Result: case InitializedEntity::EK_Exception: case InitializedEntity::EK_Member: + case InitializedEntity::EK_Binding: case InitializedEntity::EK_New: case InitializedEntity::EK_Base: case InitializedEntity::EK_Delegating: @@ -5875,6 +6045,11 @@ static const InitializedEntity *getEntityForTemporaryLifetimeExtension( // ctor-initializer persists until the constructor exits. return Entity; + case InitializedEntity::EK_Binding: + // Per [dcl.decomp]p3, the binding is treated as a variable of reference + // type. + return Entity; + case InitializedEntity::EK_Parameter: case InitializedEntity::EK_Parameter_CF_Audited: // -- A temporary bound to a reference parameter in a function call @@ -5949,10 +6124,7 @@ performReferenceExtension(Expr *Init, // Step over any subobject adjustments; we may have a materialized // temporary inside them. - SmallVector<const Expr *, 2> CommaLHSs; - SmallVector<SubobjectAdjustment, 2> Adjustments; - Init = const_cast<Expr *>( - Init->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments)); + Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments()); // Per current approach for DR1376, look through casts to reference type // when performing lifetime extension. @@ -5960,9 +6132,10 @@ performReferenceExtension(Expr *Init, if (CE->getSubExpr()->isGLValue()) Init = CE->getSubExpr(); - // FIXME: Per DR1213, subscripting on an array temporary produces an xvalue. - // It's unclear if binding a reference to that xvalue extends the array - // temporary. + // Per the current approach for DR1299, look through array element access + // when performing lifetime extension. + if (auto *ASE = dyn_cast<ArraySubscriptExpr>(Init)) + Init = ASE->getBase(); } while (Init != Old); if (MaterializeTemporaryExpr *ME = dyn_cast<MaterializeTemporaryExpr>(Init)) { @@ -5982,10 +6155,7 @@ performReferenceExtension(Expr *Init, static void performLifetimeExtension(Expr *Init, const InitializedEntity *ExtendingEntity) { // Dig out the expression which constructs the extended temporary. - SmallVector<const Expr *, 2> CommaLHSs; - SmallVector<SubobjectAdjustment, 2> Adjustments; - Init = const_cast<Expr *>( - Init->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments)); + Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments()); if (CXXBindTemporaryExpr *BTE = dyn_cast<CXXBindTemporaryExpr>(Init)) Init = BTE->getSubExpr(); @@ -6204,6 +6374,24 @@ Sema::CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, return MTE; } +ExprResult Sema::TemporaryMaterializationConversion(Expr *E) { + // In C++98, we don't want to implicitly create an xvalue. + // FIXME: This means that AST consumers need to deal with "prvalues" that + // denote materialized temporaries. Maybe we should add another ValueKind + // for "xvalue pretending to be a prvalue" for C++98 support. + if (!E->isRValue() || !getLangOpts().CPlusPlus11) + return E; + + // C++1z [conv.rval]/1: T shall be a complete type. + // FIXME: Does this ever matter (can we form a prvalue of incomplete type)? + // If so, we should check for a non-abstract class type here too. + QualType T = E->getType(); + if (RequireCompleteType(E->getExprLoc(), T, diag::err_incomplete_type)) + return ExprError(); + + return CreateMaterializeTemporaryExpr(E->getType(), E, false); +} + ExprResult InitializationSequence::Perform(Sema &S, const InitializedEntity &Entity, @@ -6250,7 +6438,7 @@ InitializationSequence::Perform(Sema &S, SourceRange Brackets; // Scavange the location of the brackets from the entity, if we can. - if (DeclaratorDecl *DD = Entity.getDecl()) { + if (auto *DD = dyn_cast_or_null<DeclaratorDecl>(Entity.getDecl())) { if (TypeSourceInfo *TInfo = DD->getTypeSourceInfo()) { TypeLoc TL = TInfo->getTypeLoc(); if (IncompleteArrayTypeLoc ArrayLoc = @@ -6302,7 +6490,9 @@ InitializationSequence::Perform(Sema &S, if (Args.size() == 1 && Args[0]->getType()->isArrayType() && Entity.getType()->isPointerType() && InitializedEntityOutlivesFullExpression(Entity)) { - Expr *Init = Args[0]; + const Expr *Init = Args[0]->skipRValueSubobjectAdjustments(); + if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) + Init = MTE->GetTemporaryExpr(); Expr::LValueClassification Kind = Init->ClassifyLValue(S.Context); if (Kind == Expr::LV_ClassTemporary || Kind == Expr::LV_ArrayTemporary) S.Diag(Init->getLocStart(), diag::warn_temporary_array_to_pointer_decay) @@ -6318,6 +6508,7 @@ InitializationSequence::Perform(Sema &S, Entity.getType(); ExprResult CurInit((Expr *)nullptr); + SmallVector<Expr*, 4> ArrayLoopCommonExprs; // For initialization steps that start with a single initializer, // grab the only argument out the Args and place it into the "current" @@ -6329,6 +6520,7 @@ InitializationSequence::Perform(Sema &S, case SK_CastDerivedToBaseLValue: case SK_BindReference: case SK_BindReferenceToTemporary: + case SK_FinalCopy: case SK_ExtraneousCopyToTemporary: case SK_UserConversion: case SK_QualificationConversionLValue: @@ -6344,14 +6536,18 @@ InitializationSequence::Perform(Sema &S, case SK_CAssignment: case SK_StringInit: case SK_ObjCObjectConversion: + case SK_ArrayLoopIndex: + case SK_ArrayLoopInit: case SK_ArrayInit: + case SK_GNUArrayInit: case SK_ParenthesizedArrayInit: case SK_PassByIndirectCopyRestore: case SK_PassByIndirectRestore: case SK_ProduceObjCObject: case SK_StdInitializerList: case SK_OCLSamplerInit: - case SK_OCLZeroEvent: { + case SK_OCLZeroEvent: + case SK_OCLZeroQueue: { assert(Args.size() == 1); CurInit = Args[0]; if (!CurInit.get()) return ExprError(); @@ -6365,6 +6561,24 @@ InitializationSequence::Perform(Sema &S, break; } + // Promote from an unevaluated context to an unevaluated list context in + // C++11 list-initialization; we need to instantiate entities usable in + // constant expressions here in order to perform narrowing checks =( + EnterExpressionEvaluationContext Evaluated( + S, EnterExpressionEvaluationContext::InitList, + CurInit.get() && isa<InitListExpr>(CurInit.get())); + + // C++ [class.abstract]p2: + // no objects of an abstract class can be created except as subobjects + // of a class derived from it + auto checkAbstractType = [&](QualType T) -> bool { + if (Entity.getKind() == InitializedEntity::EK_Base || + Entity.getKind() == InitializedEntity::EK_Delegating) + return false; + return S.RequireNonAbstractType(Kind.getLocation(), T, + diag::err_allocation_of_abstract_type); + }; + // Walk through the computed steps for the initialization sequence, // performing the specified conversions along the way. bool ConstructorInitRequiresZeroInit = false; @@ -6416,30 +6630,6 @@ InitializationSequence::Perform(Sema &S, } case SK_BindReference: - // References cannot bind to bit-fields (C++ [dcl.init.ref]p5). - if (CurInit.get()->refersToBitField()) { - // We don't necessarily have an unambiguous source bit-field. - FieldDecl *BitField = CurInit.get()->getSourceBitField(); - S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield) - << Entity.getType().isVolatileQualified() - << (BitField ? BitField->getDeclName() : DeclarationName()) - << (BitField != nullptr) - << CurInit.get()->getSourceRange(); - if (BitField) - S.Diag(BitField->getLocation(), diag::note_bitfield_decl); - - return ExprError(); - } - - if (CurInit.get()->refersToVectorElement()) { - // References cannot bind to vector elements. - S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element) - << Entity.getType().isVolatileQualified() - << CurInit.get()->getSourceRange(); - PrintInitLocationNote(S, Entity); - return ExprError(); - } - // Reference binding does not have any corresponding ASTs. // Check exception specifications @@ -6469,15 +6659,15 @@ InitializationSequence::Perform(Sema &S, // Materialize the temporary into memory. MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr( - Entity.getType().getNonReferenceType(), CurInit.get(), - Entity.getType()->isLValueReferenceType()); + Step->Type, CurInit.get(), Entity.getType()->isLValueReferenceType()); // Maybe lifetime-extend the temporary's subobjects to match the // entity's lifetime. if (const InitializedEntity *ExtendingEntity = getEntityForTemporaryLifetimeExtension(&Entity)) if (performReferenceExtension(MTE, ExtendingEntity)) - warnOnLifetimeExtension(S, Entity, CurInit.get(), /*IsInitializerList=*/false, + warnOnLifetimeExtension(S, Entity, CurInit.get(), + /*IsInitializerList=*/false, ExtendingEntity->getDecl()); // If we're binding to an Objective-C object that has lifetime, we @@ -6494,6 +6684,21 @@ InitializationSequence::Perform(Sema &S, break; } + case SK_FinalCopy: + if (checkAbstractType(Step->Type)) + return ExprError(); + + // If the overall initialization is initializing a temporary, we already + // bound our argument if it was necessary to do so. If not (if we're + // ultimately initializing a non-temporary), our argument needs to be + // bound since it's initializing a function parameter. + // FIXME: This is a mess. Rationalize temporary destruction. + if (!shouldBindAsTemporary(Entity)) + CurInit = S.MaybeBindToTemporary(CurInit.get()); + CurInit = CopyObject(S, Step->Type, Entity, CurInit, + /*IsExtraneousCopy=*/false); + break; + case SK_ExtraneousCopyToTemporary: CurInit = CopyObject(S, Step->Type, Entity, CurInit, /*IsExtraneousCopy=*/true); @@ -6503,7 +6708,6 @@ InitializationSequence::Perform(Sema &S, // We have a user-defined conversion that invokes either a constructor // or a conversion function. CastKind CastKind; - bool IsCopy = false; FunctionDecl *Fn = Step->Function.Function; DeclAccessPair FoundFn = Step->Function.FoundDecl; bool HadMultipleCandidates = Step->Function.HadMultipleCandidates; @@ -6512,7 +6716,6 @@ InitializationSequence::Perform(Sema &S, // Build a call to the selected constructor. SmallVector<Expr*, 8> ConstructorArgs; SourceLocation Loc = CurInit.get()->getLocStart(); - CurInit.get(); // Ownership transferred into MultiExprArg, below. // Determine the arguments required to actually perform the constructor // call. @@ -6541,11 +6744,6 @@ InitializationSequence::Perform(Sema &S, return ExprError(); CastKind = CK_ConstructorConversion; - QualType Class = S.Context.getTypeDeclType(Constructor->getParent()); - if (S.Context.hasSameUnqualifiedType(SourceType, Class) || - S.IsDerivedFrom(Loc, SourceType, Class)) - IsCopy = true; - CreatedObject = true; } else { // Build a call to the conversion function. @@ -6558,29 +6756,38 @@ InitializationSequence::Perform(Sema &S, // FIXME: Should we move this initialization into a separate // derived-to-base conversion? I believe the answer is "no", because // we don't want to turn off access control here for c-style casts. - ExprResult CurInitExprRes = - S.PerformObjectArgumentInitialization(CurInit.get(), - /*Qualifier=*/nullptr, - FoundFn, Conversion); - if(CurInitExprRes.isInvalid()) + CurInit = S.PerformObjectArgumentInitialization(CurInit.get(), + /*Qualifier=*/nullptr, + FoundFn, Conversion); + if (CurInit.isInvalid()) return ExprError(); - CurInit = CurInitExprRes; // Build the actual call to the conversion function. CurInit = S.BuildCXXMemberCallExpr(CurInit.get(), FoundFn, Conversion, HadMultipleCandidates); - if (CurInit.isInvalid() || !CurInit.get()) + if (CurInit.isInvalid()) return ExprError(); CastKind = CK_UserDefinedConversion; - CreatedObject = Conversion->getReturnType()->isRecordType(); } - bool RequiresCopy = !IsCopy && !isReferenceBinding(Steps.back()); - bool MaybeBindToTemp = RequiresCopy || shouldBindAsTemporary(Entity); + if (CreatedObject && checkAbstractType(CurInit.get()->getType())) + return ExprError(); + + CurInit = ImplicitCastExpr::Create(S.Context, CurInit.get()->getType(), + CastKind, CurInit.get(), nullptr, + CurInit.get()->getValueKind()); - if (!MaybeBindToTemp && CreatedObject && shouldDestroyTemporary(Entity)) { + if (shouldBindAsTemporary(Entity)) + // The overall entity is temporary, so this expression should be + // destroyed at the end of its full-expression. + CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>()); + else if (CreatedObject && shouldDestroyEntity(Entity)) { + // The object outlasts the full-expression, but we need to prepare for + // a destructor being run on it. + // FIXME: It makes no sense to do this here. This should happen + // regardless of how we initialized the entity. QualType T = CurInit.get()->getType(); if (const RecordType *Record = T->getAs<RecordType>()) { CXXDestructorDecl *Destructor @@ -6592,15 +6799,6 @@ InitializationSequence::Perform(Sema &S, return ExprError(); } } - - CurInit = ImplicitCastExpr::Create(S.Context, CurInit.get()->getType(), - CastKind, CurInit.get(), nullptr, - CurInit.get()->getValueKind()); - if (MaybeBindToTemp) - CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>()); - if (RequiresCopy) - CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity, - CurInit, /*IsExtraneousCopy=*/false); break; } @@ -6645,16 +6843,23 @@ InitializationSequence::Perform(Sema &S, getAssignmentAction(Entity), CCK); if (CurInitExprRes.isInvalid()) return ExprError(); + + S.DiscardMisalignedMemberAddress(Step->Type.getTypePtr(), CurInit.get()); + CurInit = CurInitExprRes; if (Step->Kind == SK_ConversionSequenceNoNarrowing && - S.getLangOpts().CPlusPlus && !CurInit.get()->isValueDependent()) + S.getLangOpts().CPlusPlus) DiagnoseNarrowingInInitList(S, *Step->ICS, SourceType, Entity.getType(), CurInit.get()); + break; } case SK_ListInitialization: { + if (checkAbstractType(Step->Type)) + return ExprError(); + InitListExpr *InitList = cast<InitListExpr>(CurInit.get()); // If we're not initializing the top-level entity, we need to create an // InitializeTemporary entity for our target type. @@ -6691,6 +6896,9 @@ InitializationSequence::Perform(Sema &S, } case SK_ConstructorInitializationFromList: { + if (checkAbstractType(Step->Type)) + return ExprError(); + // When an initializer list is passed for a parameter of type "reference // to object", we don't get an EK_Temporary entity, but instead an // EK_Parameter entity with reference type. @@ -6734,6 +6942,9 @@ InitializationSequence::Perform(Sema &S, case SK_ConstructorInitialization: case SK_StdInitializerListConstructorCall: { + if (checkAbstractType(Step->Type)) + return ExprError(); + // When an initializer list is passed for a parameter of type "reference // to object", we don't get an EK_Temporary entity, but instead an // EK_Parameter entity with reference type. @@ -6745,13 +6956,15 @@ InitializationSequence::Perform(Sema &S, bool UseTemporary = Entity.getType()->isReferenceType(); bool IsStdInitListInit = Step->Kind == SK_StdInitializerListConstructorCall; + Expr *Source = CurInit.get(); CurInit = PerformConstructorInitialization( - S, UseTemporary ? TempEntity : Entity, Kind, Args, *Step, + S, UseTemporary ? TempEntity : Entity, Kind, + Source ? MultiExprArg(Source) : Args, *Step, ConstructorInitRequiresZeroInit, - /*IsListInitialization*/IsStdInitListInit, - /*IsStdInitListInitialization*/IsStdInitListInit, - /*LBraceLoc*/SourceLocation(), - /*RBraceLoc*/SourceLocation()); + /*IsListInitialization*/ IsStdInitListInit, + /*IsStdInitListInitialization*/ IsStdInitListInit, + /*LBraceLoc*/ SourceLocation(), + /*RBraceLoc*/ SourceLocation()); break; } @@ -6830,13 +7043,36 @@ InitializationSequence::Perform(Sema &S, CurInit.get()->getValueKind()); break; - case SK_ArrayInit: + case SK_ArrayLoopIndex: { + Expr *Cur = CurInit.get(); + Expr *BaseExpr = new (S.Context) + OpaqueValueExpr(Cur->getExprLoc(), Cur->getType(), + Cur->getValueKind(), Cur->getObjectKind(), Cur); + Expr *IndexExpr = + new (S.Context) ArrayInitIndexExpr(S.Context.getSizeType()); + CurInit = S.CreateBuiltinArraySubscriptExpr( + BaseExpr, Kind.getLocation(), IndexExpr, Kind.getLocation()); + ArrayLoopCommonExprs.push_back(BaseExpr); + break; + } + + case SK_ArrayLoopInit: { + assert(!ArrayLoopCommonExprs.empty() && + "mismatched SK_ArrayLoopIndex and SK_ArrayLoopInit"); + Expr *Common = ArrayLoopCommonExprs.pop_back_val(); + CurInit = new (S.Context) ArrayInitLoopExpr(Step->Type, Common, + CurInit.get()); + break; + } + + case SK_GNUArrayInit: // Okay: we checked everything before creating this step. Note that // this is a GNU extension. S.Diag(Kind.getLocation(), diag::ext_array_init_copy) << Step->Type << CurInit.get()->getType() << CurInit.get()->getSourceRange(); - + LLVM_FALLTHROUGH; + case SK_ArrayInit: // If the destination type is an incomplete array type, update the // type accordingly. if (ResultType) { @@ -6904,19 +7140,93 @@ InitializationSequence::Perform(Sema &S, } case SK_OCLSamplerInit: { - assert(Step->Type->isSamplerT() && + // Sampler initialzation have 5 cases: + // 1. function argument passing + // 1a. argument is a file-scope variable + // 1b. argument is a function-scope variable + // 1c. argument is one of caller function's parameters + // 2. variable initialization + // 2a. initializing a file-scope variable + // 2b. initializing a function-scope variable + // + // For file-scope variables, since they cannot be initialized by function + // call of __translate_sampler_initializer in LLVM IR, their references + // need to be replaced by a cast from their literal initializers to + // sampler type. Since sampler variables can only be used in function + // calls as arguments, we only need to replace them when handling the + // argument passing. + assert(Step->Type->isSamplerT() && "Sampler initialization on non-sampler type."); - - QualType SourceType = CurInit.get()->getType(); - + Expr *Init = CurInit.get(); + QualType SourceType = Init->getType(); + // Case 1 if (Entity.isParameterKind()) { - if (!SourceType->isSamplerT()) + if (!SourceType->isSamplerT()) { S.Diag(Kind.getLocation(), diag::err_sampler_argument_required) << SourceType; - } else if (Entity.getKind() != InitializedEntity::EK_Variable) { - llvm_unreachable("Invalid EntityKind!"); + break; + } else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Init)) { + auto Var = cast<VarDecl>(DRE->getDecl()); + // Case 1b and 1c + // No cast from integer to sampler is needed. + if (!Var->hasGlobalStorage()) { + CurInit = ImplicitCastExpr::Create(S.Context, Step->Type, + CK_LValueToRValue, Init, + /*BasePath=*/nullptr, VK_RValue); + break; + } + // Case 1a + // For function call with a file-scope sampler variable as argument, + // get the integer literal. + // Do not diagnose if the file-scope variable does not have initializer + // since this has already been diagnosed when parsing the variable + // declaration. + if (!Var->getInit() || !isa<ImplicitCastExpr>(Var->getInit())) + break; + Init = cast<ImplicitCastExpr>(const_cast<Expr*>( + Var->getInit()))->getSubExpr(); + SourceType = Init->getType(); + } + } else { + // Case 2 + // Check initializer is 32 bit integer constant. + // If the initializer is taken from global variable, do not diagnose since + // this has already been done when parsing the variable declaration. + if (!Init->isConstantInitializer(S.Context, false)) + break; + + if (!SourceType->isIntegerType() || + 32 != S.Context.getIntWidth(SourceType)) { + S.Diag(Kind.getLocation(), diag::err_sampler_initializer_not_integer) + << SourceType; + break; + } + + llvm::APSInt Result; + Init->EvaluateAsInt(Result, S.Context); + const uint64_t SamplerValue = Result.getLimitedValue(); + // 32-bit value of sampler's initializer is interpreted as + // bit-field with the following structure: + // |unspecified|Filter|Addressing Mode| Normalized Coords| + // |31 6|5 4|3 1| 0| + // This structure corresponds to enum values of sampler properties + // defined in SPIR spec v1.2 and also opencl-c.h + unsigned AddressingMode = (0x0E & SamplerValue) >> 1; + unsigned FilterMode = (0x30 & SamplerValue) >> 4; + if (FilterMode != 1 && FilterMode != 2) + S.Diag(Kind.getLocation(), + diag::warn_sampler_initializer_invalid_bits) + << "Filter Mode"; + if (AddressingMode > 4) + S.Diag(Kind.getLocation(), + diag::warn_sampler_initializer_invalid_bits) + << "Addressing Mode"; } + // Cases 1a, 2a and 2b + // Insert cast from integer to sampler. + CurInit = S.ImpCastExprToType(Init, S.Context.OCLSamplerTy, + CK_IntToOCLSampler); break; } case SK_OCLZeroEvent: { @@ -6928,6 +7238,15 @@ InitializationSequence::Perform(Sema &S, CurInit.get()->getValueKind()); break; } + case SK_OCLZeroQueue: { + assert(Step->Type->isQueueT() && + "Event initialization on non queue type."); + + CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type, + CK_ZeroToOCLQueue, + CurInit.get()->getValueKind()); + break; + } } } @@ -7190,6 +7509,25 @@ bool InitializationSequence::Diagnose(Sema &S, << Args[0]->getSourceRange(); break; + case FK_NonConstLValueReferenceBindingToBitfield: { + // We don't necessarily have an unambiguous source bit-field. + FieldDecl *BitField = Args[0]->getSourceBitField(); + S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield) + << DestType.isVolatileQualified() + << (BitField ? BitField->getDeclName() : DeclarationName()) + << (BitField != nullptr) + << Args[0]->getSourceRange(); + if (BitField) + S.Diag(BitField->getLocation(), diag::note_bitfield_decl); + break; + } + + case FK_NonConstLValueReferenceBindingToVectorElement: + S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element) + << DestType.isVolatileQualified() + << Args[0]->getSourceRange(); + break; + case FK_RValueReferenceBindingToLValue: S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref) << DestType.getNonReferenceType() << Args[0]->getType() @@ -7487,6 +7825,14 @@ void InitializationSequence::dump(raw_ostream &OS) const { OS << "non-const lvalue reference bound to temporary"; break; + case FK_NonConstLValueReferenceBindingToBitfield: + OS << "non-const lvalue reference bound to bit-field"; + break; + + case FK_NonConstLValueReferenceBindingToVectorElement: + OS << "non-const lvalue reference bound to vector element"; + break; + case FK_NonConstLValueReferenceBindingToUnrelated: OS << "non-const lvalue reference bound to unrelated type"; break; @@ -7583,15 +7929,15 @@ void InitializationSequence::dump(raw_ostream &OS) const { break; case SK_CastDerivedToBaseRValue: - OS << "derived-to-base case (rvalue" << S->Type.getAsString() << ")"; + OS << "derived-to-base (rvalue)"; break; case SK_CastDerivedToBaseXValue: - OS << "derived-to-base case (xvalue" << S->Type.getAsString() << ")"; + OS << "derived-to-base (xvalue)"; break; case SK_CastDerivedToBaseLValue: - OS << "derived-to-base case (lvalue" << S->Type.getAsString() << ")"; + OS << "derived-to-base (lvalue)"; break; case SK_BindReference: @@ -7602,6 +7948,10 @@ void InitializationSequence::dump(raw_ostream &OS) const { OS << "bind reference to a temporary"; break; + case SK_FinalCopy: + OS << "final copy in class direct-initialization"; + break; + case SK_ExtraneousCopyToTemporary: OS << "extraneous C++03 copy to temporary"; break; @@ -7678,10 +8028,22 @@ void InitializationSequence::dump(raw_ostream &OS) const { OS << "Objective-C object conversion"; break; + case SK_ArrayLoopIndex: + OS << "indexing for array initialization loop"; + break; + + case SK_ArrayLoopInit: + OS << "array initialization loop"; + break; + case SK_ArrayInit: OS << "array initialization"; break; + case SK_GNUArrayInit: + OS << "array initialization (GNU extension)"; + break; + case SK_ParenthesizedArrayInit: OS << "parenthesized array initialization"; break; @@ -7713,6 +8075,10 @@ void InitializationSequence::dump(raw_ostream &OS) const { case SK_OCLZeroEvent: OS << "OpenCL event_t from zero"; break; + + case SK_OCLZeroQueue: + OS << "OpenCL queue_t from zero"; + break; } OS << " [" << S->Type.getAsString() << ']'; @@ -7750,6 +8116,7 @@ static void DiagnoseNarrowingInInitList(Sema &S, switch (SCS->getNarrowingKind(S.Context, PostInit, ConstantValue, ConstantType)) { case NK_Not_Narrowing: + case NK_Dependent_Narrowing: // No narrowing occurred. return; |