aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r--clang/lib/Sema/SemaInit.cpp284
1 files changed, 141 insertions, 143 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 32c9215184eb..5ca6b232df66 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -15,9 +15,11 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
+#include "clang/AST/IgnoreExpr.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/EnterExpressionEvaluationContext.h"
@@ -91,7 +93,7 @@ static StringInitFailureKind IsStringInit(Expr *Init, const ArrayType *AT,
};
switch (SL->getKind()) {
- case StringLiteral::UTF8:
+ case StringLiteralKind::UTF8:
// char8_t array can be initialized with a UTF-8 string.
// - C++20 [dcl.init.string] (DR)
// Additionally, an array of char or unsigned char may be initialized
@@ -101,11 +103,11 @@ static StringInitFailureKind IsStringInit(Expr *Init, const ArrayType *AT,
IsCharOrUnsignedChar(ElemTy.getCanonicalType())))
return SIF_None;
[[fallthrough]];
- case StringLiteral::Ordinary:
+ case StringLiteralKind::Ordinary:
// char array can be initialized with a narrow string.
// Only allow char x[] = "foo"; not char x[] = L"foo";
if (ElemTy->isCharType())
- return (SL->getKind() == StringLiteral::UTF8 &&
+ return (SL->getKind() == StringLiteralKind::UTF8 &&
Context.getLangOpts().Char8)
? SIF_UTF8StringIntoPlainChar
: SIF_None;
@@ -119,7 +121,7 @@ static StringInitFailureKind IsStringInit(Expr *Init, const ArrayType *AT,
// version of wchar_t, char16_t, or char32_t may be initialized by a wide
// string literal with the corresponding encoding prefix (L, u, or U,
// respectively), optionally enclosed in braces.
- case StringLiteral::UTF16:
+ case StringLiteralKind::UTF16:
if (Context.typesAreCompatible(Context.Char16Ty, ElemTy))
return SIF_None;
if (ElemTy->isCharType() || ElemTy->isChar8Type())
@@ -127,7 +129,7 @@ static StringInitFailureKind IsStringInit(Expr *Init, const ArrayType *AT,
if (IsWideCharCompatible(ElemTy, Context))
return SIF_IncompatWideStringIntoWideChar;
return SIF_Other;
- case StringLiteral::UTF32:
+ case StringLiteralKind::UTF32:
if (Context.typesAreCompatible(Context.Char32Ty, ElemTy))
return SIF_None;
if (ElemTy->isCharType() || ElemTy->isChar8Type())
@@ -135,7 +137,7 @@ static StringInitFailureKind IsStringInit(Expr *Init, const ArrayType *AT,
if (IsWideCharCompatible(ElemTy, Context))
return SIF_IncompatWideStringIntoWideChar;
return SIF_Other;
- case StringLiteral::Wide:
+ case StringLiteralKind::Wide:
if (Context.typesAreCompatible(Context.getWideCharType(), ElemTy))
return SIF_None;
if (ElemTy->isCharType() || ElemTy->isChar8Type())
@@ -143,7 +145,7 @@ static StringInitFailureKind IsStringInit(Expr *Init, const ArrayType *AT,
if (IsWideCharCompatible(ElemTy, Context))
return SIF_IncompatWideStringIntoWideChar;
return SIF_Other;
- case StringLiteral::Unevaluated:
+ case StringLiteralKind::Unevaluated:
assert(false && "Unevaluated string literal in initialization");
break;
}
@@ -169,22 +171,9 @@ static void updateStringLiteralType(Expr *E, QualType Ty) {
while (true) {
E->setType(Ty);
E->setValueKind(VK_PRValue);
- if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E)) {
+ if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E))
break;
- } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
- E = PE->getSubExpr();
- } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
- assert(UO->getOpcode() == UO_Extension);
- E = UO->getSubExpr();
- } else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) {
- E = GSE->getResultExpr();
- } else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E)) {
- E = CE->getChosenSubExpr();
- } else if (PredefinedExpr *PE = dyn_cast<PredefinedExpr>(E)) {
- E = PE->getFunctionName();
- } else {
- llvm_unreachable("unexpected expr in string literal init");
- }
+ E = IgnoreParensSingleStep(E);
}
}
@@ -193,20 +182,9 @@ static void updateStringLiteralType(Expr *E, QualType Ty) {
static void updateGNUCompoundLiteralRValue(Expr *E) {
while (true) {
E->setValueKind(VK_PRValue);
- if (isa<CompoundLiteralExpr>(E)) {
+ if (isa<CompoundLiteralExpr>(E))
break;
- } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
- E = PE->getSubExpr();
- } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
- assert(UO->getOpcode() == UO_Extension);
- E = UO->getSubExpr();
- } else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) {
- E = GSE->getResultExpr();
- } else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E)) {
- E = CE->getChosenSubExpr();
- } else {
- llvm_unreachable("unexpected expr in array compound literal init");
- }
+ E = IgnoreParensSingleStep(E);
}
}
@@ -222,9 +200,8 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
// being initialized to a string literal.
llvm::APInt ConstVal(32, StrLength);
// Return a new array type (C99 6.7.8p22).
- DeclT = S.Context.getConstantArrayType(IAT->getElementType(),
- ConstVal, nullptr,
- ArrayType::Normal, 0);
+ DeclT = S.Context.getConstantArrayType(
+ IAT->getElementType(), ConstVal, nullptr, ArraySizeModifier::Normal, 0);
updateStringLiteralType(Str, DeclT);
return;
}
@@ -1831,8 +1808,8 @@ void InitListChecker::CheckVectorType(const InitializedEntity &Entity,
bool isBigEndian = SemaRef.Context.getTargetInfo().isBigEndian();
const VectorType *T = Entity.getType()->castAs<VectorType>();
- if (isBigEndian && (T->getVectorKind() == VectorType::NeonVector ||
- T->getVectorKind() == VectorType::NeonPolyVector)) {
+ if (isBigEndian && (T->getVectorKind() == VectorKind::Neon ||
+ T->getVectorKind() == VectorKind::NeonPoly)) {
// The ability to use vector initializer lists is a GNU vector extension
// and is unrelated to the NEON intrinsics in arm_neon.h. On little
// endian machines it works fine, however on big endian machines it
@@ -1980,7 +1957,7 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity,
// them in all sorts of strange places).
bool HasErr = IList->getNumInits() != 0 || SemaRef.getLangOpts().CPlusPlus;
if (!VerifyOnly) {
- // C2x 6.7.9p4: An entity of variable length array type shall not be
+ // C23 6.7.10p4: An entity of variable length array type shall not be
// initialized except by an empty initializer.
//
// The C extension warnings are issued from ParseBraceInitializer() and
@@ -2075,7 +2052,7 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity,
}
DeclType = SemaRef.Context.getConstantArrayType(
- elementType, maxElements, nullptr, ArrayType::Normal, 0);
+ elementType, maxElements, nullptr, ArraySizeModifier::Normal, 0);
}
if (!hadError) {
// If there are any members of the array that get value-initialized, check
@@ -2252,6 +2229,8 @@ void InitListChecker::CheckStructUnionTypes(
!IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts());
bool HasDesignatedInit = false;
+ llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
+
while (Index < IList->getNumInits()) {
Expr *Init = IList->getInit(Index);
SourceLocation InitLoc = Init->getBeginLoc();
@@ -2267,20 +2246,23 @@ void InitListChecker::CheckStructUnionTypes(
// Handle this designated initializer. Field will be updated to
// the next field that we'll be initializing.
- if (CheckDesignatedInitializer(Entity, IList, DIE, 0,
- DeclType, &Field, nullptr, Index,
- StructuredList, StructuredIndex,
- true, TopLevelObject))
+ bool DesignatedInitFailed = CheckDesignatedInitializer(
+ Entity, IList, DIE, 0, DeclType, &Field, nullptr, Index,
+ StructuredList, StructuredIndex, true, TopLevelObject);
+ if (DesignatedInitFailed)
hadError = true;
- else if (!VerifyOnly) {
- // Find the field named by the designated initializer.
- RecordDecl::field_iterator F = RD->field_begin();
- while (std::next(F) != Field)
- ++F;
- QualType ET = SemaRef.Context.getBaseElementType(F->getType());
- if (checkDestructorReference(ET, InitLoc, SemaRef)) {
- hadError = true;
- return;
+
+ // Find the field named by the designated initializer.
+ DesignatedInitExpr::Designator *D = DIE->getDesignator(0);
+ if (!VerifyOnly && D->isFieldDesignator()) {
+ FieldDecl *F = D->getFieldDecl();
+ InitializedFields.insert(F);
+ if (!DesignatedInitFailed) {
+ QualType ET = SemaRef.Context.getBaseElementType(F->getType());
+ if (checkDestructorReference(ET, InitLoc, SemaRef)) {
+ hadError = true;
+ return;
+ }
}
}
@@ -2288,7 +2270,8 @@ void InitListChecker::CheckStructUnionTypes(
// Disable check for missing fields when designators are used.
// This matches gcc behaviour.
- CheckForMissingFields = false;
+ if (!SemaRef.getLangOpts().CPlusPlus)
+ CheckForMissingFields = false;
continue;
}
@@ -2367,6 +2350,7 @@ void InitListChecker::CheckStructUnionTypes(
CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
StructuredList, StructuredIndex);
InitializedSomething = true;
+ InitializedFields.insert(*Field);
if (RD->isUnion() && StructuredList) {
// Initialize the first field within the union.
@@ -2378,15 +2362,21 @@ void InitListChecker::CheckStructUnionTypes(
// Emit warnings for missing struct field initializers.
if (!VerifyOnly && InitializedSomething && CheckForMissingFields &&
- Field != FieldEnd && !Field->getType()->isIncompleteArrayType() &&
!RD->isUnion()) {
// It is possible we have one or more unnamed bitfields remaining.
// Find first (if any) named field and emit warning.
- for (RecordDecl::field_iterator it = Field, end = RD->field_end();
+ for (RecordDecl::field_iterator it = HasDesignatedInit ? RD->field_begin()
+ : Field,
+ end = RD->field_end();
it != end; ++it) {
- if (!it->isUnnamedBitfield() && !it->hasInClassInitializer()) {
+ if (HasDesignatedInit && InitializedFields.count(*it))
+ continue;
+
+ if (!it->isUnnamedBitfield() && !it->hasInClassInitializer() &&
+ !it->getType()->isIncompleteArrayType()) {
SemaRef.Diag(IList->getSourceRange().getEnd(),
- diag::warn_missing_field_initializers) << *it;
+ diag::warn_missing_field_initializers)
+ << *it;
break;
}
}
@@ -2691,21 +2681,16 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
FieldDecl *KnownField = D->getFieldDecl();
if (!KnownField) {
const IdentifierInfo *FieldName = D->getFieldName();
- DeclContext::lookup_result Lookup = RD->lookup(FieldName);
- for (NamedDecl *ND : Lookup) {
- if (auto *FD = dyn_cast<FieldDecl>(ND)) {
- KnownField = FD;
- break;
- }
- if (auto *IFD = dyn_cast<IndirectFieldDecl>(ND)) {
- // In verify mode, don't modify the original.
- if (VerifyOnly)
- DIE = CloneDesignatedInitExpr(SemaRef, DIE);
- ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx, IFD);
- D = DIE->getDesignator(DesigIdx);
- KnownField = cast<FieldDecl>(*IFD->chain_begin());
- break;
- }
+ ValueDecl *VD = SemaRef.tryLookupUnambiguousFieldDecl(RD, FieldName);
+ if (auto *FD = dyn_cast_if_present<FieldDecl>(VD)) {
+ KnownField = FD;
+ } else if (auto *IFD = dyn_cast_if_present<IndirectFieldDecl>(VD)) {
+ // In verify mode, don't modify the original.
+ if (VerifyOnly)
+ DIE = CloneDesignatedInitExpr(SemaRef, DIE);
+ ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx, IFD);
+ D = DIE->getDesignator(DesigIdx);
+ KnownField = cast<FieldDecl>(*IFD->chain_begin());
}
if (!KnownField) {
if (VerifyOnly) {
@@ -2713,10 +2698,17 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
return true; // No typo correction when just trying this out.
}
+ // We found a placeholder variable
+ if (SemaRef.DiagRedefinedPlaceholderFieldDecl(DIE->getBeginLoc(), RD,
+ FieldName)) {
+ ++Index;
+ return true;
+ }
// Name lookup found something, but it wasn't a field.
- if (!Lookup.empty()) {
+ if (DeclContextLookupResult Lookup = RD->lookup(FieldName);
+ !Lookup.empty()) {
SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_nonfield)
- << FieldName;
+ << FieldName;
SemaRef.Diag(Lookup.front()->getLocation(),
diag::note_field_designator_found);
++Index;
@@ -2844,7 +2836,8 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
if (PrevField &&
PrevField->getFieldIndex() > KnownField->getFieldIndex()) {
- SemaRef.Diag(DIE->getBeginLoc(), diag::ext_designated_init_reordered)
+ SemaRef.Diag(DIE->getInit()->getBeginLoc(),
+ diag::ext_designated_init_reordered)
<< KnownField << PrevField << DIE->getSourceRange();
unsigned OldIndex = StructuredIndex - 1;
@@ -4063,7 +4056,7 @@ static bool TryInitializerListConstruction(Sema &S,
E.withConst(),
llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
List->getNumInits()),
- nullptr, clang::ArrayType::Normal, 0);
+ nullptr, clang::ArraySizeModifier::Normal, 0);
InitializedEntity HiddenArray =
InitializedEntity::InitializeTemporary(ArrayType);
InitializationKind Kind = InitializationKind::CreateDirectList(
@@ -4092,16 +4085,13 @@ static bool hasCopyOrMoveCtorParam(ASTContext &Ctx,
return Ctx.hasSameUnqualifiedType(ParmT, ClassT);
}
-static OverloadingResult
-ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
- MultiExprArg Args,
- OverloadCandidateSet &CandidateSet,
- QualType DestType,
- DeclContext::lookup_result Ctors,
- OverloadCandidateSet::iterator &Best,
- bool CopyInitializing, bool AllowExplicit,
- bool OnlyListConstructors, bool IsListInit,
- bool SecondStepOfCopyInit = false) {
+static OverloadingResult ResolveConstructorOverload(
+ Sema &S, SourceLocation DeclLoc, MultiExprArg Args,
+ OverloadCandidateSet &CandidateSet, QualType DestType,
+ DeclContext::lookup_result Ctors, OverloadCandidateSet::iterator &Best,
+ bool CopyInitializing, bool AllowExplicit, bool OnlyListConstructors,
+ bool IsListInit, bool RequireActualConstructor,
+ bool SecondStepOfCopyInit = false) {
CandidateSet.clear(OverloadCandidateSet::CSK_InitByConstructor);
CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace());
@@ -4164,7 +4154,7 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
// Note: SecondStepOfCopyInit is only ever true in this case when
// evaluating whether to produce a C++98 compatibility warning.
if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 &&
- !SecondStepOfCopyInit) {
+ !RequireActualConstructor && !SecondStepOfCopyInit) {
Expr *Initializer = Args[0];
auto *SourceRD = Initializer->getType()->getAsCXXRecordDecl();
if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) {
@@ -4232,6 +4222,12 @@ static void TryConstructorInitialization(Sema &S,
return;
}
+ bool RequireActualConstructor =
+ !(Entity.getKind() != InitializedEntity::EK_Base &&
+ Entity.getKind() != InitializedEntity::EK_Delegating &&
+ Entity.getKind() !=
+ InitializedEntity::EK_LambdaToBlockConversionBlockElement);
+
// C++17 [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
@@ -4241,11 +4237,7 @@ static void TryConstructorInitialization(Sema &S,
// class or delegating to another constructor from a mem-initializer.
// ObjC++: Lambda captured by the block in the lambda to block conversion
// should avoid copy elision.
- if (S.getLangOpts().CPlusPlus17 &&
- Entity.getKind() != InitializedEntity::EK_Base &&
- Entity.getKind() != InitializedEntity::EK_Delegating &&
- Entity.getKind() !=
- InitializedEntity::EK_LambdaToBlockConversionBlockElement &&
+ if (S.getLangOpts().CPlusPlus17 && !RequireActualConstructor &&
UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isPRValue() &&
S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) {
// Convert qualifications if necessary.
@@ -4293,11 +4285,10 @@ static void TryConstructorInitialization(Sema &S,
// If the initializer list has no elements and T has a default constructor,
// the first phase is omitted.
if (!(UnwrappedArgs.empty() && S.LookupDefaultConstructor(DestRecordDecl)))
- Result = ResolveConstructorOverload(S, Kind.getLocation(), Args,
- CandidateSet, DestType, Ctors, Best,
- CopyInitialization, AllowExplicit,
- /*OnlyListConstructors=*/true,
- IsListInit);
+ Result = ResolveConstructorOverload(
+ S, Kind.getLocation(), Args, CandidateSet, DestType, Ctors, Best,
+ CopyInitialization, AllowExplicit,
+ /*OnlyListConstructors=*/true, IsListInit, RequireActualConstructor);
}
// C++11 [over.match.list]p1:
@@ -4307,11 +4298,10 @@ static void TryConstructorInitialization(Sema &S,
// elements of the initializer list.
if (Result == OR_No_Viable_Function) {
AsInitializerList = false;
- Result = ResolveConstructorOverload(S, Kind.getLocation(), UnwrappedArgs,
- CandidateSet, DestType, Ctors, Best,
- CopyInitialization, AllowExplicit,
- /*OnlyListConstructors=*/false,
- IsListInit);
+ Result = ResolveConstructorOverload(
+ S, Kind.getLocation(), UnwrappedArgs, CandidateSet, DestType, Ctors,
+ Best, CopyInitialization, AllowExplicit,
+ /*OnlyListConstructors=*/false, IsListInit, RequireActualConstructor);
}
if (Result) {
Sequence.SetOverloadFailure(
@@ -4512,6 +4502,17 @@ static void TryReferenceListInitialization(Sema &S,
if (Sequence) {
if (DestType->isRValueReferenceType() ||
(T1Quals.hasConst() && !T1Quals.hasVolatile())) {
+ if (S.getLangOpts().CPlusPlus20 &&
+ isa<IncompleteArrayType>(T1->getUnqualifiedDesugaredType()) &&
+ DestType->isRValueReferenceType()) {
+ // C++20 [dcl.init.list]p3.10:
+ // List-initialization of an object or reference of type T is defined as
+ // follows:
+ // ..., unless T is “reference to array of unknown bound of U”, in which
+ // case the type of the prvalue is the type of x in the declaration U
+ // x[] H, where H is the initializer list.
+ Sequence.AddQualificationConversionStep(cv1T1, clang::VK_PRValue);
+ }
Sequence.AddReferenceBindingStep(cv1T1IgnoreAS,
/*BindingTemporary=*/true);
if (T1Quals.hasAddressSpace())
@@ -5508,7 +5509,7 @@ static void TryOrBuildParenListInitialization(
if (ResultType.isNull()) {
ResultType = S.Context.getConstantArrayType(
AT->getElementType(), llvm::APInt(/*numBits=*/32, ArrayLength),
- /*SizeExpr=*/nullptr, ArrayType::Normal, 0);
+ /*SizeExpr=*/nullptr, ArraySizeModifier::Normal, 0);
}
} else if (auto *RT = Entity.getType()->getAs<RecordType>()) {
bool IsUnion = RT->isUnionType();
@@ -5657,8 +5658,6 @@ static void TryOrBuildParenListInitialization(
diag::warn_cxx17_compat_aggregate_init_paren_list)
<< Kind.getLocation() << SR << ResultType;
}
-
- return;
}
/// Attempt a user-defined conversion between two types (C++ [dcl.init]),
@@ -6776,6 +6775,7 @@ static ExprResult CopyObject(Sema &S,
S, Loc, CurInitExpr, CandidateSet, T, Ctors, Best,
/*CopyInitializing=*/false, /*AllowExplicit=*/true,
/*OnlyListConstructors=*/false, /*IsListInit=*/false,
+ /*RequireActualConstructor=*/false,
/*SecondStepOfCopyInit=*/true)) {
case OR_Success:
break;
@@ -6878,15 +6878,12 @@ static ExprResult CopyObject(Sema &S,
CurInitExpr->getType());
// Actually perform the constructor call.
- CurInit = S.BuildCXXConstructExpr(Loc, T, Best->FoundDecl, Constructor,
- Elidable,
- ConstructorArgs,
- HadMultipleCandidates,
- /*ListInit*/ false,
- /*StdInitListInit*/ false,
- /*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete,
- SourceRange());
+ CurInit = S.BuildCXXConstructExpr(
+ Loc, T, Best->FoundDecl, Constructor, Elidable, ConstructorArgs,
+ HadMultipleCandidates,
+ /*ListInit*/ false,
+ /*StdInitListInit*/ false,
+ /*ZeroInit*/ false, CXXConstructionKind::Complete, SourceRange());
// If we're supposed to bind temporaries, do so.
if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
@@ -6921,6 +6918,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
S, Loc, CurInitExpr, CandidateSet, CurInitExpr->getType(), Ctors, Best,
/*CopyInitializing=*/false, /*AllowExplicit=*/true,
/*OnlyListConstructors=*/false, /*IsListInit=*/false,
+ /*RequireActualConstructor=*/false,
/*SecondStepOfCopyInit=*/true);
PartialDiagnostic Diag = S.PDiag(diag::warn_cxx98_compat_temp_copy)
@@ -7080,15 +7078,14 @@ PerformConstructorInitialization(Sema &S,
ConstructorInitRequiresZeroInit),
CalleeDecl);
} else {
- CXXConstructExpr::ConstructionKind ConstructKind =
- CXXConstructExpr::CK_Complete;
+ CXXConstructionKind ConstructKind = CXXConstructionKind::Complete;
if (Entity.getKind() == InitializedEntity::EK_Base) {
- ConstructKind = Entity.getBaseSpecifier()->isVirtual() ?
- CXXConstructExpr::CK_VirtualBase :
- CXXConstructExpr::CK_NonVirtualBase;
+ ConstructKind = Entity.getBaseSpecifier()->isVirtual()
+ ? CXXConstructionKind::VirtualBase
+ : CXXConstructionKind::NonVirtualBase;
} else if (Entity.getKind() == InitializedEntity::EK_Delegating) {
- ConstructKind = CXXConstructExpr::CK_Delegating;
+ ConstructKind = CXXConstructionKind::Delegating;
}
// Only get the parenthesis or brace range if it is a list initialization or
@@ -7395,8 +7392,9 @@ static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
return true;
if (!isInStlNamespace(Callee->getParent()))
return false;
- if (!isRecordWithAttr<PointerAttr>(Callee->getThisObjectType()) &&
- !isRecordWithAttr<OwnerAttr>(Callee->getThisObjectType()))
+ if (!isRecordWithAttr<PointerAttr>(
+ Callee->getFunctionObjectParameterType()) &&
+ !isRecordWithAttr<OwnerAttr>(Callee->getFunctionObjectParameterType()))
return false;
if (Callee->getReturnType()->isPointerType() ||
isRecordWithAttr<PointerAttr>(Callee->getReturnType())) {
@@ -7531,7 +7529,7 @@ static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) {
QualType LHST;
auto *MD = dyn_cast<CXXMethodDecl>(FD);
if (MD && MD->isCXXInstanceMember())
- LHST = Ctx.getLValueReferenceType(MD->getThisObjectType());
+ LHST = Ctx.getLValueReferenceType(MD->getFunctionObjectParameterType());
else
LHST = MD->getParamDecl(0)->getType();
if (Ctx.hasSameType(RetT, LHST))
@@ -7581,10 +7579,15 @@ static void visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
VisitLifetimeBoundArg(Callee, ObjectArg);
+ bool CheckCoroCall = false;
+ if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
+ CheckCoroCall = RD->hasAttr<CoroLifetimeBoundAttr>() &&
+ RD->hasAttr<CoroReturnTypeAttr>();
+ }
for (unsigned I = 0,
N = std::min<unsigned>(Callee->getNumParams(), Args.size());
I != N; ++I) {
- if (Callee->getParamDecl(I)->hasAttr<LifetimeBoundAttr>())
+ if (CheckCoroCall || Callee->getParamDecl(I)->hasAttr<LifetimeBoundAttr>())
VisitLifetimeBoundArg(Callee->getParamDecl(I), Args[I]);
}
}
@@ -8868,15 +8871,12 @@ ExprResult InitializationSequence::Perform(Sema &S,
return ExprError();
// Build an expression that constructs a temporary.
- CurInit = S.BuildCXXConstructExpr(Loc, Step->Type,
- FoundFn, Constructor,
- ConstructorArgs,
- HadMultipleCandidates,
- /*ListInit*/ false,
- /*StdInitListInit*/ false,
- /*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete,
- SourceRange());
+ CurInit = S.BuildCXXConstructExpr(
+ Loc, Step->Type, FoundFn, Constructor, ConstructorArgs,
+ HadMultipleCandidates,
+ /*ListInit*/ false,
+ /*StdInitListInit*/ false,
+ /*ZeroInit*/ false, CXXConstructionKind::Complete, SourceRange());
if (CurInit.isInvalid())
return ExprError();
@@ -9233,10 +9233,8 @@ ExprResult InitializationSequence::Perform(Sema &S,
if (const ConstantArrayType *ConstantSource
= S.Context.getAsConstantArrayType(CurInit.get()->getType())) {
*ResultType = S.Context.getConstantArrayType(
- IncompleteDest->getElementType(),
- ConstantSource->getSize(),
- ConstantSource->getSizeExpr(),
- ArrayType::Normal, 0);
+ IncompleteDest->getElementType(), ConstantSource->getSize(),
+ ConstantSource->getSizeExpr(), ArraySizeModifier::Normal, 0);
}
}
}
@@ -9504,7 +9502,7 @@ static void diagnoseListInit(Sema &S, const InitializedEntity &Entity,
E.withConst(),
llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
InitList->getNumInits()),
- nullptr, clang::ArrayType::Normal, 0);
+ nullptr, clang::ArraySizeModifier::Normal, 0);
InitializedEntity HiddenArray =
InitializedEntity::InitializeTemporary(ArrayType);
return diagnoseListInit(S, HiddenArray, InitList);
@@ -10574,7 +10572,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
diag::err_deduced_non_class_template_specialization_type)
<< (int)getTemplateNameKindForDiagnostics(TemplateName) << TemplateName;
if (auto *TD = TemplateName.getAsTemplateDecl())
- Diag(TD->getLocation(), diag::note_template_decl_here);
+ NoteTemplateLocation(*TD);
return QualType();
}
@@ -10629,7 +10627,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
bool AllowExplicit = !Kind.isCopyInit() || ListInit;
- // Return true is the candidate is added successfully, false otherwise.
+ // Return true if the candidate is added successfully, false otherwise.
auto addDeductionCandidate = [&](FunctionTemplateDecl *TD,
CXXDeductionGuideDecl *GD,
DeclAccessPair FoundDecl,