diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp | 1142 |
1 files changed, 628 insertions, 514 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp index 5b0417fa8859..1f7ab49ccdd7 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp @@ -255,7 +255,7 @@ static ParsedType recoverFromTypeInKnownDependentBase(Sema &S, // We found some types in dependent base classes. Recover as if the user // wrote 'typename MyClass::II' instead of 'II'. We'll fully resolve the // lookup during template instantiation. - S.Diag(NameLoc, diag::ext_found_via_dependent_bases_lookup) << &II; + S.Diag(NameLoc, diag::ext_found_in_dependent_base) << &II; ASTContext &Context = S.Context; auto *NNS = NestedNameSpecifier::Create(Context, nullptr, false, @@ -436,9 +436,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Res != ResEnd; ++Res) { if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res) || (AllowDeducedTemplate && getAsTypeTemplateDecl(*Res))) { - if (!IIDecl || - (*Res)->getLocation().getRawEncoding() < - IIDecl->getLocation().getRawEncoding()) + if (!IIDecl || (*Res)->getLocation() < IIDecl->getLocation()) IIDecl = *Res; } } @@ -1184,23 +1182,20 @@ Corrected: return ParsedType::make(T); } - // FIXME: This is context-dependent. We need to defer building the member - // expression until the classification is consumed. - if (FirstDecl->isCXXClassMember()) - return NameClassification::ContextIndependentExpr( - BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, nullptr, - S)); - // If we already know which single declaration is referenced, just annotate - // that declaration directly. + // that declaration directly. Defer resolving even non-overloaded class + // member accesses, as we need to defer certain access checks until we know + // the context. bool ADL = UseArgumentDependentLookup(SS, Result, NextToken.is(tok::l_paren)); - if (Result.isSingleResult() && !ADL) + if (Result.isSingleResult() && !ADL && !FirstDecl->isCXXClassMember()) return NameClassification::NonType(Result.getRepresentativeDecl()); - // Build an UnresolvedLookupExpr. Note that this doesn't depend on the - // context in which we performed classification, so it's safe to do now. - return NameClassification::ContextIndependentExpr( - BuildDeclarationNameExpr(SS, Result, ADL)); + // Otherwise, this is an overload set that we will need to resolve later. + Result.suppressDiagnostics(); + return NameClassification::OverloadSet(UnresolvedLookupExpr::Create( + Context, Result.getNamingClass(), SS.getWithLocInContext(Context), + Result.getLookupNameInfo(), ADL, Result.isOverloadedResult(), + Result.begin(), Result.end())); } ExprResult @@ -1240,6 +1235,30 @@ ExprResult Sema::ActOnNameClassifiedAsNonType(Scope *S, const CXXScopeSpec &SS, return BuildDeclarationNameExpr(SS, Result, ADL); } +ExprResult Sema::ActOnNameClassifiedAsOverloadSet(Scope *S, Expr *E) { + // For an implicit class member access, transform the result into a member + // access expression if necessary. + auto *ULE = cast<UnresolvedLookupExpr>(E); + if ((*ULE->decls_begin())->isCXXClassMember()) { + CXXScopeSpec SS; + SS.Adopt(ULE->getQualifierLoc()); + + // Reconstruct the lookup result. + LookupResult Result(*this, ULE->getName(), ULE->getNameLoc(), + LookupOrdinaryName); + Result.setNamingClass(ULE->getNamingClass()); + for (auto I = ULE->decls_begin(), E = ULE->decls_end(); I != E; ++I) + Result.addDecl(*I, I.getAccess()); + Result.resolveKind(); + return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, + nullptr, S); + } + + // Otherwise, this is already in the form we needed, and no further checks + // are necessary. + return ULE; +} + Sema::TemplateNameKindForDiagnostics Sema::getTemplateNameKindForDiagnostics(TemplateName Name) { auto *TD = Name.getAsTemplateDecl(); @@ -1457,10 +1476,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) { // Out-of-line definitions shouldn't be pushed into scope in C++, unless they // are function-local declarations. - if (getLangOpts().CPlusPlus && D->isOutOfLine() && - !D->getDeclContext()->getRedeclContext()->Equals( - D->getLexicalDeclContext()->getRedeclContext()) && - !D->getLexicalDeclContext()->isFunctionOrMethod()) + if (getLangOpts().CPlusPlus && D->isOutOfLine() && !S->getFnParent()) return; // Template instantiations should also not be pushed into scope. @@ -1742,25 +1758,20 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { if (D->isInvalidDecl()) return false; - bool Referenced = false; if (auto *DD = dyn_cast<DecompositionDecl>(D)) { // For a decomposition declaration, warn if none of the bindings are // referenced, instead of if the variable itself is referenced (which // it is, by the bindings' expressions). - for (auto *BD : DD->bindings()) { - if (BD->isReferenced()) { - Referenced = true; - break; - } - } + for (auto *BD : DD->bindings()) + if (BD->isReferenced()) + return false; } else if (!D->getDeclName()) { return false; } else if (D->isReferenced() || D->isUsed()) { - Referenced = true; + return false; } - if (Referenced || D->hasAttr<UnusedAttr>() || - D->hasAttr<ObjCPreciseLifetimeAttr>()) + if (D->hasAttr<UnusedAttr>() || D->hasAttr<ObjCPreciseLifetimeAttr>()) return false; if (isa<LabelDecl>(D)) @@ -1905,7 +1916,7 @@ static void CheckPoppedLabel(LabelDecl *L, Sema &S) { else Diagnose = L->getStmt() == nullptr; if (Diagnose) - S.Diag(L->getLocation(), diag::err_undeclared_label_use) <<L->getDeclName(); + S.Diag(L->getLocation(), diag::err_undeclared_label_use) << L; } void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { @@ -2019,24 +2030,6 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) { return S; } -/// Looks up the declaration of "struct objc_super" and -/// saves it for later use in building builtin declaration of -/// objc_msgSendSuper and objc_msgSendSuper_stret. If no such -/// pre-existing declaration exists no action takes place. -static void LookupPredefedObjCSuperType(Sema &ThisSema, Scope *S, - IdentifierInfo *II) { - if (!II->isStr("objc_msgSendSuper")) - return; - ASTContext &Context = ThisSema.Context; - - LookupResult Result(ThisSema, &Context.Idents.get("objc_super"), - SourceLocation(), Sema::LookupTagName); - ThisSema.LookupName(Result, S); - if (Result.getResultKind() == LookupResult::Found) - if (const TagDecl *TD = Result.getAsSingle<TagDecl>()) - Context.setObjCSuperType(Context.getTagDeclType(TD)); -} - static StringRef getHeaderName(Builtin::Context &BuiltinInfo, unsigned ID, ASTContext::GetBuiltinTypeError Error) { switch (Error) { @@ -2097,7 +2090,7 @@ FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, QualType Type, NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S, bool ForRedeclaration, SourceLocation Loc) { - LookupPredefedObjCSuperType(*this, S, II); + LookupNecessaryTypesForBuiltin(S, ID); ASTContext::GetBuiltinTypeError Error; QualType R = Context.GetBuiltinType(ID, Error); @@ -2593,6 +2586,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, return false; } else if (const auto *MA = dyn_cast<MinSizeAttr>(Attr)) NewAttr = S.mergeMinSizeAttr(D, *MA); + else if (const auto *SNA = dyn_cast<SwiftNameAttr>(Attr)) + NewAttr = S.mergeSwiftNameAttr(D, *SNA, SNA->getName()); else if (const auto *OA = dyn_cast<OptimizeNoneAttr>(Attr)) NewAttr = S.mergeOptimizeNoneAttr(D, *OA); else if (const auto *InternalLinkageA = dyn_cast<InternalLinkageAttr>(Attr)) @@ -2617,6 +2612,10 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, NewAttr = S.mergeImportModuleAttr(D, *IMA); else if (const auto *INA = dyn_cast<WebAssemblyImportNameAttr>(Attr)) NewAttr = S.mergeImportNameAttr(D, *INA); + else if (const auto *TCBA = dyn_cast<EnforceTCBAttr>(Attr)) + NewAttr = S.mergeEnforceTCBAttr(D, *TCBA); + else if (const auto *TCBLA = dyn_cast<EnforceTCBLeafAttr>(Attr)) + NewAttr = S.mergeEnforceTCBLeafAttr(D, *TCBLA); else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr)) NewAttr = cast<InheritableAttr>(Attr->clone(S.Context)); @@ -2640,8 +2639,11 @@ static const NamedDecl *getDefinition(const Decl *D) { return Def; return VD->getActingDefinition(); } - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - return FD->getDefinition(); + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + const FunctionDecl *Def = nullptr; + if (FD->isDefined(Def, true)) + return Def; + } return nullptr; } @@ -3236,6 +3238,10 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, } } + // If the old declaration was found in an inline namespace and the new + // declaration was qualified, update the DeclContext to match. + adjustDeclContextForDeclaratorDecl(New, Old); + // If the old declaration is invalid, just give up here. if (Old->isInvalidDecl()) return true; @@ -4050,6 +4056,10 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { return New->setInvalidDecl(); } + // If the old declaration was found in an inline namespace and the new + // declaration was qualified, update the DeclContext to match. + adjustDeclContextForDeclaratorDecl(New, Old); + // Ensure the template parameters are compatible. if (NewTemplate && !TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), @@ -4234,7 +4244,6 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { New->setPreviousDecl(Old); if (NewTemplate) NewTemplate->setPreviousDecl(OldTemplate); - adjustDeclContextForDeclaratorDecl(New, Old); // Inherit access appropriately. New->setAccess(Old->getAccess()); @@ -4599,10 +4608,10 @@ Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, if (Tag) Diag(DS.getConstexprSpecLoc(), diag::err_constexpr_tag) << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) - << DS.getConstexprSpecifier(); + << static_cast<int>(DS.getConstexprSpecifier()); else Diag(DS.getConstexprSpecLoc(), diag::err_constexpr_wrong_decl_kind) - << DS.getConstexprSpecifier(); + << static_cast<int>(DS.getConstexprSpecifier()); // Don't emit warnings after this error. return TagD; } @@ -4738,7 +4747,10 @@ Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, if (!DeclaresAnything) { // In C, we allow this as a (popular) extension / bug. Don't bother // producing further diagnostics for redundant qualifiers after this. - Diag(DS.getBeginLoc(), diag::ext_no_declarators) << DS.getSourceRange(); + Diag(DS.getBeginLoc(), (IsExplicitInstantiation || !TemplateParams.empty()) + ? diag::err_no_declarators + : diag::ext_no_declarators) + << DS.getSourceRange(); return TagD; } @@ -5157,7 +5169,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, Diag(DS.getBeginLoc(), diag::ext_no_declarators) << DS.getSourceRange(); // Mock up a declarator. - Declarator Dc(DS, DeclaratorContext::MemberContext); + Declarator Dc(DS, DeclaratorContext::Member); TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S); assert(TInfo && "couldn't build declarator info for anonymous struct/union"); @@ -5254,7 +5266,7 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, assert(Record && "expected a record!"); // Mock up a declarator. - Declarator Dc(DS, DeclaratorContext::TypeNameContext); + Declarator Dc(DS, DeclaratorContext::TypeName); TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S); assert(TInfo && "couldn't build declarator info for anonymous struct"); @@ -5339,8 +5351,8 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { case UnqualifiedIdKind::IK_OperatorFunctionId: NameInfo.setName(Context.DeclarationNames.getCXXOperatorName( Name.OperatorFunctionId.Operator)); - NameInfo.getInfo().CXXOperatorName.BeginOpNameLoc - = Name.OperatorFunctionId.SymbolLocations[0]; + NameInfo.getInfo().CXXOperatorName.BeginOpNameLoc = + Name.OperatorFunctionId.SymbolLocations[0].getRawEncoding(); NameInfo.getInfo().CXXOperatorName.EndOpNameLoc = Name.EndLocation.getRawEncoding(); return NameInfo; @@ -5488,7 +5500,7 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D, // Grab the type from the parser. TypeSourceInfo *TSI = nullptr; QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI); - if (T.isNull() || !T->isDependentType()) break; + if (T.isNull() || !T->isInstantiationDependentType()) break; // Make sure there's a type source info. This isn't really much // of a waste; most dependent types should have type source info @@ -5540,7 +5552,7 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D, } Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) { - D.setFunctionDefinitionKind(FDK_Declaration); + D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration); Decl *Dcl = HandleDeclarator(S, D, MultiTemplateParamsArg()); if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer() && @@ -5929,9 +5941,14 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, const VariableArrayType* VLATy = dyn_cast<VariableArrayType>(T); if (!VLATy) return QualType(); - // FIXME: We should probably handle this case - if (VLATy->getElementType()->isVariablyModifiedType()) - return QualType(); + + QualType ElemTy = VLATy->getElementType(); + if (ElemTy->isVariablyModifiedType()) { + ElemTy = TryToFixInvalidVariablyModifiedType(ElemTy, Context, + SizeIsNegative, Oversized); + if (ElemTy.isNull()) + return QualType(); + } Expr::EvalResult Result; if (!VLATy->getSizeExpr() || @@ -5947,16 +5964,19 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, } // Check whether the array is too large to be addressed. - unsigned ActiveSizeBits - = ConstantArrayType::getNumAddressingBits(Context, VLATy->getElementType(), - Res); + unsigned ActiveSizeBits = + (!ElemTy->isDependentType() && !ElemTy->isVariablyModifiedType() && + !ElemTy->isIncompleteType() && !ElemTy->isUndeducedType()) + ? ConstantArrayType::getNumAddressingBits(Context, ElemTy, Res) + : Res.getActiveBits(); if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) { Oversized = Res; return QualType(); } - return Context.getConstantArrayType( - VLATy->getElementType(), Res, VLATy->getSizeExpr(), ArrayType::Normal, 0); + QualType FoldedArrayType = Context.getConstantArrayType( + ElemTy, Res, VLATy->getSizeExpr(), ArrayType::Normal, 0); + return Qs.apply(Context, FoldedArrayType); } static void @@ -5982,7 +6002,13 @@ FixInvalidVariablyModifiedTypeLoc(TypeLoc SrcTL, TypeLoc DstTL) { ArrayTypeLoc DstATL = DstTL.castAs<ArrayTypeLoc>(); TypeLoc SrcElemTL = SrcATL.getElementLoc(); TypeLoc DstElemTL = DstATL.getElementLoc(); - DstElemTL.initializeFullCopy(SrcElemTL); + if (VariableArrayTypeLoc SrcElemATL = + SrcElemTL.getAs<VariableArrayTypeLoc>()) { + ConstantArrayTypeLoc DstElemATL = DstElemTL.castAs<ConstantArrayTypeLoc>(); + FixInvalidVariablyModifiedTypeLoc(SrcElemATL, DstElemATL); + } else { + DstElemTL.initializeFullCopy(SrcElemTL); + } DstATL.setLBracketLoc(SrcATL.getLBracketLoc()); DstATL.setSizeExpr(SrcATL.getSizeExpr()); DstATL.setRBracketLoc(SrcATL.getRBracketLoc()); @@ -6007,6 +6033,31 @@ TryToFixInvalidVariablyModifiedTypeSourceInfo(TypeSourceInfo *TInfo, return FixedTInfo; } +/// Attempt to fold a variable-sized type to a constant-sized type, returning +/// true if we were successful. +static bool tryToFixVariablyModifiedVarType(Sema &S, TypeSourceInfo *&TInfo, + QualType &T, SourceLocation Loc, + unsigned FailedFoldDiagID) { + bool SizeIsNegative; + llvm::APSInt Oversized; + TypeSourceInfo *FixedTInfo = TryToFixInvalidVariablyModifiedTypeSourceInfo( + TInfo, S.Context, SizeIsNegative, Oversized); + if (FixedTInfo) { + S.Diag(Loc, diag::ext_vla_folded_to_constant); + TInfo = FixedTInfo; + T = FixedTInfo->getType(); + return true; + } + + if (SizeIsNegative) + S.Diag(Loc, diag::err_typecheck_negative_array_size); + else if (Oversized.getBoolValue()) + S.Diag(Loc, diag::err_array_too_large) << Oversized.toString(10); + else if (FailedFoldDiagID) + S.Diag(Loc, FailedFoldDiagID); + return false; +} + /// Register the given locally-scoped extern "C" declaration so /// that it can be found later for redeclarations. We include any extern "C" /// declaration that is not visible in the translation unit here, not just @@ -6066,7 +6117,7 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, << getLangOpts().CPlusPlus17; if (D.getDeclSpec().hasConstexprSpecifier()) Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr) - << 1 << D.getDeclSpec().getConstexprSpecifier(); + << 1 << static_cast<int>(D.getDeclSpec().getConstexprSpecifier()); if (D.getName().Kind != UnqualifiedIdKind::IK_Identifier) { if (D.getName().Kind == UnqualifiedIdKind::IK_DeductionGuideName) @@ -6112,7 +6163,7 @@ Sema::CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *NewTD) { SizeIsNegative, Oversized); if (FixedTInfo) { - Diag(NewTD->getLocation(), diag::warn_illegal_constant_array_size); + Diag(NewTD->getLocation(), diag::ext_vla_folded_to_constant); NewTD->setTypeSourceInfo(FixedTInfo); } else { if (SizeIsNegative) @@ -6494,7 +6545,7 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl, // special MSVC extension: in the last case, the declaration is treated as if // it were marked dllexport. bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false; - bool IsMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft(); + bool IsMicrosoftABI = S.Context.getTargetInfo().shouldDLLImportComdatSymbols(); if (const auto *VD = dyn_cast<VarDecl>(NewDecl)) { // Ignore static data because out-of-line definitions are diagnosed // separately. @@ -6508,9 +6559,9 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl, } if (OldImportAttr && !HasNewAttr && - (!IsInline || (IsMicrosoft && IsTemplate)) && !IsStaticDataMember && + (!IsInline || (IsMicrosoftABI && IsTemplate)) && !IsStaticDataMember && !NewDecl->isLocalExternDecl() && !IsQualifiedFriend) { - if (IsMicrosoft && IsDefinition) { + if (IsMicrosoftABI && IsDefinition) { S.Diag(NewDecl->getLocation(), diag::warn_redeclaration_without_import_attribute) << NewDecl; @@ -6527,7 +6578,7 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl, OldDecl->dropAttr<DLLImportAttr>(); NewDecl->dropAttr<DLLImportAttr>(); } - } else if (IsInline && OldImportAttr && !IsMicrosoft) { + } else if (IsInline && OldImportAttr && !IsMicrosoftABI) { // In MinGW, seeing a function declared inline drops the dllimport // attribute. OldDecl->dropAttr<DLLImportAttr>(); @@ -6706,14 +6757,16 @@ static bool diagnoseOpenCLTypes(Scope *S, Sema &Se, Declarator &D, } // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed. - QualType NR = R; - while (NR->isPointerType()) { - if (NR->isFunctionPointerType()) { - Se.Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer); - D.setInvalidType(); - return false; + if (!Se.getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) { + QualType NR = R; + while (NR->isPointerType() || NR->isMemberFunctionPointerType()) { + if (NR->isFunctionPointerType() || NR->isMemberFunctionPointerType()) { + Se.Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer); + D.setInvalidType(); + return false; + } + NR = NR->getPointeeType(); } - NR = NR->getPointeeType(); } if (!Se.getOpenCLOptions().isEnabled("cl_khr_fp16")) { @@ -6845,6 +6898,12 @@ NamedDecl *Sema::ActOnVariableDeclarator( } } + // If this variable has a variable-modified type and an initializer, try to + // fold to a constant-sized type. This is otherwise invalid. + if (D.hasInitializer() && R->isVariablyModifiedType()) + tryToFixVariablyModifiedVarType(*this, TInfo, R, D.getIdentifierLoc(), + /*DiagID=*/0); + bool IsMemberSpecialization = false; bool IsVariableTemplateSpecialization = false; bool IsPartialSpecialization = false; @@ -6963,19 +7022,18 @@ NamedDecl *Sema::ActOnVariableDeclarator( TemplateParams->getRAngleLoc()); TemplateParams = nullptr; } else { + // Check that we can declare a template here. + if (CheckTemplateDeclScope(S, TemplateParams)) + return nullptr; + if (D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId) { // This is an explicit specialization or a partial specialization. - // FIXME: Check that we can declare a specialization here. IsVariableTemplateSpecialization = true; IsPartialSpecialization = TemplateParams->size() > 0; } else { // if (TemplateParams->size() > 0) // This is a template declaration. IsVariableTemplate = true; - // Check that we can declare a template here. - if (CheckTemplateDeclScope(S, TemplateParams)) - return nullptr; - // Only C++1y supports variable templates (N3651). Diag(D.getIdentifierLoc(), getLangOpts().CPlusPlus14 @@ -6984,6 +7042,10 @@ NamedDecl *Sema::ActOnVariableDeclarator( } } } else { + // Check that we can declare a member specialization here. + if (!TemplateParamLists.empty() && IsMemberSpecialization && + CheckTemplateDeclScope(S, TemplateParamLists.back())) + return nullptr; assert((Invalid || D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) && "should have a 'template<>' for this decl"); @@ -7103,16 +7165,16 @@ NamedDecl *Sema::ActOnVariableDeclarator( } switch (D.getDeclSpec().getConstexprSpecifier()) { - case CSK_unspecified: + case ConstexprSpecKind::Unspecified: break; - case CSK_consteval: + case ConstexprSpecKind::Consteval: Diag(D.getDeclSpec().getConstexprSpecLoc(), - diag::err_constexpr_wrong_decl_kind) - << D.getDeclSpec().getConstexprSpecifier(); + diag::err_constexpr_wrong_decl_kind) + << static_cast<int>(D.getDeclSpec().getConstexprSpecifier()); LLVM_FALLTHROUGH; - case CSK_constexpr: + case ConstexprSpecKind::Constexpr: NewVD->setConstexpr(true); MaybeAddCUDAConstantAttr(NewVD); // C++1z [dcl.spec.constexpr]p1: @@ -7124,7 +7186,7 @@ NamedDecl *Sema::ActOnVariableDeclarator( NewVD->setImplicitlyInline(); break; - case CSK_constinit: + case ConstexprSpecKind::Constinit: if (!NewVD->hasGlobalStorage()) Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_constinit_local_variable); @@ -7166,9 +7228,10 @@ NamedDecl *Sema::ActOnVariableDeclarator( << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); else if (NewVD->hasLocalStorage()) Diag(NewVD->getLocation(), diag::err_module_private_local) - << 0 << NewVD->getDeclName() - << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) - << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); + << 0 << NewVD + << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) + << FixItHint::CreateRemoval( + D.getDeclSpec().getModulePrivateSpecLoc()); else { NewVD->setModulePrivate(); if (NewTemplate) @@ -7975,7 +8038,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { return; } - Diag(NewVD->getLocation(), diag::warn_illegal_constant_array_size); + Diag(NewVD->getLocation(), diag::ext_vla_folded_to_constant); NewVD->setType(FixedT); NewVD->setTypeSourceInfo(FixedTInfo); } @@ -8015,6 +8078,14 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { NewVD->setInvalidDecl(); return; } + + // PPC MMA non-pointer types are not allowed as non-local variable types. + if (Context.getTargetInfo().getTriple().isPPC64() && + !NewVD->isLocalVarDecl() && + CheckPPCMMAType(T, NewVD->getLocation())) { + NewVD->setInvalidDecl(); + return; + } } /// Perform semantic checking on a newly-created variable @@ -8049,73 +8120,54 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) { return false; } -namespace { -struct FindOverriddenMethod { - Sema *S; - CXXMethodDecl *Method; - - /// Member lookup function that determines whether a given C++ - /// method overrides a method in a base class, to be used with - /// CXXRecordDecl::lookupInBases(). - bool operator()(const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { - RecordDecl *BaseRecord = - Specifier->getType()->castAs<RecordType>()->getDecl(); +/// AddOverriddenMethods - See if a method overrides any in the base classes, +/// and if so, check that it's a valid override and remember it. +bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) { + llvm::SmallPtrSet<const CXXMethodDecl*, 4> Overridden; - DeclarationName Name = Method->getDeclName(); + // Look for methods in base classes that this method might override. + CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false, + /*DetectVirtual=*/false); + auto VisitBase = [&] (const CXXBaseSpecifier *Specifier, CXXBasePath &Path) { + CXXRecordDecl *BaseRecord = Specifier->getType()->getAsCXXRecordDecl(); + DeclarationName Name = MD->getDeclName(); - // FIXME: Do we care about other names here too? if (Name.getNameKind() == DeclarationName::CXXDestructorName) { // We really want to find the base class destructor here. - QualType T = S->Context.getTypeDeclType(BaseRecord); - CanQualType CT = S->Context.getCanonicalType(T); - - Name = S->Context.DeclarationNames.getCXXDestructorName(CT); - } - - for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty(); - Path.Decls = Path.Decls.slice(1)) { - NamedDecl *D = Path.Decls.front(); - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { - if (MD->isVirtual() && - !S->IsOverload( - Method, MD, /*UseMemberUsingDeclRules=*/false, - /*ConsiderCudaAttrs=*/true, - // C++2a [class.virtual]p2 does not consider requires clauses - // when overriding. - /*ConsiderRequiresClauses=*/false)) - return true; + QualType T = Context.getTypeDeclType(BaseRecord); + CanQualType CT = Context.getCanonicalType(T); + Name = Context.DeclarationNames.getCXXDestructorName(CT); + } + + for (NamedDecl *BaseND : BaseRecord->lookup(Name)) { + CXXMethodDecl *BaseMD = + dyn_cast<CXXMethodDecl>(BaseND->getCanonicalDecl()); + if (!BaseMD || !BaseMD->isVirtual() || + IsOverload(MD, BaseMD, /*UseMemberUsingDeclRules=*/false, + /*ConsiderCudaAttrs=*/true, + // C++2a [class.virtual]p2 does not consider requires + // clauses when overriding. + /*ConsiderRequiresClauses=*/false)) + continue; + + if (Overridden.insert(BaseMD).second) { + MD->addOverriddenMethod(BaseMD); + CheckOverridingFunctionReturnType(MD, BaseMD); + CheckOverridingFunctionAttributes(MD, BaseMD); + CheckOverridingFunctionExceptionSpec(MD, BaseMD); + CheckIfOverriddenFunctionIsMarkedFinal(MD, BaseMD); } + + // A method can only override one function from each base class. We + // don't track indirectly overridden methods from bases of bases. + return true; } return false; - } -}; -} // end anonymous namespace - -/// AddOverriddenMethods - See if a method overrides any in the base classes, -/// and if so, check that it's a valid override and remember it. -bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) { - // Look for methods in base classes that this method might override. - CXXBasePaths Paths; - FindOverriddenMethod FOM; - FOM.Method = MD; - FOM.S = this; - bool AddedAny = false; - if (DC->lookupInBases(FOM, Paths)) { - for (auto *I : Paths.found_decls()) { - if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(I)) { - MD->addOverriddenMethod(OldMD->getCanonicalDecl()); - if (!CheckOverridingFunctionReturnType(MD, OldMD) && - !CheckOverridingFunctionAttributes(MD, OldMD) && - !CheckOverridingFunctionExceptionSpec(MD, OldMD) && - !CheckIfOverriddenFunctionIsMarkedFinal(MD, OldMD)) { - AddedAny = true; - } - } - } - } + }; - return AddedAny; + DC->lookupInBases(VisitBase, Paths); + return !Overridden.empty(); } namespace { @@ -8394,7 +8446,7 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, NewFD = FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), NameInfo, R, TInfo, SC, isInline, HasPrototype, - CSK_unspecified, + ConstexprSpecKind::Unspecified, /*TrailingRequiresClause=*/nullptr); if (D.isInvalidType()) NewFD->setInvalidDecl(); @@ -8405,11 +8457,11 @@ static FunctionDecl *CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, ExplicitSpecifier ExplicitSpecifier = D.getDeclSpec().getExplicitSpecifier(); ConstexprSpecKind ConstexprKind = D.getDeclSpec().getConstexprSpecifier(); - if (ConstexprKind == CSK_constinit) { + if (ConstexprKind == ConstexprSpecKind::Constinit) { SemaRef.Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_constexpr_wrong_decl_kind) - << ConstexprKind; - ConstexprKind = CSK_unspecified; + << static_cast<int>(ConstexprKind); + ConstexprKind = ConstexprSpecKind::Unspecified; D.getMutableDeclSpec().ClearConstexprSpec(); } Expr *TrailingRequiresClause = D.getTrailingRequiresClause(); @@ -8563,12 +8615,21 @@ static bool isOpenCLSizeDependentType(ASTContext &C, QualType Ty) { static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) { if (PT->isPointerType()) { QualType PointeeType = PT->getPointeeType(); - if (PointeeType->isPointerType()) - return PtrPtrKernelParam; if (PointeeType.getAddressSpace() == LangAS::opencl_generic || PointeeType.getAddressSpace() == LangAS::opencl_private || PointeeType.getAddressSpace() == LangAS::Default) return InvalidAddrSpacePtrKernelParam; + + if (PointeeType->isPointerType()) { + // This is a pointer to pointer parameter. + // Recursively check inner type. + OpenCLParamType ParamKind = getOpenCLKernelParameterType(S, PointeeType); + if (ParamKind == InvalidAddrSpacePtrKernelParam || + ParamKind == InvalidKernelParam) + return ParamKind; + + return PtrPtrKernelParam; + } return PtrKernelParam; } @@ -8621,11 +8682,17 @@ static void checkIsValidOpenCLKernelParameter( switch (getOpenCLKernelParameterType(S, PT)) { case PtrPtrKernelParam: - // OpenCL v1.2 s6.9.a: - // A kernel function argument cannot be declared as a - // pointer to a pointer type. - S.Diag(Param->getLocation(), diag::err_opencl_ptrptr_kernel_param); - D.setInvalidType(); + // OpenCL v3.0 s6.11.a: + // A kernel function argument cannot be declared as a pointer to a pointer + // type. [...] This restriction only applies to OpenCL C 1.2 or below. + if (S.getLangOpts().OpenCLVersion < 120 && + !S.getLangOpts().OpenCLCPlusPlus) { + S.Diag(Param->getLocation(), diag::err_opencl_ptrptr_kernel_param); + D.setInvalidType(); + return; + } + + ValidTypes.insert(PT.getTypePtr()); return; case InvalidAddrSpacePtrKernelParam: @@ -8909,13 +8976,13 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, TemplateParamLists, isFriend, isMemberSpecialization, Invalid); if (TemplateParams) { + // Check that we can declare a template here. + if (CheckTemplateDeclScope(S, TemplateParams)) + NewFD->setInvalidDecl(); + if (TemplateParams->size() > 0) { // This is a function template - // Check that we can declare a template here. - if (CheckTemplateDeclScope(S, TemplateParams)) - NewFD->setInvalidDecl(); - // A destructor cannot be a template. if (Name.getNameKind() == DeclarationName::CXXDestructorName) { Diag(NewFD->getLocation(), diag::err_destructor_template); @@ -8974,6 +9041,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } } else { + // Check that we can declare a template here. + if (!TemplateParamLists.empty() && isMemberSpecialization && + CheckTemplateDeclScope(S, TemplateParamLists.back())) + NewFD->setInvalidDecl(); + // All template param lists were matched against the scope specifier: // this is NOT (an explicit specialization of) a template. if (TemplateParamLists.size() > 0) @@ -9068,8 +9140,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - if (ConstexprSpecKind ConstexprKind = - D.getDeclSpec().getConstexprSpecifier()) { + ConstexprSpecKind ConstexprKind = D.getDeclSpec().getConstexprSpecifier(); + if (ConstexprKind != ConstexprSpecKind::Unspecified) { // C++11 [dcl.constexpr]p2: constexpr functions and constexpr constructors // are implicitly inline. NewFD->setImplicitlyInline(); @@ -9078,15 +9150,18 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // be either constructors or to return a literal type. Therefore, // destructors cannot be declared constexpr. if (isa<CXXDestructorDecl>(NewFD) && - (!getLangOpts().CPlusPlus20 || ConstexprKind == CSK_consteval)) { + (!getLangOpts().CPlusPlus20 || + ConstexprKind == ConstexprSpecKind::Consteval)) { Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_constexpr_dtor) - << ConstexprKind; - NewFD->setConstexprKind(getLangOpts().CPlusPlus20 ? CSK_unspecified : CSK_constexpr); + << static_cast<int>(ConstexprKind); + NewFD->setConstexprKind(getLangOpts().CPlusPlus20 + ? ConstexprSpecKind::Unspecified + : ConstexprSpecKind::Constexpr); } // C++20 [dcl.constexpr]p2: An allocation function, or a // deallocation function shall not be declared with the consteval // specifier. - if (ConstexprKind == CSK_consteval && + if (ConstexprKind == ConstexprSpecKind::Consteval && (NewFD->getOverloadedOperator() == OO_New || NewFD->getOverloadedOperator() == OO_Array_New || NewFD->getOverloadedOperator() == OO_Delete || @@ -9094,7 +9169,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_consteval_decl_kind) << NewFD; - NewFD->setConstexprKind(CSK_constexpr); + NewFD->setConstexprKind(ConstexprSpecKind::Constexpr); } } @@ -9125,17 +9200,17 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // If a function is defined as defaulted or deleted, mark it as such now. // We'll do the relevant checks on defaulted / deleted functions later. switch (D.getFunctionDefinitionKind()) { - case FDK_Declaration: - case FDK_Definition: - break; + case FunctionDefinitionKind::Declaration: + case FunctionDefinitionKind::Definition: + break; - case FDK_Defaulted: - NewFD->setDefaulted(); - break; + case FunctionDefinitionKind::Defaulted: + NewFD->setDefaulted(); + break; - case FDK_Deleted: - NewFD->setDeletedAsWritten(); - break; + case FunctionDefinitionKind::Deleted: + NewFD->setDeletedAsWritten(); + break; } if (isa<CXXMethodDecl>(NewFD) && DC == CurContext && @@ -9345,6 +9420,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } + if (LangOpts.SYCLIsDevice || (LangOpts.OpenMP && LangOpts.OpenMPIsDevice)) + checkDeviceDecl(NewFD, D.getBeginLoc()); + if (!getLangOpts().CPlusPlus) { // Perform semantic checking on the function declaration. if (!NewFD->isInvalidDecl() && NewFD->isMain()) @@ -9452,12 +9530,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // that either the specialized function type or the specialized // template is dependent, and therefore matching will fail. In // this case, don't check the specialization yet. - bool InstantiationDependent = false; if (isFunctionTemplateSpecialization && isFriend && (NewFD->getType()->isDependentType() || DC->isDependentContext() || - TemplateSpecializationType::anyDependentTemplateArguments( - TemplateArgs, - InstantiationDependent))) { + TemplateSpecializationType::anyInstantiationDependentTemplateArguments( + TemplateArgs.arguments()))) { assert(HasExplicitTemplateArgs && "friend function specialization without template args"); if (CheckDependentFunctionTemplateSpecialization(NewFD, TemplateArgs, @@ -9642,7 +9718,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewFD->addAttr(BuiltinAttr::CreateImplicit(Context, BuiltinID)); } else { ASTContext::GetBuiltinTypeError Error; - LookupPredefedObjCSuperType(*this, S, NewFD->getIdentifier()); + LookupNecessaryTypesForBuiltin(S, BuiltinID); QualType BuiltinType = Context.GetBuiltinType(BuiltinID, Error); if (!Error && !BuiltinType.isNull() && @@ -9836,17 +9912,17 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // because Sema::ActOnStartOfFunctionDef has not been called yet. if (const auto *NBA = NewFD->getAttr<NoBuiltinAttr>()) switch (D.getFunctionDefinitionKind()) { - case FDK_Defaulted: - case FDK_Deleted: + case FunctionDefinitionKind::Defaulted: + case FunctionDefinitionKind::Deleted: Diag(NBA->getLocation(), diag::err_attribute_no_builtin_on_defaulted_deleted_function) << NBA->getSpelling(); break; - case FDK_Declaration: + case FunctionDefinitionKind::Declaration: Diag(NBA->getLocation(), diag::err_attribute_no_builtin_on_non_definition) << NBA->getSpelling(); break; - case FDK_Definition: + case FunctionDefinitionKind::Definition: break; } @@ -10019,31 +10095,50 @@ static bool CheckMultiVersionValue(Sema &S, const FunctionDecl *FD) { // multiversion functions. static bool AttrCompatibleWithMultiVersion(attr::Kind Kind, MultiVersionKind MVType) { + // Note: this list/diagnosis must match the list in + // checkMultiversionAttributesAllSame. switch (Kind) { default: return false; case attr::Used: return MVType == MultiVersionKind::Target; + case attr::NonNull: + case attr::NoThrow: + return true; } } -static bool HasNonMultiVersionAttributes(const FunctionDecl *FD, - MultiVersionKind MVType) { +static bool checkNonMultiVersionCompatAttributes(Sema &S, + const FunctionDecl *FD, + const FunctionDecl *CausedFD, + MultiVersionKind MVType) { + bool IsCPUSpecificCPUDispatchMVType = + MVType == MultiVersionKind::CPUDispatch || + MVType == MultiVersionKind::CPUSpecific; + const auto Diagnose = [FD, CausedFD, IsCPUSpecificCPUDispatchMVType]( + Sema &S, const Attr *A) { + S.Diag(FD->getLocation(), diag::err_multiversion_disallowed_other_attr) + << IsCPUSpecificCPUDispatchMVType << A; + if (CausedFD) + S.Diag(CausedFD->getLocation(), diag::note_multiversioning_caused_here); + return true; + }; + for (const Attr *A : FD->attrs()) { switch (A->getKind()) { case attr::CPUDispatch: case attr::CPUSpecific: if (MVType != MultiVersionKind::CPUDispatch && MVType != MultiVersionKind::CPUSpecific) - return true; + return Diagnose(S, A); break; case attr::Target: if (MVType != MultiVersionKind::Target) - return true; + return Diagnose(S, A); break; default: if (!AttrCompatibleWithMultiVersion(A->getKind(), MVType)) - return true; + return Diagnose(S, A); break; } } @@ -10177,18 +10272,12 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, MVType == MultiVersionKind::CPUDispatch || MVType == MultiVersionKind::CPUSpecific; - // For now, disallow all other attributes. These should be opt-in, but - // an analysis of all of them is a future FIXME. - if (CausesMV && OldFD && HasNonMultiVersionAttributes(OldFD, MVType)) { - S.Diag(OldFD->getLocation(), diag::err_multiversion_no_other_attrs) - << IsCPUSpecificCPUDispatchMVType; - S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); + if (CausesMV && OldFD && + checkNonMultiVersionCompatAttributes(S, OldFD, NewFD, MVType)) return true; - } - if (HasNonMultiVersionAttributes(NewFD, MVType)) - return S.Diag(NewFD->getLocation(), diag::err_multiversion_no_other_attrs) - << IsCPUSpecificCPUDispatchMVType; + if (checkNonMultiVersionCompatAttributes(S, NewFD, nullptr, MVType)) + return true; // Only allow transition to MultiVersion if it hasn't been used. if (OldFD && CausesMV && OldFD->isUsed(false)) @@ -10641,6 +10730,12 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, MergeTypeWithPrevious, Previous)) return Redeclaration; + // PPC MMA non-pointer types are not allowed as function return types. + if (Context.getTargetInfo().getTriple().isPPC64() && + CheckPPCMMAType(NewFD->getReturnType(), NewFD->getLocation())) { + NewFD->setInvalidDecl(); + } + // C++11 [dcl.constexpr]p8: // A constexpr specifier for a non-static member function that is not // a constructor declares that member function to be const. @@ -10703,7 +10798,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewTemplateDecl->mergePrevDecl(OldTemplateDecl); NewFD->setPreviousDeclaration(OldFD); - adjustDeclContextForDeclaratorDecl(NewFD, OldFD); if (NewFD->isCXXClassMember()) { NewFD->setAccess(OldTemplateDecl->getAccess()); NewTemplateDecl->setAccess(OldTemplateDecl->getAccess()); @@ -10730,7 +10824,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, auto *OldFD = cast<FunctionDecl>(OldDecl); // This needs to happen first so that 'inline' propagates. NewFD->setPreviousDeclaration(OldFD); - adjustDeclContextForDeclaratorDecl(NewFD, OldFD); if (NewFD->isCXXClassMember()) NewFD->setAccess(OldFD->getAccess()); } @@ -10760,6 +10853,9 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } } + if (LangOpts.OpenMP) + ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(NewFD); + // Semantic checking for this function declaration (in isolation). if (getLangOpts().CPlusPlus) { @@ -10838,7 +10934,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // declaration against the expected type for the builtin. if (unsigned BuiltinID = NewFD->getBuiltinID()) { ASTContext::GetBuiltinTypeError Error; - LookupPredefedObjCSuperType(*this, S, NewFD->getIdentifier()); + LookupNecessaryTypesForBuiltin(S, BuiltinID); QualType T = Context.GetBuiltinType(BuiltinID, Error); // If the type of the builtin differs only in its exception // specification, that's OK. @@ -10934,7 +11030,7 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { Diag(DS.getConstexprSpecLoc(), diag::err_constexpr_main) << FD->isConsteval() << FixItHint::CreateRemoval(DS.getConstexprSpecLoc()); - FD->setConstexprKind(CSK_unspecified); + FD->setConstexprKind(ConstexprSpecKind::Unspecified); } if (getLangOpts().OpenCL) { @@ -11090,8 +11186,14 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) { // except that the aforementioned are allowed in unevaluated // expressions. Everything else falls under the // "may accept other forms of constant expressions" exception. - // (We never end up here for C++, so the constant expression - // rules there don't matter.) + // + // Regular C++ code will not end up here (exceptions: language extensions, + // OpenCL C++ etc), so the constant expression rules there don't matter. + if (Init->isValueDependent()) { + assert(Init->containsErrors() && + "Dependent code should only occur in error-recovery path."); + return true; + } const Expr *Culprit; if (Init->isConstantInitializer(Context, false, &Culprit)) return false; @@ -12056,7 +12158,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // Try to correct any TypoExprs in the initialization arguments. for (size_t Idx = 0; Idx < Args.size(); ++Idx) { ExprResult Res = CorrectDelayedTyposInExpr( - Args[Idx], VDecl, /*RecoverUncorrectedTypos=*/false, + Args[Idx], VDecl, /*RecoverUncorrectedTypos=*/true, [this, Entity, Kind](Expr *E) { InitializationSequence Init(*this, Entity, Kind, MultiExprArg(E)); return Init.Failed() ? ExprError() : E; @@ -12425,7 +12527,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { !Context.getTargetInfo().getCXXABI().isMicrosoft()) { Diag(Var->getLocation(), diag::err_constexpr_static_mem_var_requires_init) - << Var->getDeclName(); + << Var; Var->setInvalidDecl(); return; } @@ -12447,6 +12549,17 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { } if (!Var->isInvalidDecl() && RealDecl->hasAttr<LoaderUninitializedAttr>()) { + if (Var->getStorageClass() == SC_Extern) { + Diag(Var->getLocation(), diag::err_loader_uninitialized_extern_decl) + << Var; + Var->setInvalidDecl(); + return; + } + if (RequireCompleteType(Var->getLocation(), Var->getType(), + diag::err_typecheck_decl_incomplete_type)) { + Var->setInvalidDecl(); + return; + } if (CXXRecordDecl *RD = Var->getType()->getAsCXXRecordDecl()) { if (!RD->hasTrivialDefaultConstructor()) { Diag(Var->getLocation(), diag::err_loader_uninitialized_trivial_ctor); @@ -12454,12 +12567,6 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { return; } } - if (Var->getStorageClass() == SC_Extern) { - Diag(Var->getLocation(), diag::err_loader_uninitialized_extern_decl) - << Var; - Var->setInvalidDecl(); - return; - } } VarDecl::DefinitionKind DefKind = Var->isThisDeclarationADefinition(); @@ -12558,8 +12665,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { // definitions with reference type. if (Type->isReferenceType()) { Diag(Var->getLocation(), diag::err_reference_var_requires_init) - << Var->getDeclName() - << SourceRange(Var->getLocation(), Var->getLocation()); + << Var << SourceRange(Var->getLocation(), Var->getLocation()); Var->setInvalidDecl(); return; } @@ -12690,9 +12796,21 @@ void Sema::ActOnCXXForRangeDecl(Decl *D) { Error = 4; break; } + + // for-range-declaration cannot be given a storage class specifier con't. + switch (VD->getTSCSpec()) { + case TSCS_thread_local: + Error = 6; + break; + case TSCS___thread: + case TSCS__Thread_local: + case TSCS_unspecified: + break; + } + if (Error != -1) { Diag(VD->getOuterLocStart(), diag::err_for_range_storage_class) - << VD->getDeclName() << Error; + << VD << Error; D->setInvalidDecl(); } } @@ -12714,7 +12832,7 @@ Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, DS.SetTypeSpecType(DeclSpec::TST_auto, IdentLoc, PrevSpec, DiagID, getPrintingPolicy()); - Declarator D(DS, DeclaratorContext::ForContext); + Declarator D(DS, DeclaratorContext::ForInit); D.SetIdentifier(Ident, IdentLoc); D.takeAttributes(Attrs, AttrEnd); @@ -12858,20 +12976,64 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { AttributeCommonInfo::AS_Pragma)); } + if (!var->getType()->isStructureType() && var->hasInit() && + isa<InitListExpr>(var->getInit())) { + const auto *ILE = cast<InitListExpr>(var->getInit()); + unsigned NumInits = ILE->getNumInits(); + if (NumInits > 2) + for (unsigned I = 0; I < NumInits; ++I) { + const auto *Init = ILE->getInit(I); + if (!Init) + break; + const auto *SL = dyn_cast<StringLiteral>(Init->IgnoreImpCasts()); + if (!SL) + break; + + unsigned NumConcat = SL->getNumConcatenated(); + // Diagnose missing comma in string array initialization. + // Do not warn when all the elements in the initializer are concatenated + // together. Do not warn for macros too. + if (NumConcat == 2 && !SL->getBeginLoc().isMacroID()) { + bool OnlyOneMissingComma = true; + for (unsigned J = I + 1; J < NumInits; ++J) { + const auto *Init = ILE->getInit(J); + if (!Init) + break; + const auto *SLJ = dyn_cast<StringLiteral>(Init->IgnoreImpCasts()); + if (!SLJ || SLJ->getNumConcatenated() > 1) { + OnlyOneMissingComma = false; + break; + } + } + + if (OnlyOneMissingComma) { + SmallVector<FixItHint, 1> Hints; + for (unsigned i = 0; i < NumConcat - 1; ++i) + Hints.push_back(FixItHint::CreateInsertion( + PP.getLocForEndOfToken(SL->getStrTokenLoc(i)), ",")); + + Diag(SL->getStrTokenLoc(1), + diag::warn_concatenated_literal_array_init) + << Hints; + Diag(SL->getBeginLoc(), + diag::note_concatenated_string_literal_silence); + } + // In any case, stop now. + break; + } + } + } + // All the following checks are C++ only. if (!getLangOpts().CPlusPlus) { - // If this variable must be emitted, add it as an initializer for the - // current module. - if (Context.DeclMustBeEmitted(var) && !ModuleScopes.empty()) - Context.addModuleInitializer(ModuleScopes.back().Module, var); - return; + // If this variable must be emitted, add it as an initializer for the + // current module. + if (Context.DeclMustBeEmitted(var) && !ModuleScopes.empty()) + Context.addModuleInitializer(ModuleScopes.back().Module, var); + return; } - if (auto *DD = dyn_cast<DecompositionDecl>(var)) - CheckCompleteDecompositionDeclaration(DD); - QualType type = var->getType(); - if (type->isDependentType()) return; if (var->hasAttr<BlocksAttr>()) getCurFunction()->addByrefBlockVar(var); @@ -12880,79 +13042,93 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { bool IsGlobal = GlobalStorage && !var->isStaticLocal(); QualType baseType = Context.getBaseElementType(type); - if (Init && !Init->isValueDependent()) { - if (var->isConstexpr()) { - SmallVector<PartialDiagnosticAt, 8> Notes; - if (!var->evaluateValue(Notes) || !var->isInitICE()) { - SourceLocation DiagLoc = var->getLocation(); - // If the note doesn't add any useful information other than a source - // location, fold it into the primary diagnostic. - if (Notes.size() == 1 && Notes[0].second.getDiagID() == - diag::note_invalid_subexpr_in_const_expr) { - DiagLoc = Notes[0].first; - Notes.clear(); - } - Diag(DiagLoc, diag::err_constexpr_var_requires_const_init) - << var << Init->getSourceRange(); - for (unsigned I = 0, N = Notes.size(); I != N; ++I) - Diag(Notes[I].first, Notes[I].second); + // Check whether the initializer is sufficiently constant. + if (!type->isDependentType() && Init && !Init->isValueDependent() && + (GlobalStorage || var->isConstexpr() || + var->mightBeUsableInConstantExpressions(Context))) { + // If this variable might have a constant initializer or might be usable in + // constant expressions, check whether or not it actually is now. We can't + // do this lazily, because the result might depend on things that change + // later, such as which constexpr functions happen to be defined. + SmallVector<PartialDiagnosticAt, 8> Notes; + bool HasConstInit; + if (!getLangOpts().CPlusPlus11) { + // Prior to C++11, in contexts where a constant initializer is required, + // the set of valid constant initializers is described by syntactic rules + // in [expr.const]p2-6. + // FIXME: Stricter checking for these rules would be useful for constinit / + // -Wglobal-constructors. + HasConstInit = checkConstInit(); + + // Compute and cache the constant value, and remember that we have a + // constant initializer. + if (HasConstInit) { + (void)var->checkForConstantInitialization(Notes); + Notes.clear(); + } else if (CacheCulprit) { + Notes.emplace_back(CacheCulprit->getExprLoc(), + PDiag(diag::note_invalid_subexpr_in_const_expr)); + Notes.back().second << CacheCulprit->getSourceRange(); } - } else if (var->mightBeUsableInConstantExpressions(Context)) { - // Check whether the initializer of a const variable of integral or - // enumeration type is an ICE now, since we can't tell whether it was - // initialized by a constant expression if we check later. - var->checkInitIsICE(); - } - - // Don't emit further diagnostics about constexpr globals since they - // were just diagnosed. - if (!var->isConstexpr() && GlobalStorage && var->hasAttr<ConstInitAttr>()) { - // FIXME: Need strict checking in C++03 here. - bool DiagErr = getLangOpts().CPlusPlus11 - ? !var->checkInitIsICE() : !checkConstInit(); - if (DiagErr) { - auto *Attr = var->getAttr<ConstInitAttr>(); - Diag(var->getLocation(), diag::err_require_constant_init_failed) - << Init->getSourceRange(); - Diag(Attr->getLocation(), - diag::note_declared_required_constant_init_here) - << Attr->getRange() << Attr->isConstinit(); - if (getLangOpts().CPlusPlus11) { - APValue Value; - SmallVector<PartialDiagnosticAt, 8> Notes; - Init->EvaluateAsInitializer(Value, getASTContext(), var, Notes); - for (auto &it : Notes) - Diag(it.first, it.second); - } else { - Diag(CacheCulprit->getExprLoc(), - diag::note_invalid_subexpr_in_const_expr) - << CacheCulprit->getSourceRange(); - } + } else { + // Evaluate the initializer to see if it's a constant initializer. + HasConstInit = var->checkForConstantInitialization(Notes); + } + + if (HasConstInit) { + // FIXME: Consider replacing the initializer with a ConstantExpr. + } else if (var->isConstexpr()) { + SourceLocation DiagLoc = var->getLocation(); + // If the note doesn't add any useful information other than a source + // location, fold it into the primary diagnostic. + if (Notes.size() == 1 && Notes[0].second.getDiagID() == + diag::note_invalid_subexpr_in_const_expr) { + DiagLoc = Notes[0].first; + Notes.clear(); } - } - else if (!var->isConstexpr() && IsGlobal && - !getDiagnostics().isIgnored(diag::warn_global_constructor, - var->getLocation())) { + Diag(DiagLoc, diag::err_constexpr_var_requires_const_init) + << var << Init->getSourceRange(); + for (unsigned I = 0, N = Notes.size(); I != N; ++I) + Diag(Notes[I].first, Notes[I].second); + } else if (GlobalStorage && var->hasAttr<ConstInitAttr>()) { + auto *Attr = var->getAttr<ConstInitAttr>(); + Diag(var->getLocation(), diag::err_require_constant_init_failed) + << Init->getSourceRange(); + Diag(Attr->getLocation(), diag::note_declared_required_constant_init_here) + << Attr->getRange() << Attr->isConstinit(); + for (auto &it : Notes) + Diag(it.first, it.second); + } else if (IsGlobal && + !getDiagnostics().isIgnored(diag::warn_global_constructor, + var->getLocation())) { // Warn about globals which don't have a constant initializer. Don't // warn about globals with a non-trivial destructor because we already // warned about them. CXXRecordDecl *RD = baseType->getAsCXXRecordDecl(); if (!(RD && !RD->hasTrivialDestructor())) { + // checkConstInit() here permits trivial default initialization even in + // C++11 onwards, where such an initializer is not a constant initializer + // but nonetheless doesn't require a global constructor. if (!checkConstInit()) Diag(var->getLocation(), diag::warn_global_constructor) - << Init->getSourceRange(); + << Init->getSourceRange(); } } } // Require the destructor. - if (const RecordType *recordType = baseType->getAs<RecordType>()) - FinalizeVarWithDestructor(var, recordType); + if (!type->isDependentType()) + if (const RecordType *recordType = baseType->getAs<RecordType>()) + FinalizeVarWithDestructor(var, recordType); // If this variable must be emitted, add it as an initializer for the current // module. if (Context.DeclMustBeEmitted(var) && !ModuleScopes.empty()) Context.addModuleInitializer(ModuleScopes.back().Module, var); + + // Build the bindings if this is a structured binding declaration. + if (auto *DD = dyn_cast<DecompositionDecl>(var)) + CheckCompleteDecompositionDeclaration(DD); } /// Determines if a variable's alignment is dependent. @@ -13064,32 +13240,9 @@ void Sema::FinalizeDeclaration(Decl *ThisDecl) { } } - if (VD->isStaticLocal()) { + if (VD->isStaticLocal()) CheckStaticLocalForDllExport(VD); - if (dyn_cast_or_null<FunctionDecl>(VD->getParentFunctionOrMethod())) { - // CUDA 8.0 E.3.9.4: Within the body of a __device__ or __global__ - // function, only __shared__ variables or variables without any device - // memory qualifiers may be declared with static storage class. - // Note: It is unclear how a function-scope non-const static variable - // without device memory qualifier is implemented, therefore only static - // const variable without device memory qualifier is allowed. - [&]() { - if (!getLangOpts().CUDA) - return; - if (VD->hasAttr<CUDASharedAttr>()) - return; - if (VD->getType().isConstQualified() && - !(VD->hasAttr<CUDADeviceAttr>() || VD->hasAttr<CUDAConstantAttr>())) - return; - if (CUDADiagIfDeviceCode(VD->getLocation(), - diag::err_device_static_local_var) - << CurrentCUDATarget()) - VD->setInvalidDecl(); - }(); - } - } - // Perform check for initializers of device-side global variables. // CUDA allows empty constructors as initializers (see E.2.3.1, CUDA // 7.5). We must also apply the same checks to all __shared__ @@ -13167,20 +13320,20 @@ void Sema::FinalizeDeclaration(Decl *ThisDecl) { if (!MagicValueExpr) { continue; } - llvm::APSInt MagicValueInt; - if (!MagicValueExpr->isIntegerConstantExpr(MagicValueInt, Context)) { + Optional<llvm::APSInt> MagicValueInt; + if (!(MagicValueInt = MagicValueExpr->getIntegerConstantExpr(Context))) { Diag(I->getRange().getBegin(), diag::err_type_tag_for_datatype_not_ice) << LangOpts.CPlusPlus << MagicValueExpr->getSourceRange(); continue; } - if (MagicValueInt.getActiveBits() > 64) { + if (MagicValueInt->getActiveBits() > 64) { Diag(I->getRange().getBegin(), diag::err_type_tag_for_datatype_too_large) << LangOpts.CPlusPlus << MagicValueExpr->getSourceRange(); continue; } - uint64_t MagicValue = MagicValueInt.getZExtValue(); + uint64_t MagicValue = MagicValueInt->getZExtValue(); RegisterTypeTagForDatatype(I->getArgumentKind(), MagicValue, I->getMatchingCType(), @@ -13415,7 +13568,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { << getLangOpts().CPlusPlus17; if (DS.hasConstexprSpecifier()) Diag(DS.getConstexprSpecLoc(), diag::err_invalid_constexpr) - << 0 << D.getDeclSpec().getConstexprSpecifier(); + << 0 << static_cast<int>(D.getDeclSpec().getConstexprSpecifier()); DiagnoseFunctionSpecifiers(DS); @@ -13473,9 +13626,8 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { if (D.getDeclSpec().isModulePrivateSpecified()) Diag(New->getLocation(), diag::err_module_private_local) - << 1 << New->getDeclName() - << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) - << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); + << 1 << New << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) + << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); if (New->hasAttr<BlocksAttr>()) { Diag(New->getLocation(), diag::err_block_on_nonlocal); @@ -13527,8 +13679,7 @@ void Sema::DiagnoseSizeOfParametersAndReturnValue( if (!ReturnTy->isDependentType() && ReturnTy.isPODType(Context)) { unsigned Size = Context.getTypeSizeInChars(ReturnTy).getQuantity(); if (Size > LangOpts.NumLargeByValueCopy) - Diag(D->getLocation(), diag::warn_return_value_size) - << D->getDeclName() << Size; + Diag(D->getLocation(), diag::warn_return_value_size) << D << Size; } // Warn if any parameter is pass-by-value and larger than the specified @@ -13540,7 +13691,7 @@ void Sema::DiagnoseSizeOfParametersAndReturnValue( unsigned Size = Context.getTypeSizeInChars(T).getQuantity(); if (Size > LangOpts.NumLargeByValueCopy) Diag(Parameter->getLocation(), diag::warn_parameter_size) - << Parameter->getDeclName() << Size; + << Parameter << Size; } } @@ -13624,6 +13775,12 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, New->setInvalidDecl(); } + // PPC MMA non-pointer types are not allowed as function argument types. + if (Context.getTargetInfo().getTriple().isPPC64() && + CheckPPCMMAType(New->getOriginalType(), New->getLocation())) { + New->setInvalidDecl(); + } + return New; } @@ -13655,7 +13812,7 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, // Use the identifier location for the type source range. DS.SetRangeStart(FTI.Params[i].IdentLoc); DS.SetRangeEnd(FTI.Params[i].IdentLoc); - Declarator ParamD(DS, DeclaratorContext::KNRTypeListContext); + Declarator ParamD(DS, DeclaratorContext::KNRTypeList); ParamD.SetIdentifier(FTI.Params[i].Ident, FTI.Params[i].IdentLoc); FTI.Params[i].Param = ActOnParamDeclarator(S, ParamD); } @@ -13678,19 +13835,17 @@ Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D, // variant` annotation which specifies the mangled definition as a // specialization function under the OpenMP context defined as part of the // `omp begin declare variant`. - FunctionDecl *BaseFD = nullptr; - if (LangOpts.OpenMP && isInOpenMPDeclareVariantScope() && - TemplateParameterLists.empty()) - BaseFD = ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( - ParentScope, D); + SmallVector<FunctionDecl *, 4> Bases; + if (LangOpts.OpenMP && isInOpenMPDeclareVariantScope()) + ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( + ParentScope, D, TemplateParameterLists, Bases); - D.setFunctionDefinitionKind(FDK_Definition); + D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists); Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody); - if (BaseFD) - ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( - cast<FunctionDecl>(Dcl), BaseFD); + if (!Bases.empty()) + ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl, Bases); return Dcl; } @@ -13759,69 +13914,23 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, const FunctionDecl *EffectiveDefinition, SkipBodyInfo *SkipBody) { const FunctionDecl *Definition = EffectiveDefinition; - if (!Definition && !FD->isDefined(Definition) && !FD->isCXXClassMember()) { - // If this is a friend function defined in a class template, it does not - // have a body until it is used, nevertheless it is a definition, see - // [temp.inst]p2: - // - // ... for the purpose of determining whether an instantiated redeclaration - // is valid according to [basic.def.odr] and [class.mem], a declaration that - // corresponds to a definition in the template is considered to be a - // definition. - // - // The following code must produce redefinition error: - // - // template<typename T> struct C20 { friend void func_20() {} }; - // C20<int> c20i; - // void func_20() {} - // - for (auto I : FD->redecls()) { - if (I != FD && !I->isInvalidDecl() && - I->getFriendObjectKind() != Decl::FOK_None) { - if (FunctionDecl *Original = I->getInstantiatedFromMemberFunction()) { - if (FunctionDecl *OrigFD = FD->getInstantiatedFromMemberFunction()) { - // A merged copy of the same function, instantiated as a member of - // the same class, is OK. - if (declaresSameEntity(OrigFD, Original) && - declaresSameEntity(cast<Decl>(I->getLexicalDeclContext()), - cast<Decl>(FD->getLexicalDeclContext()))) - continue; - } + if (!Definition && + !FD->isDefined(Definition, /*CheckForPendingFriendDefinition*/ true)) + return; - if (Original->isThisDeclarationADefinition()) { - Definition = I; - break; - } - } + if (Definition->getFriendObjectKind() != Decl::FOK_None) { + if (FunctionDecl *OrigDef = Definition->getInstantiatedFromMemberFunction()) { + if (FunctionDecl *OrigFD = FD->getInstantiatedFromMemberFunction()) { + // A merged copy of the same function, instantiated as a member of + // the same class, is OK. + if (declaresSameEntity(OrigFD, OrigDef) && + declaresSameEntity(cast<Decl>(Definition->getLexicalDeclContext()), + cast<Decl>(FD->getLexicalDeclContext()))) + return; } } } - if (!Definition) - // Similar to friend functions a friend function template may be a - // definition and do not have a body if it is instantiated in a class - // template. - if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) { - for (auto I : FTD->redecls()) { - auto D = cast<FunctionTemplateDecl>(I); - if (D != FTD) { - assert(!D->isThisDeclarationADefinition() && - "More than one definition in redeclaration chain"); - if (D->getFriendObjectKind() != Decl::FOK_None) - if (FunctionTemplateDecl *FT = - D->getInstantiatedFromMemberTemplate()) { - if (FT->isThisDeclarationADefinition()) { - Definition = D->getTemplatedDecl(); - break; - } - } - } - } - } - - if (!Definition) - return; - if (canRedefineFunction(Definition, getLangOpts())) return; @@ -13848,9 +13957,9 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, if (getLangOpts().GNUMode && Definition->isInlineSpecified() && Definition->getStorageClass() == SC_Extern) Diag(FD->getLocation(), diag::err_redefinition_extern_inline) - << FD->getDeclName() << getLangOpts().CPlusPlus; + << FD << getLangOpts().CPlusPlus; else - Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName(); + Diag(FD->getLocation(), diag::err_redefinition) << FD; Diag(Definition->getLocation(), diag::note_previous_definition); FD->setInvalidDecl(); @@ -13939,9 +14048,20 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, FD->setInvalidDecl(); } - // See if this is a redefinition. If 'will have body' is already set, then - // these checks were already performed when it was set. - if (!FD->willHaveBody() && !FD->isLateTemplateParsed()) { + if (auto *Ctor = dyn_cast<CXXConstructorDecl>(FD)) { + if (Ctor->getTemplateSpecializationKind() == TSK_ExplicitSpecialization && + Ctor->isDefaultConstructor() && + Context.getTargetInfo().getCXXABI().isMicrosoft()) { + // If this is an MS ABI dllexport default constructor, instantiate any + // default arguments. + InstantiateDefaultCtorDefaultArgs(Ctor); + } + } + + // See if this is a redefinition. If 'will have body' (or similar) is already + // set, then these checks were already performed when it was set. + if (!FD->willHaveBody() && !FD->isLateTemplateParsed() && + !FD->isThisDeclarationInstantiatedFromAFriendDefinition()) { CheckForFunctionRedefinition(FD, nullptr, SkipBody); // If we're skipping the body, we're done. Don't enter the scope. @@ -14181,12 +14301,16 @@ static void diagnoseImplicitlyRetainedSelf(Sema &S) { Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation) { + FunctionScopeInfo *FSI = getCurFunction(); FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr; + if (FSI->UsesFPIntrin && !FD->hasAttr<StrictFPAttr>()) + FD->addAttr(StrictFPAttr::CreateImplicit(Context)); + sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy(); sema::AnalysisBasedWarnings::Policy *ActivePolicy = nullptr; - if (getLangOpts().Coroutines && getCurFunction()->isCoroutine()) + if (getLangOpts().Coroutines && FSI->isCoroutine()) CheckCompletedCoroutineBody(FD, Body); // Do not call PopExpressionEvaluationContext() if it is a lambda because one @@ -14263,7 +14387,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, // to deduce an implicit return type. if (FD->getReturnType()->isRecordType() && (!getLangOpts().CPlusPlus || !FD->isDependentContext())) - computeNRVO(Body, getCurFunction()); + computeNRVO(Body, FSI); } // GNU warning -Wmissing-prototypes: @@ -14387,14 +14511,14 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, MD->getReturnType(), MD); if (Body) - computeNRVO(Body, getCurFunction()); + computeNRVO(Body, FSI); } - if (getCurFunction()->ObjCShouldCallSuper) { + if (FSI->ObjCShouldCallSuper) { Diag(MD->getEndLoc(), diag::warn_objc_missing_super_call) << MD->getSelector().getAsString(); - getCurFunction()->ObjCShouldCallSuper = false; + FSI->ObjCShouldCallSuper = false; } - if (getCurFunction()->ObjCWarnForNoDesignatedInitChain) { + if (FSI->ObjCWarnForNoDesignatedInitChain) { const ObjCMethodDecl *InitMethod = nullptr; bool isDesignated = MD->isDesignatedInitializerForTheInterface(&InitMethod); @@ -14419,14 +14543,14 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, Diag(InitMethod->getLocation(), diag::note_objc_designated_init_marked_here); } - getCurFunction()->ObjCWarnForNoDesignatedInitChain = false; + FSI->ObjCWarnForNoDesignatedInitChain = false; } - if (getCurFunction()->ObjCWarnForNoInitDelegation) { + if (FSI->ObjCWarnForNoInitDelegation) { // Don't issue this warning for unavaialable inits. if (!MD->isUnavailable()) Diag(MD->getLocation(), diag::warn_objc_secondary_init_missing_init_call); - getCurFunction()->ObjCWarnForNoInitDelegation = false; + FSI->ObjCWarnForNoInitDelegation = false; } diagnoseImplicitlyRetainedSelf(*this); @@ -14437,10 +14561,10 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, return nullptr; } - if (Body && getCurFunction()->HasPotentialAvailabilityViolations) + if (Body && FSI->HasPotentialAvailabilityViolations) DiagnoseUnguardedAvailabilityViolations(dcl); - assert(!getCurFunction()->ObjCShouldCallSuper && + assert(!FSI->ObjCShouldCallSuper && "This should only be set for ObjC methods, which should have been " "handled in the block above."); @@ -14453,7 +14577,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, DiagnoseReturnInConstructorExceptionHandler(cast<CXXTryStmt>(Body)); // Verify that gotos and switch cases don't jump into scopes illegally. - if (getCurFunction()->NeedsScopeChecking() && + if (FSI->NeedsScopeChecking() && !PP.isCodeCompletionEnabled()) DiagnoseInvalidJumps(Body); @@ -14468,11 +14592,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, // If any errors have occurred, clear out any temporaries that may have // been leftover. This ensures that these temporaries won't be picked up for // deletion in some later function. - if (getDiagnostics().hasUncompilableErrorOccurred() || + if (hasUncompilableErrorOccurred() || getDiagnostics().getSuppressAllDiagnostics()) { DiscardCleanupsInEvaluationContext(); } - if (!getDiagnostics().hasUncompilableErrorOccurred() && + if (!hasUncompilableErrorOccurred() && !isa<FunctionTemplateDecl>(dcl)) { // Since the body is valid, issue any analysis-based warnings that are // enabled. @@ -14524,11 +14648,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, // If any errors have occurred, clear out any temporaries that may have // been leftover. This ensures that these temporaries won't be picked up for // deletion in some later function. - if (getDiagnostics().hasUncompilableErrorOccurred()) { + if (hasUncompilableErrorOccurred()) { DiscardCleanupsInEvaluationContext(); } - if (LangOpts.OpenMP || LangOpts.CUDA || LangOpts.SYCLIsDevice) { + if (FD && (LangOpts.OpenMP || LangOpts.CUDA || LangOpts.SYCLIsDevice)) { auto ES = getEmissionStatus(FD); if (ES == Sema::FunctionEmissionStatus::Emitted || ES == Sema::FunctionEmissionStatus::Unknown) @@ -14635,7 +14759,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, (void)Error; // Silence warning. assert(!Error && "Error setting up implicit decl!"); SourceLocation NoLoc; - Declarator D(DS, DeclaratorContext::BlockContext); + Declarator D(DS, DeclaratorContext::Block); D.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/false, /*IsAmbiguous=*/false, /*LParenLoc=*/NoLoc, @@ -14905,9 +15029,10 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, if (D.getDeclSpec().isModulePrivateSpecified()) { if (CurContext->isFunctionOrMethod()) Diag(NewTD->getLocation(), diag::err_module_private_local) - << 2 << NewTD->getDeclName() - << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) - << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); + << 2 << NewTD + << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) + << FixItHint::CreateRemoval( + D.getDeclSpec().getModulePrivateSpecLoc()); else NewTD->setModulePrivate(); } @@ -15295,6 +15420,10 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, isMemberSpecialization = true; } } + + if (!TemplateParameterLists.empty() && isMemberSpecialization && + CheckTemplateDeclScope(S, TemplateParameterLists.back())) + return nullptr; } // Figure out the underlying type if this a enum declaration. We need to do @@ -15615,6 +15744,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // type declared by an elaborated-type-specifier. In C that is not correct // and we should instead merge compatible types found by lookup. if (getLangOpts().CPlusPlus) { + // FIXME: This can perform qualified lookups into function contexts, + // which are meaningless. Previous.setRedeclarationKind(forRedeclarationInCurContext()); LookupQualifiedName(Previous, SearchDC); } else { @@ -16332,7 +16463,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, return BitWidth; llvm::APSInt Value; - ExprResult ICE = VerifyIntegerConstantExpression(BitWidth, &Value); + ExprResult ICE = VerifyIntegerConstantExpression(BitWidth, &Value, AllowFold); if (ICE.isInvalid()) return ICE; BitWidth = ICE.get(); @@ -16352,6 +16483,13 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, << Value.toString(10); } + // The size of the bit-field must not exceed our maximum permitted object + // size. + if (Value.getActiveBits() > ConstantArrayType::getMaxSizeBits(Context)) { + return Diag(FieldLoc, diag::err_bitfield_too_wide) + << !FieldName << FieldName << Value.toString(10); + } + if (!FieldTy->isDependentType()) { uint64_t TypeStorageSize = Context.getTypeSize(FieldTy); uint64_t TypeWidth = Context.getIntWidth(FieldTy); @@ -16369,25 +16507,21 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, CStdConstraintViolation ? TypeWidth : TypeStorageSize; if (FieldName) return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_width) - << FieldName << (unsigned)Value.getZExtValue() + << FieldName << Value.toString(10) << !CStdConstraintViolation << DiagWidth; return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_width) - << (unsigned)Value.getZExtValue() << !CStdConstraintViolation + << Value.toString(10) << !CStdConstraintViolation << DiagWidth; } // Warn on types where the user might conceivably expect to get all // specified bits as value bits: that's all integral types other than // 'bool'. - if (BitfieldIsOverwide && !FieldTy->isBooleanType()) { - if (FieldName) - Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_width) - << FieldName << (unsigned)Value.getZExtValue() - << (unsigned)TypeWidth; - else - Diag(FieldLoc, diag::warn_anon_bitfield_width_exceeds_type_width) - << (unsigned)Value.getZExtValue() << (unsigned)TypeWidth; + if (BitfieldIsOverwide && !FieldTy->isBooleanType() && FieldName) { + Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_width) + << FieldName << Value.toString(10) + << (unsigned)TypeWidth; } } @@ -16581,27 +16715,9 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // C99 6.7.2.1p8: A member of a structure or union may have any type other // than a variably modified type. if (!InvalidDecl && T->isVariablyModifiedType()) { - bool SizeIsNegative; - llvm::APSInt Oversized; - - TypeSourceInfo *FixedTInfo = - TryToFixInvalidVariablyModifiedTypeSourceInfo(TInfo, Context, - SizeIsNegative, - Oversized); - if (FixedTInfo) { - Diag(Loc, diag::warn_illegal_constant_array_size); - TInfo = FixedTInfo; - T = FixedTInfo->getType(); - } else { - if (SizeIsNegative) - Diag(Loc, diag::err_typecheck_negative_array_size); - else if (Oversized.getBoolValue()) - Diag(Loc, diag::err_array_too_large) - << Oversized.toString(10); - else - Diag(Loc, diag::err_typecheck_field_variable_size); + if (!tryToFixVariablyModifiedVarType( + *this, TInfo, T, Loc, diag::err_typecheck_field_variable_size)) InvalidDecl = true; - } } // Fields can not have abstract class types @@ -16622,14 +16738,6 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, BitWidth = nullptr; ZeroWidth = false; } - - // Only data members can have in-class initializers. - if (BitWidth && !II && InitStyle) { - Diag(Loc, diag::err_anon_bitfield_init); - InvalidDecl = true; - BitWidth = nullptr; - ZeroWidth = false; - } } // Check that 'mutable' is consistent with the type of the declaration. @@ -16717,6 +16825,11 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (T.isObjCGCWeak()) Diag(Loc, diag::warn_attribute_weak_on_field); + // PPC MMA non-pointer types are not allowed as field types. + if (Context.getTargetInfo().getTriple().isPPC64() && + CheckPPCMMAType(T, NewFD->getLocation())) + NewFD->setInvalidDecl(); + NewFD->setAccess(AS); return NewFD; } @@ -16830,8 +16943,9 @@ Decl *Sema::ActOnIvar(Scope *S, // C99 6.7.2.1p8: A member of a structure or union may have any type other // than a variably modified type. else if (T->isVariablyModifiedType()) { - Diag(Loc, diag::err_typecheck_ivar_variable_size); - D.setInvalidType(); + if (!tryToFixVariablyModifiedVarType( + *this, TInfo, T, Loc, diag::err_typecheck_ivar_variable_size)) + D.setInvalidType(); } // Get the visibility (access control) for this ivar. @@ -17294,7 +17408,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record); CheckForZeroSize = CXXRecord->getLexicalDeclContext()->isExternCContext() && - !CXXRecord->isDependentType() && + !CXXRecord->isDependentType() && !inTemplateInstantiation() && CXXRecord->isCLike(); } if (CheckForZeroSize) { @@ -17458,6 +17572,8 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, if (Enum->isDependentType() || Val->isTypeDependent()) EltTy = Context.DependentTy; else { + // FIXME: We don't allow folding in C++11 mode for an enum with a fixed + // underlying type, but do allow it in all other contexts. if (getLangOpts().CPlusPlus11 && Enum->isFixed()) { // C++11 [dcl.enum]p5: If the underlying type is fixed, [...] the // constant-expression in the enumerator-definition shall be a converted @@ -17471,8 +17587,9 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, else Val = Converted.get(); } else if (!Val->isValueDependent() && - !(Val = VerifyIntegerConstantExpression(Val, - &EnumVal).get())) { + !(Val = + VerifyIntegerConstantExpression(Val, &EnumVal, AllowFold) + .get())) { // C99 6.7.2.2p2: Make sure we have an integer constant expression. } else { if (Enum->isComplete()) { @@ -18093,11 +18210,9 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, // Adjust the Expr initializer and type. if (ECD->getInitExpr() && !Context.hasSameType(NewTy, ECD->getInitExpr()->getType())) - ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy, - CK_IntegralCast, - ECD->getInitExpr(), - /*base paths*/ nullptr, - VK_RValue)); + ECD->setInitExpr(ImplicitCastExpr::Create( + Context, NewTy, CK_IntegralCast, ECD->getInitExpr(), + /*base paths*/ nullptr, VK_RValue, FPOptionsOverride())); if (getLangOpts().CPlusPlus) // C++ [dcl.enum]p4: Following the closing brace of an // enum-specifier, each enumerator has the type of its @@ -18217,42 +18332,51 @@ Sema::FunctionEmissionStatus Sema::getEmissionStatus(FunctionDecl *FD, if (FD->isDependentContext()) return FunctionEmissionStatus::TemplateDiscarded; - FunctionEmissionStatus OMPES = FunctionEmissionStatus::Unknown; + // Check whether this function is an externally visible definition. + auto IsEmittedForExternalSymbol = [this, FD]() { + // We have to check the GVA linkage of the function's *definition* -- if we + // only have a declaration, we don't know whether or not the function will + // be emitted, because (say) the definition could include "inline". + FunctionDecl *Def = FD->getDefinition(); + + return Def && !isDiscardableGVALinkage( + getASTContext().GetGVALinkageForFunction(Def)); + }; + if (LangOpts.OpenMPIsDevice) { + // In OpenMP device mode we will not emit host only functions, or functions + // we don't need due to their linkage. Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD->getCanonicalDecl()); - if (DevTy.hasValue()) { + // DevTy may be changed later by + // #pragma omp declare target to(*) device_type(*). + // Therefore DevTyhaving no value does not imply host. The emission status + // will be checked again at the end of compilation unit with Final = true. + if (DevTy.hasValue()) if (*DevTy == OMPDeclareTargetDeclAttr::DT_Host) - OMPES = FunctionEmissionStatus::OMPDiscarded; - else if (*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost || - *DevTy == OMPDeclareTargetDeclAttr::DT_Any) { - OMPES = FunctionEmissionStatus::Emitted; - } - } - } else if (LangOpts.OpenMP) { - // In OpenMP 4.5 all the functions are host functions. - if (LangOpts.OpenMP <= 45) { - OMPES = FunctionEmissionStatus::Emitted; - } else { - Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = - OMPDeclareTargetDeclAttr::getDeviceType(FD->getCanonicalDecl()); - // In OpenMP 5.0 or above, DevTy may be changed later by - // #pragma omp declare target to(*) device_type(*). Therefore DevTy - // having no value does not imply host. The emission status will be - // checked again at the end of compilation unit. - if (DevTy.hasValue()) { - if (*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { - OMPES = FunctionEmissionStatus::OMPDiscarded; - } else if (*DevTy == OMPDeclareTargetDeclAttr::DT_Host || - *DevTy == OMPDeclareTargetDeclAttr::DT_Any) - OMPES = FunctionEmissionStatus::Emitted; - } else if (Final) - OMPES = FunctionEmissionStatus::Emitted; - } - } - if (OMPES == FunctionEmissionStatus::OMPDiscarded || - (OMPES == FunctionEmissionStatus::Emitted && !LangOpts.CUDA)) - return OMPES; + return FunctionEmissionStatus::OMPDiscarded; + // If we have an explicit value for the device type, or we are in a target + // declare context, we need to emit all extern and used symbols. + if (isInOpenMPDeclareTargetContext() || DevTy.hasValue()) + if (IsEmittedForExternalSymbol()) + return FunctionEmissionStatus::Emitted; + // Device mode only emits what it must, if it wasn't tagged yet and needed, + // we'll omit it. + if (Final) + return FunctionEmissionStatus::OMPDiscarded; + } else if (LangOpts.OpenMP > 45) { + // In OpenMP host compilation prior to 5.0 everything was an emitted host + // function. In 5.0, no_host was introduced which might cause a function to + // be ommitted. + Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = + OMPDeclareTargetDeclAttr::getDeviceType(FD->getCanonicalDecl()); + if (DevTy.hasValue()) + if (*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) + return FunctionEmissionStatus::OMPDiscarded; + } + + if (Final && LangOpts.OpenMP && !LangOpts.CUDA) + return FunctionEmissionStatus::Emitted; if (LangOpts.CUDA) { // When compiling for device, host functions are never emitted. Similarly, @@ -18266,17 +18390,7 @@ Sema::FunctionEmissionStatus Sema::getEmissionStatus(FunctionDecl *FD, (T == Sema::CFT_Device || T == Sema::CFT_Global)) return FunctionEmissionStatus::CUDADiscarded; - // Check whether this function is externally visible -- if so, it's - // known-emitted. - // - // We have to check the GVA linkage of the function's *definition* -- if we - // only have a declaration, we don't know whether or not the function will - // be emitted, because (say) the definition could include "inline". - FunctionDecl *Def = FD->getDefinition(); - - if (Def && - !isDiscardableGVALinkage(getASTContext().GetGVALinkageForFunction(Def)) - && (!LangOpts.OpenMP || OMPES == FunctionEmissionStatus::Emitted)) + if (IsEmittedForExternalSymbol()) return FunctionEmissionStatus::Emitted; } |