diff options
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 1207 |
1 files changed, 845 insertions, 362 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index c5cd83da59d6..510738ea8168 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -36,6 +36,7 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/Template.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include <map> @@ -212,7 +213,7 @@ Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc, ComputedEST = EST_Dynamic; // Record the exceptions in this function's exception specification. for (const auto &E : Proto->exceptions()) - if (ExceptionsSeen.insert(Self->Context.getCanonicalType(E))) + if (ExceptionsSeen.insert(Self->Context.getCanonicalType(E)).second) Exceptions.push_back(E); } @@ -353,7 +354,9 @@ void Sema::ActOnParamDefaultArgumentError(Decl *param, Param->setInvalidDecl(); UnparsedDefaultArgLocs.erase(Param); Param->setDefaultArg(new(Context) - OpaqueValueExpr(EqualLoc, Param->getType(), VK_RValue)); + OpaqueValueExpr(EqualLoc, + Param->getType().getNonReferenceType(), + VK_RValue)); } /// CheckExtraCXXDefaultArguments - Check for any extra default @@ -385,9 +388,14 @@ void Sema::CheckExtraCXXDefaultArguments(Declarator &D) { ParmVarDecl *Param = cast<ParmVarDecl>(chunk.Fun.Params[argIdx].Param); if (Param->hasUnparsedDefaultArg()) { CachedTokens *Toks = chunk.Fun.Params[argIdx].DefaultArgTokens; + SourceRange SR; + if (Toks->size() > 1) + SR = SourceRange((*Toks)[1].getLocation(), + Toks->back().getLocation()); + else + SR = UnparsedDefaultArgLocs[Param]; Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc) - << SourceRange((*Toks)[1].getLocation(), - Toks->back().getLocation()); + << SR; delete Toks; chunk.Fun.Params[argIdx].DefaultArgTokens = nullptr; } else if (Param->getDefaultArg()) { @@ -446,20 +454,24 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, bool OldParamHasDfl = OldParam->hasDefaultArg(); bool NewParamHasDfl = NewParam->hasDefaultArg(); - NamedDecl *ND = Old; - // The declaration context corresponding to the scope is the semantic // parent, unless this is a local function declaration, in which case // it is that surrounding function. - DeclContext *ScopeDC = New->getLexicalDeclContext(); - if (!ScopeDC->isFunctionOrMethod()) - ScopeDC = New->getDeclContext(); - if (S && !isDeclInScope(ND, ScopeDC, S) && + DeclContext *ScopeDC = New->isLocalExternDecl() + ? New->getLexicalDeclContext() + : New->getDeclContext(); + if (S && !isDeclInScope(Old, ScopeDC, S) && !New->getDeclContext()->isRecord()) // Ignore default parameters of old decl if they are not in // the same scope and this is not an out-of-line definition of // a member function. OldParamHasDfl = false; + if (New->isLocalExternDecl() != Old->isLocalExternDecl()) + // If only one of these is a local function declaration, then they are + // declared in different scopes, even though isDeclInScope may think + // they're in the same scope. (If both are local, the scope check is + // sufficent, and if neither is local, then they are in the same scope.) + OldParamHasDfl = false; if (OldParamHasDfl && NewParamHasDfl) { @@ -855,7 +867,7 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl, // C++1y allows types to be defined, not just declared. if (cast<TagDecl>(DclIt)->isThisDeclarationADefinition()) SemaRef.Diag(DS->getLocStart(), - SemaRef.getLangOpts().CPlusPlus1y + SemaRef.getLangOpts().CPlusPlus14 ? diag::warn_cxx11_compat_constexpr_type_definition : diag::ext_constexpr_type_definition) << isa<CXXConstructorDecl>(Dcl); @@ -896,7 +908,7 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl, } } SemaRef.Diag(VD->getLocation(), - SemaRef.getLangOpts().CPlusPlus1y + SemaRef.getLangOpts().CPlusPlus14 ? diag::warn_cxx11_compat_constexpr_local_var : diag::ext_constexpr_local_var) << isa<CXXConstructorDecl>(Dcl); @@ -1041,7 +1053,7 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S, case Stmt::ContinueStmtClass: // C++1y allows all of these. We don't allow them as extensions in C++11, // because they don't make sense without variable mutation. - if (!SemaRef.getLangOpts().CPlusPlus1y) + if (!SemaRef.getLangOpts().CPlusPlus14) break; if (!Cxx1yLoc.isValid()) Cxx1yLoc = S->getLocStart(); @@ -1115,7 +1127,7 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) { if (Cxx1yLoc.isValid()) Diag(Cxx1yLoc, - getLangOpts().CPlusPlus1y + getLangOpts().CPlusPlus14 ? diag::warn_cxx11_compat_constexpr_body_invalid_stmt : diag::ext_constexpr_body_invalid_stmt) << isa<CXXConstructorDecl>(Dcl); @@ -1180,7 +1192,7 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) { // statement. We still do, unless the return type might be void, because // otherwise if there's no return statement, the function cannot // be used in a core constant expression. - bool OK = getLangOpts().CPlusPlus1y && + bool OK = getLangOpts().CPlusPlus14 && (Dcl->getReturnType()->isVoidType() || Dcl->getReturnType()->isDependentType()); Diag(Dcl->getLocation(), @@ -1190,7 +1202,7 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) { } if (ReturnStmts.size() > 1) { Diag(ReturnStmts.back(), - getLangOpts().CPlusPlus1y + getLangOpts().CPlusPlus14 ? diag::warn_cxx11_compat_constexpr_body_multiple_return : diag::ext_constexpr_body_multiple_return); for (unsigned I = 0; I < ReturnStmts.size() - 1; ++I) @@ -1881,7 +1893,7 @@ void Sema::CheckOverrideControl(NamedDecl *D) { } // C++11 [class.virtual]p5: - // If a virtual function is marked with the virt-specifier override and + // If a function is marked with the virt-specifier override and // does not override a member function of a base class, the program is // ill-formed. bool HasOverriddenMethods = @@ -1891,6 +1903,30 @@ void Sema::CheckOverrideControl(NamedDecl *D) { << MD->getDeclName(); } +void Sema::DiagnoseAbsenceOfOverrideControl(NamedDecl *D) { + if (D->isInvalidDecl() || D->hasAttr<OverrideAttr>()) + return; + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D); + if (!MD || MD->isImplicit() || MD->hasAttr<FinalAttr>() || + isa<CXXDestructorDecl>(MD)) + return; + + SourceLocation Loc = MD->getLocation(); + SourceLocation SpellingLoc = Loc; + if (getSourceManager().isMacroArgExpansion(Loc)) + SpellingLoc = getSourceManager().getImmediateExpansionRange(Loc).first; + SpellingLoc = getSourceManager().getSpellingLoc(SpellingLoc); + if (SpellingLoc.isValid() && getSourceManager().isInSystemHeader(SpellingLoc)) + return; + + if (MD->size_overridden_methods() > 0) { + Diag(MD->getLocation(), diag::warn_function_marked_not_override_overriding) + << MD->getDeclName(); + const CXXMethodDecl *OMD = *MD->begin_overridden_methods(); + Diag(OMD->getLocation(), diag::note_overridden_virtual_function); + } +} + /// CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member /// function overrides a virtual member function marked 'final', according to /// C++11 [class.virtual]p4. @@ -2133,7 +2169,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, if (BitWidth) { if (Member->isInvalidDecl()) { // don't emit another diagnostic. - } else if (isa<VarDecl>(Member)) { + } else if (isa<VarDecl>(Member) || isa<VarTemplateDecl>(Member)) { // C++ 9.6p3: A bit-field shall not be a static member. // "static member 'A' cannot be a bit-field" Diag(Loc, diag::err_static_not_bitfield) @@ -2205,18 +2241,73 @@ namespace { Sema &S; // List of Decls to generate a warning on. Also remove Decls that become // initialized. - llvm::SmallPtrSet<ValueDecl*, 4> &Decls; + llvm::SmallPtrSetImpl<ValueDecl*> &Decls; + // List of base classes of the record. Classes are removed after their + // initializers. + llvm::SmallPtrSetImpl<QualType> &BaseClasses; + // Vector of decls to be removed from the Decl set prior to visiting the + // nodes. These Decls may have been initialized in the prior initializer. + llvm::SmallVector<ValueDecl*, 4> DeclsToRemove; // If non-null, add a note to the warning pointing back to the constructor. const CXXConstructorDecl *Constructor; + // Variables to hold state when processing an initializer list. When + // InitList is true, special case initialization of FieldDecls matching + // InitListFieldDecl. + bool InitList; + FieldDecl *InitListFieldDecl; + llvm::SmallVector<unsigned, 4> InitFieldIndex; + public: typedef EvaluatedExprVisitor<UninitializedFieldVisitor> Inherited; UninitializedFieldVisitor(Sema &S, - llvm::SmallPtrSet<ValueDecl*, 4> &Decls, - const CXXConstructorDecl *Constructor) - : Inherited(S.Context), S(S), Decls(Decls), - Constructor(Constructor) { } + llvm::SmallPtrSetImpl<ValueDecl*> &Decls, + llvm::SmallPtrSetImpl<QualType> &BaseClasses) + : Inherited(S.Context), S(S), Decls(Decls), BaseClasses(BaseClasses), + Constructor(nullptr), InitList(false), InitListFieldDecl(nullptr) {} + + // Returns true if the use of ME is not an uninitialized use. + bool IsInitListMemberExprInitialized(MemberExpr *ME, + bool CheckReferenceOnly) { + llvm::SmallVector<FieldDecl*, 4> Fields; + bool ReferenceField = false; + while (ME) { + FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()); + if (!FD) + return false; + Fields.push_back(FD); + if (FD->getType()->isReferenceType()) + ReferenceField = true; + ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParenImpCasts()); + } + + // Binding a reference to an unintialized field is not an + // uninitialized use. + if (CheckReferenceOnly && !ReferenceField) + return true; - void HandleMemberExpr(MemberExpr *ME, bool CheckReferenceOnly) { + llvm::SmallVector<unsigned, 4> UsedFieldIndex; + // Discard the first field since it is the field decl that is being + // initialized. + for (auto I = Fields.rbegin() + 1, E = Fields.rend(); I != E; ++I) { + UsedFieldIndex.push_back((*I)->getFieldIndex()); + } + + for (auto UsedIter = UsedFieldIndex.begin(), + UsedEnd = UsedFieldIndex.end(), + OrigIter = InitFieldIndex.begin(), + OrigEnd = InitFieldIndex.end(); + UsedIter != UsedEnd && OrigIter != OrigEnd; ++UsedIter, ++OrigIter) { + if (*UsedIter < *OrigIter) + return true; + if (*UsedIter > *OrigIter) + break; + } + + return false; + } + + void HandleMemberExpr(MemberExpr *ME, bool CheckReferenceOnly, + bool AddressOf) { if (isa<EnumConstantDecl>(ME->getMemberDecl())) return; @@ -2224,33 +2315,63 @@ namespace { // or union. MemberExpr *FieldME = ME; + bool AllPODFields = FieldME->getType().isPODType(S.Context); + Expr *Base = ME; - while (isa<MemberExpr>(Base)) { - ME = cast<MemberExpr>(Base); + while (MemberExpr *SubME = + dyn_cast<MemberExpr>(Base->IgnoreParenImpCasts())) { - if (isa<VarDecl>(ME->getMemberDecl())) + if (isa<VarDecl>(SubME->getMemberDecl())) return; - if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) + if (FieldDecl *FD = dyn_cast<FieldDecl>(SubME->getMemberDecl())) if (!FD->isAnonymousStructOrUnion()) - FieldME = ME; + FieldME = SubME; + + if (!FieldME->getType().isPODType(S.Context)) + AllPODFields = false; - Base = ME->getBase(); + Base = SubME->getBase(); } - if (!isa<CXXThisExpr>(Base)) + if (!isa<CXXThisExpr>(Base->IgnoreParenImpCasts())) + return; + + if (AddressOf && AllPODFields) return; ValueDecl* FoundVD = FieldME->getMemberDecl(); + if (ImplicitCastExpr *BaseCast = dyn_cast<ImplicitCastExpr>(Base)) { + while (isa<ImplicitCastExpr>(BaseCast->getSubExpr())) { + BaseCast = cast<ImplicitCastExpr>(BaseCast->getSubExpr()); + } + + if (BaseCast->getCastKind() == CK_UncheckedDerivedToBase) { + QualType T = BaseCast->getType(); + if (T->isPointerType() && + BaseClasses.count(T->getPointeeType())) { + S.Diag(FieldME->getExprLoc(), diag::warn_base_class_is_uninit) + << T->getPointeeType() << FoundVD; + } + } + } + if (!Decls.count(FoundVD)) return; const bool IsReference = FoundVD->getType()->isReferenceType(); - // Prevent double warnings on use of unbounded references. - if (IsReference != CheckReferenceOnly) - return; + if (InitList && !AddressOf && FoundVD == InitListFieldDecl) { + // Special checking for initializer lists. + if (IsInitListMemberExprInitialized(ME, CheckReferenceOnly)) { + return; + } + } else { + // Prevent double warnings on use of unbounded references. + if (CheckReferenceOnly && !IsReference) + return; + } unsigned diag = IsReference ? diag::warn_reference_field_is_uninit @@ -2263,74 +2384,160 @@ namespace { } - void HandleValue(Expr *E) { + void HandleValue(Expr *E, bool AddressOf) { E = E->IgnoreParens(); if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) { - HandleMemberExpr(ME, false /*CheckReferenceOnly*/); + HandleMemberExpr(ME, false /*CheckReferenceOnly*/, + AddressOf /*AddressOf*/); return; } if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { - HandleValue(CO->getTrueExpr()); - HandleValue(CO->getFalseExpr()); + Visit(CO->getCond()); + HandleValue(CO->getTrueExpr(), AddressOf); + HandleValue(CO->getFalseExpr(), AddressOf); return; } if (BinaryConditionalOperator *BCO = dyn_cast<BinaryConditionalOperator>(E)) { - HandleValue(BCO->getCommon()); - HandleValue(BCO->getFalseExpr()); + Visit(BCO->getCond()); + HandleValue(BCO->getFalseExpr(), AddressOf); + return; + } + + if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) { + HandleValue(OVE->getSourceExpr(), AddressOf); return; } if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { switch (BO->getOpcode()) { default: - return; + break; case(BO_PtrMemD): case(BO_PtrMemI): - HandleValue(BO->getLHS()); + HandleValue(BO->getLHS(), AddressOf); + Visit(BO->getRHS()); return; case(BO_Comma): - HandleValue(BO->getRHS()); + Visit(BO->getLHS()); + HandleValue(BO->getRHS(), AddressOf); return; } } + + Visit(E); + } + + void CheckInitListExpr(InitListExpr *ILE) { + InitFieldIndex.push_back(0); + for (auto Child : ILE->children()) { + if (InitListExpr *SubList = dyn_cast<InitListExpr>(Child)) { + CheckInitListExpr(SubList); + } else { + Visit(Child); + } + ++InitFieldIndex.back(); + } + InitFieldIndex.pop_back(); + } + + void CheckInitializer(Expr *E, const CXXConstructorDecl *FieldConstructor, + FieldDecl *Field, const Type *BaseClass) { + // Remove Decls that may have been initialized in the previous + // initializer. + for (ValueDecl* VD : DeclsToRemove) + Decls.erase(VD); + DeclsToRemove.clear(); + + Constructor = FieldConstructor; + InitListExpr *ILE = dyn_cast<InitListExpr>(E); + + if (ILE && Field) { + InitList = true; + InitListFieldDecl = Field; + InitFieldIndex.clear(); + CheckInitListExpr(ILE); + } else { + InitList = false; + Visit(E); + } + + if (Field) + Decls.erase(Field); + if (BaseClass) + BaseClasses.erase(BaseClass->getCanonicalTypeInternal()); } void VisitMemberExpr(MemberExpr *ME) { // All uses of unbounded reference fields will warn. - HandleMemberExpr(ME, true /*CheckReferenceOnly*/); - - Inherited::VisitMemberExpr(ME); + HandleMemberExpr(ME, true /*CheckReferenceOnly*/, false /*AddressOf*/); } void VisitImplicitCastExpr(ImplicitCastExpr *E) { - if (E->getCastKind() == CK_LValueToRValue) - HandleValue(E->getSubExpr()); + if (E->getCastKind() == CK_LValueToRValue) { + HandleValue(E->getSubExpr(), false /*AddressOf*/); + return; + } Inherited::VisitImplicitCastExpr(E); } void VisitCXXConstructExpr(CXXConstructExpr *E) { - if (E->getConstructor()->isCopyConstructor()) - if (ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(E->getArg(0))) + if (E->getConstructor()->isCopyConstructor()) { + Expr *ArgExpr = E->getArg(0); + if (InitListExpr *ILE = dyn_cast<InitListExpr>(ArgExpr)) + if (ILE->getNumInits() == 1) + ArgExpr = ILE->getInit(0); + if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgExpr)) if (ICE->getCastKind() == CK_NoOp) - if (MemberExpr *ME = dyn_cast<MemberExpr>(ICE->getSubExpr())) - HandleMemberExpr(ME, false /*CheckReferenceOnly*/); - + ArgExpr = ICE->getSubExpr(); + HandleValue(ArgExpr, false /*AddressOf*/); + return; + } Inherited::VisitCXXConstructExpr(E); } void VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { Expr *Callee = E->getCallee(); - if (isa<MemberExpr>(Callee)) - HandleValue(Callee); + if (isa<MemberExpr>(Callee)) { + HandleValue(Callee, false /*AddressOf*/); + for (auto Arg : E->arguments()) + Visit(Arg); + return; + } Inherited::VisitCXXMemberCallExpr(E); } + void VisitCallExpr(CallExpr *E) { + // Treat std::move as a use. + if (E->getNumArgs() == 1) { + if (FunctionDecl *FD = E->getDirectCallee()) { + if (FD->isInStdNamespace() && FD->getIdentifier() && + FD->getIdentifier()->isStr("move")) { + HandleValue(E->getArg(0), false /*AddressOf*/); + return; + } + } + } + + Inherited::VisitCallExpr(E); + } + + void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { + Expr *Callee = E->getCallee(); + + if (isa<UnresolvedLookupExpr>(Callee)) + return Inherited::VisitCXXOperatorCallExpr(E); + + Visit(Callee); + for (auto Arg : E->arguments()) + HandleValue(Arg->IgnoreParenImpCasts(), false /*AddressOf*/); + } + void VisitBinaryOperator(BinaryOperator *E) { // If a field assignment is detected, remove the field from the // uninitiailized field set. @@ -2338,30 +2545,32 @@ namespace { if (MemberExpr *ME = dyn_cast<MemberExpr>(E->getLHS())) if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) if (!FD->getType()->isReferenceType()) - Decls.erase(FD); + DeclsToRemove.push_back(FD); + + if (E->isCompoundAssignmentOp()) { + HandleValue(E->getLHS(), false /*AddressOf*/); + Visit(E->getRHS()); + return; + } Inherited::VisitBinaryOperator(E); } - }; - static void CheckInitExprContainsUninitializedFields( - Sema &S, Expr *E, llvm::SmallPtrSet<ValueDecl*, 4> &Decls, - const CXXConstructorDecl *Constructor) { - if (Decls.size() == 0) - return; - - if (!E) - return; - if (CXXDefaultInitExpr *Default = dyn_cast<CXXDefaultInitExpr>(E)) { - E = Default->getExpr(); - if (!E) + void VisitUnaryOperator(UnaryOperator *E) { + if (E->isIncrementDecrementOp()) { + HandleValue(E->getSubExpr(), false /*AddressOf*/); return; - // In class initializers will point to the constructor. - UninitializedFieldVisitor(S, Decls, Constructor).Visit(E); - } else { - UninitializedFieldVisitor(S, Decls, nullptr).Visit(E); + } + if (E->getOpcode() == UO_AddrOf) { + if (MemberExpr *ME = dyn_cast<MemberExpr>(E->getSubExpr())) { + HandleValue(ME->getBase(), true /*AddressOf*/); + return; + } + } + + Inherited::VisitUnaryOperator(E); } - } + }; // Diagnose value-uses of fields to initialize themselves, e.g. // foo(foo) @@ -2382,6 +2591,9 @@ namespace { const CXXRecordDecl *RD = Constructor->getParent(); + if (RD->getDescribedClassTemplate()) + return; + // Holds fields that are uninitialized. llvm::SmallPtrSet<ValueDecl*, 4> UninitializedFields; @@ -2394,14 +2606,39 @@ namespace { } } + llvm::SmallPtrSet<QualType, 4> UninitializedBaseClasses; + for (auto I : RD->bases()) + UninitializedBaseClasses.insert(I.getType().getCanonicalType()); + + if (UninitializedFields.empty() && UninitializedBaseClasses.empty()) + return; + + UninitializedFieldVisitor UninitializedChecker(SemaRef, + UninitializedFields, + UninitializedBaseClasses); + for (const auto *FieldInit : Constructor->inits()) { - Expr *InitExpr = FieldInit->getInit(); + if (UninitializedFields.empty() && UninitializedBaseClasses.empty()) + break; - CheckInitExprContainsUninitializedFields( - SemaRef, InitExpr, UninitializedFields, Constructor); + Expr *InitExpr = FieldInit->getInit(); + if (!InitExpr) + continue; - if (FieldDecl *Field = FieldInit->getAnyMember()) - UninitializedFields.erase(Field); + if (CXXDefaultInitExpr *Default = + dyn_cast<CXXDefaultInitExpr>(InitExpr)) { + InitExpr = Default->getExpr(); + if (!InitExpr) + continue; + // In class initializers will point to the constructor. + UninitializedChecker.CheckInitializer(InitExpr, Constructor, + FieldInit->getAnyMember(), + FieldInit->getBaseClass()); + } else { + UninitializedChecker.CheckInitializer(InitExpr, nullptr, + FieldInit->getAnyMember(), + FieldInit->getBaseClass()); + } } } } // namespace @@ -2424,13 +2661,14 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D, // Pop the notional constructor scope we created earlier. PopFunctionScopeInfo(nullptr, D); - FieldDecl *FD = cast<FieldDecl>(D); - assert(FD->getInClassInitStyle() != ICIS_NoInit && + FieldDecl *FD = dyn_cast<FieldDecl>(D); + assert((isa<MSPropertyDecl>(D) || FD->getInClassInitStyle() != ICIS_NoInit) && "must set init style when field is created"); if (!InitExpr) { - FD->setInvalidDecl(); - FD->removeInClassInitializer(); + D->setInvalidDecl(); + if (FD) + FD->removeInClassInitializer(); return; } @@ -2581,6 +2819,11 @@ Sema::BuildMemInitializer(Decl *ConstructorD, SourceLocation IdLoc, Expr *Init, SourceLocation EllipsisLoc) { + ExprResult Res = CorrectDelayedTyposInExpr(Init); + if (!Res.isUsable()) + return true; + Init = Res.get(); + if (!ConstructorD) return true; @@ -2610,8 +2853,7 @@ Sema::BuildMemInitializer(Decl *ConstructorD, // using a qualified name. ] if (!SS.getScopeRep() && !TemplateTypeTy) { // Look for a member, first. - DeclContext::lookup_result Result - = ClassDecl->lookup(MemberOrBase); + DeclContext::lookup_result Result = ClassDecl->lookup(MemberOrBase); if (!Result.empty()) { ValueDecl *Member; if ((Member = dyn_cast<FieldDecl>(Result.front())) || @@ -2666,10 +2908,11 @@ Sema::BuildMemInitializer(Decl *ConstructorD, // If no results were found, try to correct typos. TypoCorrection Corr; - MemInitializerValidatorCCC Validator(ClassDecl); if (R.empty() && BaseType.isNull() && - (Corr = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, - Validator, CTK_ErrorRecovery, ClassDecl))) { + (Corr = CorrectTypo( + R.getLookupNameInfo(), R.getLookupKind(), S, &SS, + llvm::make_unique<MemInitializerValidatorCCC>(ClassDecl), + CTK_ErrorRecovery, ClassDecl))) { if (FieldDecl *Member = Corr.getCorrectionDeclAs<FieldDecl>()) { // We have found a non-static data member with a similar // name to what was typed; complain and initialize that @@ -2713,6 +2956,7 @@ Sema::BuildMemInitializer(Decl *ConstructorD, if (BaseType.isNull()) { BaseType = Context.getTypeDeclType(TyD); + MarkAnyDeclReferenced(TyD->getLocation(), TyD, /*OdrUse=*/false); if (SS.isSet()) // FIXME: preserve source range information BaseType = Context.getElaboratedType(ETK_None, SS.getScopeRep(), @@ -3528,19 +3772,19 @@ static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info, return false; if (Field->hasInClassInitializer() && !Info.isImplicitCopyOrMove()) { - Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context, - Info.Ctor->getLocation(), Field); + ExprResult DIE = + SemaRef.BuildCXXDefaultInitExpr(Info.Ctor->getLocation(), Field); + if (DIE.isInvalid()) + return true; CXXCtorInitializer *Init; if (Indirect) - Init = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Indirect, - SourceLocation(), - SourceLocation(), DIE, - SourceLocation()); + Init = new (SemaRef.Context) + CXXCtorInitializer(SemaRef.Context, Indirect, SourceLocation(), + SourceLocation(), DIE.get(), SourceLocation()); else - Init = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Field, - SourceLocation(), - SourceLocation(), DIE, - SourceLocation()); + Init = new (SemaRef.Context) + CXXCtorInitializer(SemaRef.Context, Field, SourceLocation(), + SourceLocation(), DIE.get(), SourceLocation()); return Info.addFieldInitializer(Init); } @@ -3582,6 +3826,8 @@ Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor, DelegatingCtorDecls.push_back(Constructor); + DiagnoseUninitializedFields(*this, Constructor); + return false; } @@ -4234,7 +4480,7 @@ void Sema::DiagnoseAbstractType(const CXXRecordDecl *RD) { if (!SO->second.front().Method->isPure()) continue; - if (!SeenPureMethods.insert(SO->second.front().Method)) + if (!SeenPureMethods.insert(SO->second.front().Method).second) continue; Diag(SO->second.front().Method->getLocation(), @@ -4415,10 +4661,53 @@ static void CheckAbstractClassUsage(AbstractUsageInfo &Info, /// \brief Check class-level dllimport/dllexport attribute. static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { Attr *ClassAttr = getDLLAttr(Class); + + // MSVC inherits DLL attributes to partial class template specializations. + if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && !ClassAttr) { + if (auto *Spec = dyn_cast<ClassTemplatePartialSpecializationDecl>(Class)) { + if (Attr *TemplateAttr = + getDLLAttr(Spec->getSpecializedTemplate()->getTemplatedDecl())) { + auto *A = cast<InheritableAttr>(TemplateAttr->clone(S.getASTContext())); + A->setInherited(true); + ClassAttr = A; + } + } + } + if (!ClassAttr) return; - bool ClassExported = ClassAttr->getKind() == attr::DLLExport; + if (!Class->isExternallyVisible()) { + S.Diag(Class->getLocation(), diag::err_attribute_dll_not_extern) + << Class << ClassAttr; + return; + } + + if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && + !ClassAttr->isInherited()) { + // Diagnose dll attributes on members of class with dll attribute. + for (Decl *Member : Class->decls()) { + if (!isa<VarDecl>(Member) && !isa<CXXMethodDecl>(Member)) + continue; + InheritableAttr *MemberAttr = getDLLAttr(Member); + if (!MemberAttr || MemberAttr->isInherited() || Member->isInvalidDecl()) + continue; + + S.Diag(MemberAttr->getLocation(), + diag::err_attribute_dll_member_of_dll_class) + << MemberAttr << ClassAttr; + S.Diag(ClassAttr->getLocation(), diag::note_previous_attribute); + Member->setInvalidDecl(); + } + } + + if (Class->getDescribedClassTemplate()) + // Don't inherit dll attribute until the template is instantiated. + return; + + // The class is either imported or exported. + const bool ClassExported = ClassAttr->getKind() == attr::DLLExport; + const bool ClassImported = !ClassExported; // Force declaration of implicit members so they can inherit the attribute. S.ForceDeclarationOfImplicitMembers(Class); @@ -4426,6 +4715,9 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { // FIXME: MSVC's docs say all bases must be exportable, but this doesn't // seem to be true in practice? + TemplateSpecializationKind TSK = + Class->getTemplateSpecializationKind(); + for (Decl *Member : Class->decls()) { VarDecl *VD = dyn_cast<VarDecl>(Member); CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member); @@ -4434,50 +4726,57 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { if (!VD && !MD) continue; - // Don't process deleted methods. - if (MD && MD->isDeleted()) - continue; + if (MD) { + // Don't process deleted methods. + if (MD->isDeleted()) + continue; - if (MD && MD->isMoveAssignmentOperator() && !ClassExported && - MD->isInlined()) { - // Current MSVC versions don't export the move assignment operators, so - // don't attempt to import them if we have a definition. - continue; - } + if (MD->isMoveAssignmentOperator() && ClassImported && MD->isInlined()) { + // Current MSVC versions don't export the move assignment operators, so + // don't attempt to import them if we have a definition. + continue; + } - if (InheritableAttr *MemberAttr = getDLLAttr(Member)) { - if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && - !MemberAttr->isInherited() && !ClassAttr->isInherited()) { - S.Diag(MemberAttr->getLocation(), - diag::err_attribute_dll_member_of_dll_class) - << MemberAttr << ClassAttr; - S.Diag(ClassAttr->getLocation(), diag::note_previous_attribute); - Member->setInvalidDecl(); + if (MD->isInlined() && ClassImported && + !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { + // MinGW does not import inline functions. continue; } - } else { + } + + if (!getDLLAttr(Member)) { auto *NewAttr = cast<InheritableAttr>(ClassAttr->clone(S.getASTContext())); NewAttr->setInherited(true); Member->addAttr(NewAttr); } - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) { - if (ClassExported) { - if (MD->isUserProvided()) { - // Instantiate non-default methods. - S.MarkFunctionReferenced(Class->getLocation(), MD); - } else if (!MD->isTrivial() || MD->isExplicitlyDefaulted() || - MD->isCopyAssignmentOperator() || - MD->isMoveAssignmentOperator()) { - // Instantiate non-trivial or explicitly defaulted methods, and the - // copy assignment / move assignment operators. - S.MarkFunctionReferenced(Class->getLocation(), MD); - // Resolve its exception specification; CodeGen needs it. - auto *FPT = MD->getType()->getAs<FunctionProtoType>(); - S.ResolveExceptionSpec(Class->getLocation(), FPT); - S.ActOnFinishInlineMethodDef(MD); - } + if (MD && ClassExported) { + if (MD->isUserProvided()) { + // Instantiate non-default class member functions ... + + // .. except for certain kinds of template specializations. + if (TSK == TSK_ExplicitInstantiationDeclaration) + continue; + if (TSK == TSK_ImplicitInstantiation && !ClassAttr->isInherited()) + continue; + + S.MarkFunctionReferenced(Class->getLocation(), MD); + + // The function will be passed to the consumer when its definition is + // encountered. + } else if (!MD->isTrivial() || MD->isExplicitlyDefaulted() || + MD->isCopyAssignmentOperator() || + MD->isMoveAssignmentOperator()) { + // Synthesize and instantiate non-trivial implicit methods, explicitly + // defaulted methods, and the copy and move assignment operators. The + // latter are exported even if they are trivial, because the address of + // an operator can be taken and should compare equal accross libraries. + S.MarkFunctionReferenced(Class->getLocation(), MD); + + // There is no later point when we will see the definition of this + // function, so pass it to the consumer now. + S.Consumer.HandleTopLevelDecl(DeclGroupRef(MD)); } } } @@ -4563,13 +4862,18 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { } } + bool HasMethodWithOverrideControl = false, + HasOverridingMethodWithoutOverrideControl = false; if (!Record->isDependentType()) { for (auto *M : Record->methods()) { // See if a method overloads virtual methods in a base // class without overriding any. if (!M->isStatic()) DiagnoseHiddenVirtualMethods(M); - + if (M->hasAttr<OverrideAttr>()) + HasMethodWithOverrideControl = true; + else if (M->size_overridden_methods() > 0) + HasOverridingMethodWithoutOverrideControl = true; // Check whether the explicitly-defaulted special members are valid. if (!M->isInvalidDecl() && M->isExplicitlyDefaulted()) CheckExplicitlyDefaultedSpecialMember(M); @@ -4588,41 +4892,12 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { } } - // 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. [...] The class of which that function is a member shall be - // a literal type. - // - // If the class has virtual bases, any constexpr members will already have - // been diagnosed by the checks performed on the member declaration, so - // suppress this (less useful) diagnostic. - // - // We delay this until we know whether an explicitly-defaulted (or deleted) - // destructor for the class is trivial. - if (LangOpts.CPlusPlus11 && !Record->isDependentType() && - !Record->isLiteral() && !Record->getNumVBases()) { - for (const auto *M : Record->methods()) { - if (M->isConstexpr() && M->isInstance() && !isa<CXXConstructorDecl>(M)) { - switch (Record->getTemplateSpecializationKind()) { - case TSK_ImplicitInstantiation: - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - // If a template instantiates to a non-literal type, but its members - // instantiate to constexpr functions, the template is technically - // ill-formed, but we allow it for sanity. - continue; - - case TSK_Undeclared: - case TSK_ExplicitSpecialization: - RequireLiteralType(M->getLocation(), Context.getRecordType(Record), - diag::err_constexpr_method_non_literal); - break; - } - - // Only produce one error per class. - break; - } - } + if (HasMethodWithOverrideControl && + HasOverridingMethodWithoutOverrideControl) { + // At least one method has the 'override' control declared. + // Diagnose all other overridden methods which do not have 'override' specified on them. + for (auto *M : Record->methods()) + DiagnoseAbsenceOfOverrideControl(M); } // ms_struct is a request to use the same ABI rules as MSVC. Check @@ -4723,7 +4998,7 @@ static bool defaultedSpecialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl, case Sema::CXXCopyAssignment: case Sema::CXXMoveAssignment: - if (!S.getLangOpts().CPlusPlus1y) + if (!S.getLangOpts().CPlusPlus14) return false; // In C++1y, we need to perform overload resolution. Ctor = false; @@ -4818,8 +5093,8 @@ static FunctionProtoType::ExtProtoInfo getImplicitMethodEPI(Sema &S, FunctionProtoType::ExtProtoInfo EPI; // Build an exception specification pointing back at this member. - EPI.ExceptionSpecType = EST_Unevaluated; - EPI.ExceptionSpecDecl = MD; + EPI.ExceptionSpec.Type = EST_Unevaluated; + EPI.ExceptionSpec.SourceDecl = MD; // Set the calling convention to the default for C++ instance methods. EPI.ExtInfo = EPI.ExtInfo.withCallingConv( @@ -4834,14 +5109,10 @@ void Sema::EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD) return; // Evaluate the exception specification. - ImplicitExceptionSpecification ExceptSpec = - computeImplicitExceptionSpec(*this, Loc, MD); - - FunctionProtoType::ExtProtoInfo EPI; - ExceptSpec.getEPI(EPI); + auto ESI = computeImplicitExceptionSpec(*this, Loc, MD).getExceptionSpec(); // Update the type of the special member to use it. - UpdateExceptionSpec(MD, EPI); + UpdateExceptionSpec(MD, ESI); // A user-provided destructor can be defined outside the class. When that // happens, be sure to update the exception specification on both @@ -4849,7 +5120,7 @@ void Sema::EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD) const FunctionProtoType *CanonicalFPT = MD->getCanonicalDecl()->getType()->castAs<FunctionProtoType>(); if (CanonicalFPT->getExceptionSpecType() == EST_Unevaluated) - UpdateExceptionSpec(MD->getCanonicalDecl(), EPI); + UpdateExceptionSpec(MD->getCanonicalDecl(), ESI); } void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) { @@ -4911,7 +5182,7 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) { // A defaulted special member cannot have cv-qualifiers. if (Type->getTypeQuals()) { Diag(MD->getLocation(), diag::err_defaulted_special_member_quals) - << (CSM == CXXMoveAssignment) << getLangOpts().CPlusPlus1y; + << (CSM == CXXMoveAssignment) << getLangOpts().CPlusPlus14; HadError = true; } } @@ -4960,7 +5231,7 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) { // destructors in C++1y), this is checked elsewhere. bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, RD, CSM, HasConstParam); - if ((getLangOpts().CPlusPlus1y ? !isa<CXXDestructorDecl>(MD) + if ((getLangOpts().CPlusPlus14 ? !isa<CXXDestructorDecl>(MD) : isa<CXXConstructorDecl>(MD)) && MD->isConstexpr() && !Constexpr && MD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) { @@ -4995,10 +5266,10 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) { // -- it is implicitly considered to have the same exception-specification // as if it had been implicitly declared, FunctionProtoType::ExtProtoInfo EPI = Type->getExtProtoInfo(); - EPI.ExceptionSpecType = EST_Unevaluated; - EPI.ExceptionSpecDecl = MD; + EPI.ExceptionSpec.Type = EST_Unevaluated; + EPI.ExceptionSpec.SourceDecl = MD; MD->setType(Context.getFunctionType(ReturnType, - ArrayRef<QualType>(&ArgType, + llvm::makeArrayRef(&ArgType, ExpectedParams), EPI)); } @@ -5026,11 +5297,18 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) { /// C++11 [dcl.fct.def.default]p2. void Sema::CheckExplicitlyDefaultedMemberExceptionSpec( CXXMethodDecl *MD, const FunctionProtoType *SpecifiedType) { + // If the exception specification was explicitly specified but hadn't been + // parsed when the method was defaulted, grab it now. + if (SpecifiedType->getExceptionSpecType() == EST_Unparsed) + SpecifiedType = + MD->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>(); + // Compute the implicit exception specification. CallingConv CC = Context.getDefaultCallingConvention(/*IsVariadic=*/false, /*IsCXXMethod=*/true); FunctionProtoType::ExtProtoInfo EPI(CC); - computeImplicitExceptionSpec(*this, MD->getLocation(), MD).getEPI(EPI); + EPI.ExceptionSpec = computeImplicitExceptionSpec(*this, MD->getLocation(), MD) + .getExceptionSpec(); const FunctionProtoType *ImplicitType = cast<FunctionProtoType>( Context.getFunctionType(Context.VoidTy, None, EPI)); @@ -5043,27 +5321,21 @@ void Sema::CheckExplicitlyDefaultedMemberExceptionSpec( } void Sema::CheckDelayedMemberExceptionSpecs() { - SmallVector<std::pair<const CXXDestructorDecl *, const CXXDestructorDecl *>, - 2> Checks; - SmallVector<std::pair<CXXMethodDecl *, const FunctionProtoType *>, 2> Specs; + decltype(DelayedExceptionSpecChecks) Checks; + decltype(DelayedDefaultedMemberExceptionSpecs) Specs; - std::swap(Checks, DelayedDestructorExceptionSpecChecks); + std::swap(Checks, DelayedExceptionSpecChecks); std::swap(Specs, DelayedDefaultedMemberExceptionSpecs); // Perform any deferred checking of exception specifications for virtual // destructors. - for (unsigned i = 0, e = Checks.size(); i != e; ++i) { - const CXXDestructorDecl *Dtor = Checks[i].first; - assert(!Dtor->getParent()->isDependentType() && - "Should not ever add destructors of templates into the list."); - CheckOverridingFunctionExceptionSpec(Dtor, Checks[i].second); - } + for (auto &Check : Checks) + CheckOverridingFunctionExceptionSpec(Check.first, Check.second); // Check that any explicitly-defaulted methods have exception specifications // compatible with their implicit exception specifications. - for (unsigned I = 0, N = Specs.size(); I != N; ++I) - CheckExplicitlyDefaultedMemberExceptionSpec(Specs[I].first, - Specs[I].second); + for (auto &Spec : Specs) + CheckExplicitlyDefaultedMemberExceptionSpec(Spec.first, Spec.second); } namespace { @@ -5491,6 +5763,13 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, if (SMI.shouldDeleteForAllConstMembers()) return true; + if (getLangOpts().CUDA) { + // We should delete the special member in CUDA mode if target inference + // failed. + return inferCUDATargetForImplicitSpecialMember(RD, CSM, MD, SMI.ConstArg, + Diagnose); + } + return false; } @@ -5907,7 +6186,7 @@ namespace { /// \brief Check whether any most overriden method from MD in Methods static bool CheckMostOverridenMethods(const CXXMethodDecl *MD, - const llvm::SmallPtrSet<const CXXMethodDecl *, 8>& Methods) { + const llvm::SmallPtrSetImpl<const CXXMethodDecl *>& Methods) { if (MD->size_overridden_methods() == 0) return Methods.count(MD->getCanonicalDecl()); for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), @@ -5945,7 +6224,14 @@ static bool FindHiddenVirtualMethod(const CXXBaseSpecifier *Specifier, if (!MD->isVirtual()) continue; // If the method we are checking overrides a method from its base - // don't warn about the other overloaded methods. + // don't warn about the other overloaded methods. Clang deviates from GCC + // by only diagnosing overloads of inherited virtual functions that do not + // override any other virtual functions in the base. GCC's + // -Woverloaded-virtual diagnoses any derived function hiding a virtual + // function from a base class. These cases may be better served by a + // warning (not specific to virtual functions) on call sites when the call + // would select a different function from the base class, were it visible. + // See FIXME in test/SemaCXX/warn-overload-virtual.cpp for an example. if (!Data.S->IsOverload(Data.Method, MD, false)) return true; // Collect the overload only if its hidden. @@ -5962,7 +6248,7 @@ static bool FindHiddenVirtualMethod(const CXXBaseSpecifier *Specifier, /// \brief Add the most overriden methods from MD to Methods static void AddMostOverridenMethods(const CXXMethodDecl *MD, - llvm::SmallPtrSet<const CXXMethodDecl *, 8>& Methods) { + llvm::SmallPtrSetImpl<const CXXMethodDecl *>& Methods) { if (MD->size_overridden_methods() == 0) Methods.insert(MD->getCanonicalDecl()); for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), @@ -6515,6 +6801,22 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R, return Context.getFunctionType(Context.VoidTy, None, EPI); } +static void extendLeft(SourceRange &R, const SourceRange &Before) { + if (Before.isInvalid()) + return; + R.setBegin(Before.getBegin()); + if (R.getEnd().isInvalid()) + R.setEnd(Before.getEnd()); +} + +static void extendRight(SourceRange &R, const SourceRange &After) { + if (After.isInvalid()) + return; + if (R.getBegin().isInvalid()) + R.setBegin(After.getBegin()); + R.setEnd(After.getEnd()); +} + /// CheckConversionDeclarator - Called by ActOnDeclarator to check the /// well-formednes of the conversion function declarator @p D with /// type @p R. If there are any errors in the declarator, this routine @@ -6536,7 +6838,9 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, SC = SC_None; } - QualType ConvType = GetTypeFromParser(D.getName().ConversionFunctionId); + TypeSourceInfo *ConvTSI = nullptr; + QualType ConvType = + GetTypeFromParser(D.getName().ConversionFunctionId, &ConvTSI); if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) { // Conversion functions don't have return types, but the parser will @@ -6570,9 +6874,75 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, // Diagnose "&operator bool()" and other such nonsense. This // is actually a gcc extension which we don't support. if (Proto->getReturnType() != ConvType) { - Diag(D.getIdentifierLoc(), diag::err_conv_function_with_complex_decl) - << Proto->getReturnType(); - D.setInvalidType(); + bool NeedsTypedef = false; + SourceRange Before, After; + + // Walk the chunks and extract information on them for our diagnostic. + bool PastFunctionChunk = false; + for (auto &Chunk : D.type_objects()) { + switch (Chunk.Kind) { + case DeclaratorChunk::Function: + if (!PastFunctionChunk) { + if (Chunk.Fun.HasTrailingReturnType) { + TypeSourceInfo *TRT = nullptr; + GetTypeFromParser(Chunk.Fun.getTrailingReturnType(), &TRT); + if (TRT) extendRight(After, TRT->getTypeLoc().getSourceRange()); + } + PastFunctionChunk = true; + break; + } + // Fall through. + case DeclaratorChunk::Array: + NeedsTypedef = true; + extendRight(After, Chunk.getSourceRange()); + break; + + case DeclaratorChunk::Pointer: + case DeclaratorChunk::BlockPointer: + case DeclaratorChunk::Reference: + case DeclaratorChunk::MemberPointer: + extendLeft(Before, Chunk.getSourceRange()); + break; + + case DeclaratorChunk::Paren: + extendLeft(Before, Chunk.Loc); + extendRight(After, Chunk.EndLoc); + break; + } + } + + SourceLocation Loc = Before.isValid() ? Before.getBegin() : + After.isValid() ? After.getBegin() : + D.getIdentifierLoc(); + auto &&DB = Diag(Loc, diag::err_conv_function_with_complex_decl); + DB << Before << After; + + if (!NeedsTypedef) { + DB << /*don't need a typedef*/0; + + // If we can provide a correct fix-it hint, do so. + if (After.isInvalid() && ConvTSI) { + SourceLocation InsertLoc = + PP.getLocForEndOfToken(ConvTSI->getTypeLoc().getLocEnd()); + DB << FixItHint::CreateInsertion(InsertLoc, " ") + << FixItHint::CreateInsertionFromRange( + InsertLoc, CharSourceRange::getTokenRange(Before)) + << FixItHint::CreateRemoval(Before); + } + } else if (!Proto->getReturnType()->isDependentType()) { + DB << /*typedef*/1 << Proto->getReturnType(); + } else if (getLangOpts().CPlusPlus11) { + DB << /*alias template*/2 << Proto->getReturnType(); + } else { + DB << /*might not be fixable*/3; + } + + // Recover by incorporating the other type chunks into the result type. + // Note, this does *not* change the name of the function. This is compatible + // with the GCC extension: + // struct S { &operator int(); } s; + // int &r = s.operator int(); // ok in GCC + // S::operator int&() {} // error in GCC, function name is 'operator int'. ConvType = Proto->getReturnType(); } @@ -6893,7 +7263,7 @@ NamespaceDecl *Sema::getOrCreateStdNamespace() { /*PrevDecl=*/nullptr); getStdNamespace()->setImplicit(true); } - + return getStdNamespace(); } @@ -7054,12 +7424,11 @@ static bool TryNamespaceTypoCorrection(Sema &S, LookupResult &R, Scope *Sc, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *Ident) { - NamespaceValidatorCCC Validator; R.clear(); - if (TypoCorrection Corrected = S.CorrectTypo(R.getLookupNameInfo(), - R.getLookupKind(), Sc, &SS, - Validator, - Sema::CTK_ErrorRecovery)) { + if (TypoCorrection Corrected = + S.CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), Sc, &SS, + llvm::make_unique<NamespaceValidatorCCC>(), + Sema::CTK_ErrorRecovery)) { if (DeclContext *DC = S.computeDeclContext(SS, false)) { std::string CorrectedStr(Corrected.getAsString(S.getLangOpts())); bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && @@ -7124,6 +7493,10 @@ Decl *Sema::ActOnUsingDirective(Scope *S, NamedDecl *Named = R.getFoundDecl(); assert((isa<NamespaceDecl>(Named) || isa<NamespaceAliasDecl>(Named)) && "expected namespace decl"); + + // The use of a nested name specifier may trigger deprecation warnings. + DiagnoseUseOfDecl(Named, IdentLoc); + // C++ [namespace.udir]p1: // A using-directive specifies that the names in the nominated // namespace can be used in the scope in which the @@ -7685,11 +8058,12 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, // Try to correct typos if possible. if (R.empty()) { - UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation, SS.getScopeRep(), - dyn_cast<CXXRecordDecl>(CurContext)); - if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), - R.getLookupKind(), S, &SS, CCC, - CTK_ErrorRecovery)){ + if (TypoCorrection Corrected = CorrectTypo( + R.getLookupNameInfo(), R.getLookupKind(), S, &SS, + llvm::make_unique<UsingValidatorCCC>( + HasTypenameKeyword, IsInstantiation, SS.getScopeRep(), + dyn_cast<CXXRecordDecl>(CurContext)), + CTK_ErrorRecovery)) { // We reject any correction for which ND would be NULL. NamedDecl *ND = Corrected.getCorrectionDecl(); @@ -7874,7 +8248,7 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc, // If we weren't able to compute a valid scope, it must be a // dependent class scope. if (!NamedContext || NamedContext->isRecord()) { - auto *RD = dyn_cast<CXXRecordDecl>(NamedContext); + auto *RD = dyn_cast_or_null<CXXRecordDecl>(NamedContext); if (RD && RequireCompleteDeclContext(const_cast<CXXScopeSpec&>(SS), RD)) RD = nullptr; @@ -8164,6 +8538,7 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, TypeAliasTemplateDecl::Create(Context, CurContext, UsingLoc, Name.Identifier, TemplateParams, NewTD); + NewTD->setDescribedAliasTemplate(NewDecl); NewDecl->setAccess(AS); @@ -8185,57 +8560,65 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, return NewND; } -Decl *Sema::ActOnNamespaceAliasDef(Scope *S, - SourceLocation NamespaceLoc, - SourceLocation AliasLoc, - IdentifierInfo *Alias, - CXXScopeSpec &SS, - SourceLocation IdentLoc, - IdentifierInfo *Ident) { +Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc, + SourceLocation AliasLoc, + IdentifierInfo *Alias, CXXScopeSpec &SS, + SourceLocation IdentLoc, + IdentifierInfo *Ident) { // Lookup the namespace name. LookupResult R(*this, Ident, IdentLoc, LookupNamespaceName); LookupParsedName(R, S, &SS); + if (R.isAmbiguous()) + return nullptr; + + if (R.empty()) { + if (!TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, Ident)) { + Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange(); + return nullptr; + } + } + assert(!R.isAmbiguous() && !R.empty()); + // Check if we have a previous declaration with the same name. - NamedDecl *PrevDecl - = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName, - ForRedeclaration); + NamedDecl *PrevDecl = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName, + ForRedeclaration); if (PrevDecl && !isDeclInScope(PrevDecl, CurContext, S)) PrevDecl = nullptr; + NamedDecl *ND = R.getFoundDecl(); + if (PrevDecl) { if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(PrevDecl)) { // We already have an alias with the same name that points to the same - // namespace, so don't create a new one. - // FIXME: At some point, we'll want to create the (redundant) - // declaration to maintain better source information. - if (!R.isAmbiguous() && !R.empty() && - AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl()))) + // namespace; check that it matches. + if (!AD->getNamespace()->Equals(getNamespaceDecl(ND))) { + Diag(AliasLoc, diag::err_redefinition_different_namespace_alias) + << Alias; + Diag(PrevDecl->getLocation(), diag::note_previous_namespace_alias) + << AD->getNamespace(); return nullptr; - } - - unsigned DiagID = isa<NamespaceDecl>(PrevDecl) ? diag::err_redefinition : - diag::err_redefinition_different_kind; - Diag(AliasLoc, DiagID) << Alias; - Diag(PrevDecl->getLocation(), diag::note_previous_definition); - return nullptr; - } - - if (R.isAmbiguous()) - return nullptr; - - if (R.empty()) { - if (!TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, Ident)) { - Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange(); + } + } else { + unsigned DiagID = isa<NamespaceDecl>(PrevDecl) + ? diag::err_redefinition + : diag::err_redefinition_different_kind; + Diag(AliasLoc, DiagID) << Alias; + Diag(PrevDecl->getLocation(), diag::note_previous_definition); return nullptr; } } + // The use of a nested name specifier may trigger deprecation warnings. + DiagnoseUseOfDecl(ND, IdentLoc); + NamespaceAliasDecl *AliasDecl = NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc, Alias, SS.getWithLocInContext(Context), - IdentLoc, R.getFoundDecl()); + IdentLoc, ND); + if (PrevDecl) + AliasDecl->setPreviousDecl(cast<NamespaceAliasDecl>(PrevDecl)); PushOnScopeChains(AliasDecl, S); return AliasDecl; @@ -8285,22 +8668,6 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc, if (F->hasInClassInitializer()) { if (Expr *E = F->getInClassInitializer()) ExceptSpec.CalledExpr(E); - else if (!F->isInvalidDecl()) - // DR1351: - // If the brace-or-equal-initializer of a non-static data member - // invokes a defaulted default constructor of its class or of an - // enclosing class in a potentially evaluated subexpression, the - // program is ill-formed. - // - // This resolution is unworkable: the exception specification of the - // default constructor can be needed in an unevaluated context, in - // particular, in the operand of a noexcept-expression, and we can be - // unable to compute an exception specification for an enclosed class. - // - // We do not allow an in-class initializer to require the evaluation - // of the exception specification for any in-class initializer whose - // definition is not lexically complete. - Diag(Loc, diag::err_in_class_initializer_references_def_ctor) << MD; } else if (const RecordType *RecordTy = Context.getBaseElementType(F->getType())->getAs<RecordType>()) { CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl()); @@ -8368,9 +8735,6 @@ Sema::ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD) { if (F->hasInClassInitializer()) { if (Expr *E = F->getInClassInitializer()) ExceptSpec.CalledExpr(E); - else if (!F->isInvalidDecl()) - Diag(CD->getLocation(), - diag::err_in_class_initializer_references_def_ctor) << CD; } else if (const RecordType *RecordTy = Context.getBaseElementType(F->getType())->getAs<RecordType>()) { CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl()); @@ -8392,7 +8756,7 @@ struct DeclaringSpecialMember { DeclaringSpecialMember(Sema &S, CXXRecordDecl *RD, Sema::CXXSpecialMember CSM) : S(S), D(RD, CSM) { - WasAlreadyBeingDeclared = !S.SpecialMembersBeingDeclared.insert(D); + WasAlreadyBeingDeclared = !S.SpecialMembersBeingDeclared.insert(D).second; if (WasAlreadyBeingDeclared) // This almost never happens, but if it does, ensure that our cache // doesn't contain a stale result. @@ -8421,7 +8785,7 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor( // user-declared constructor for class X, a default constructor is // implicitly declared. An implicitly-declared default constructor // is an inline public member of its class. - assert(ClassDecl->needsImplicitDefaultConstructor() && + assert(ClassDecl->needsImplicitDefaultConstructor() && "Should not build implicit default constructor!"); DeclaringSpecialMember DSM(*this, ClassDecl, CXXDefaultConstructor); @@ -8445,7 +8809,13 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor( /*isImplicitlyDeclared=*/true, Constexpr); DefaultCon->setAccess(AS_public); DefaultCon->setDefaulted(); - DefaultCon->setImplicit(); + + if (getLangOpts().CUDA) { + inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXDefaultConstructor, + DefaultCon, + /* ConstRHS */ false, + /* Diagnose */ false); + } // Build an exception specification pointing back at this constructor. FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, DefaultCon); @@ -8488,6 +8858,11 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, return; } + // The exception specification is needed because we are defining the + // function. + ResolveExceptionSpec(CurrentLocation, + Constructor->getType()->castAs<FunctionProtoType>()); + SourceLocation Loc = Constructor->getLocEnd().isValid() ? Constructor->getLocEnd() : Constructor->getLocation(); @@ -8597,7 +8972,7 @@ private: void inherit(const CXXConstructorDecl *Ctor) { const FunctionProtoType *CtorType = Ctor->getType()->castAs<FunctionProtoType>(); - ArrayRef<QualType> ArgTypes(CtorType->getParamTypes()); + ArrayRef<QualType> ArgTypes = CtorType->getParamTypes(); FunctionProtoType::ExtProtoInfo EPI = CtorType->getExtProtoInfo(); SourceLocation UsingLoc = getUsingLoc(Ctor->getParent()); @@ -8737,8 +9112,8 @@ private: // Build an unevaluated exception specification for this constructor. const FunctionProtoType *FPT = DerivedType->castAs<FunctionProtoType>(); FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - EPI.ExceptionSpecType = EST_Unevaluated; - EPI.ExceptionSpecDecl = DerivedCtor; + EPI.ExceptionSpec.Type = EST_Unevaluated; + EPI.ExceptionSpec.SourceDecl = DerivedCtor; DerivedCtor->setType(Context.getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI)); @@ -8900,7 +9275,13 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) { /*isImplicitlyDeclared=*/true); Destructor->setAccess(AS_public); Destructor->setDefaulted(); - Destructor->setImplicit(); + + if (getLangOpts().CUDA) { + inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXDestructor, + Destructor, + /* ConstRHS */ false, + /* Diagnose */ false); + } // Build an exception specification pointing back at this destructor. FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, Destructor); @@ -8952,6 +9333,11 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, return; } + // The exception specification is needed because we are defining the + // function. + ResolveExceptionSpec(CurrentLocation, + Destructor->getType()->castAs<FunctionProtoType>()); + SourceLocation Loc = Destructor->getLocEnd().isValid() ? Destructor->getLocEnd() : Destructor->getLocation(); @@ -8971,7 +9357,7 @@ void Sema::ActOnFinishCXXMemberDecls() { if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(CurContext)) { if (Record->isInvalidDecl()) { DelayedDefaultedMemberExceptionSpecs.clear(); - DelayedDestructorExceptionSpecChecks.clear(); + DelayedExceptionSpecChecks.clear(); return; } } @@ -8995,8 +9381,8 @@ void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl, // the only thing of interest in the destructor type is its extended info. // The return and arguments are fixed. FunctionProtoType::ExtProtoInfo EPI = DtorType->getExtProtoInfo(); - EPI.ExceptionSpecType = EST_Unevaluated; - EPI.ExceptionSpecDecl = Destructor; + EPI.ExceptionSpec.Type = EST_Unevaluated; + EPI.ExceptionSpec.SourceDecl = Destructor; Destructor->setType(Context.getFunctionType(Context.VoidTy, None, EPI)); // FIXME: If the destructor has a body that could throw, and the newly created @@ -9032,7 +9418,7 @@ class RefBuilder: public ExprBuilder { QualType VarType; public: - virtual Expr *build(Sema &S, SourceLocation Loc) const override { + Expr *build(Sema &S, SourceLocation Loc) const override { return assertNotNull(S.BuildDeclRefExpr(Var, VarType, VK_LValue, Loc).get()); } @@ -9042,7 +9428,7 @@ public: class ThisBuilder: public ExprBuilder { public: - virtual Expr *build(Sema &S, SourceLocation Loc) const override { + Expr *build(Sema &S, SourceLocation Loc) const override { return assertNotNull(S.ActOnCXXThis(Loc).getAs<Expr>()); } }; @@ -9054,7 +9440,7 @@ class CastBuilder: public ExprBuilder { const CXXCastPath &Path; public: - virtual Expr *build(Sema &S, SourceLocation Loc) const override { + Expr *build(Sema &S, SourceLocation Loc) const override { return assertNotNull(S.ImpCastExprToType(Builder.build(S, Loc), Type, CK_UncheckedDerivedToBase, Kind, &Path).get()); @@ -9069,7 +9455,7 @@ class DerefBuilder: public ExprBuilder { const ExprBuilder &Builder; public: - virtual Expr *build(Sema &S, SourceLocation Loc) const override { + Expr *build(Sema &S, SourceLocation Loc) const override { return assertNotNull( S.CreateBuiltinUnaryOp(Loc, UO_Deref, Builder.build(S, Loc)).get()); } @@ -9085,7 +9471,7 @@ class MemberBuilder: public ExprBuilder { LookupResult &MemberLookup; public: - virtual Expr *build(Sema &S, SourceLocation Loc) const override { + Expr *build(Sema &S, SourceLocation Loc) const override { return assertNotNull(S.BuildMemberReferenceExpr( Builder.build(S, Loc), Type, Loc, IsArrow, SS, SourceLocation(), nullptr, MemberLookup, nullptr).get()); @@ -9101,7 +9487,7 @@ class MoveCastBuilder: public ExprBuilder { const ExprBuilder &Builder; public: - virtual Expr *build(Sema &S, SourceLocation Loc) const override { + Expr *build(Sema &S, SourceLocation Loc) const override { return assertNotNull(CastForMoving(S, Builder.build(S, Loc))); } @@ -9112,7 +9498,7 @@ class LvalueConvBuilder: public ExprBuilder { const ExprBuilder &Builder; public: - virtual Expr *build(Sema &S, SourceLocation Loc) const override { + Expr *build(Sema &S, SourceLocation Loc) const override { return assertNotNull( S.DefaultLvalueConversion(Builder.build(S, Loc)).get()); } @@ -9125,7 +9511,7 @@ class SubscriptBuilder: public ExprBuilder { const ExprBuilder &Index; public: - virtual Expr *build(Sema &S, SourceLocation Loc) const override { + Expr *build(Sema &S, SourceLocation Loc) const override { return assertNotNull(S.CreateBuiltinArraySubscriptExpr( Base.build(S, Loc), Loc, Index.build(S, Loc), Loc).get()); } @@ -9521,6 +9907,13 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) { CopyAssignment->setDefaulted(); CopyAssignment->setImplicit(); + if (getLangOpts().CUDA) { + inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXCopyAssignment, + CopyAssignment, + /* ConstRHS */ Const, + /* Diagnose */ false); + } + // Build an exception specification pointing back at this member. FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, CopyAssignment); @@ -9795,6 +10188,11 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, } } + // The exception specification is needed because we are defining the + // function. + ResolveExceptionSpec(CurrentLocation, + CopyAssignOperator->getType()->castAs<FunctionProtoType>()); + if (Invalid) { CopyAssignOperator->setInvalidDecl(); return; @@ -9898,6 +10296,13 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) { MoveAssignment->setDefaulted(); MoveAssignment->setImplicit(); + if (getLangOpts().CUDA) { + inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXMoveAssignment, + MoveAssignment, + /* ConstRHS */ false, + /* Diagnose */ false); + } + // Build an exception specification pointing back at this member. FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, MoveAssignment); @@ -10217,6 +10622,11 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, } } + // The exception specification is needed because we are defining the + // function. + ResolveExceptionSpec(CurrentLocation, + MoveAssignOperator->getType()->castAs<FunctionProtoType>()); + if (Invalid) { MoveAssignOperator->setInvalidDecl(); return; @@ -10319,6 +10729,13 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor( CopyConstructor->setAccess(AS_public); CopyConstructor->setDefaulted(); + if (getLangOpts().CUDA) { + inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXCopyConstructor, + CopyConstructor, + /* ConstRHS */ Const, + /* Diagnose */ false); + } + // Build an exception specification pointing back at this member. FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, CopyConstructor); @@ -10386,6 +10803,11 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, ActOnCompoundStmt(Loc, Loc, None, /*isStmtExpr=*/false).getAs<Stmt>()); } + // The exception specification is needed because we are defining the + // function. + ResolveExceptionSpec(CurrentLocation, + CopyConstructor->getType()->castAs<FunctionProtoType>()); + CopyConstructor->markUsed(Context); MarkVTableUsed(CurrentLocation, ClassDecl); @@ -10484,6 +10906,13 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor( MoveConstructor->setAccess(AS_public); MoveConstructor->setDefaulted(); + if (getLangOpts().CUDA) { + inferCUDATargetForImplicitSpecialMember(ClassDecl, CXXMoveConstructor, + MoveConstructor, + /* ConstRHS */ false, + /* Diagnose */ false); + } + // Build an exception specification pointing back at this member. FunctionProtoType::ExtProtoInfo EPI = getImplicitMethodEPI(*this, MoveConstructor); @@ -10546,6 +10975,11 @@ void Sema::DefineImplicitMoveConstructor(SourceLocation CurrentLocation, Loc, Loc, None, /*isStmtExpr=*/ false).getAs<Stmt>()); } + // The exception specification is needed because we are defining the + // function. + ResolveExceptionSpec(CurrentLocation, + MoveConstructor->getType()->castAs<FunctionProtoType>()); + MoveConstructor->markUsed(Context); MarkVTableUsed(CurrentLocation, ClassDecl); @@ -10765,6 +11199,56 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, ParenRange); } +ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { + assert(Field->hasInClassInitializer()); + + // If we already have the in-class initializer nothing needs to be done. + if (Field->getInClassInitializer()) + return CXXDefaultInitExpr::Create(Context, Loc, Field); + + // Maybe we haven't instantiated the in-class initializer. Go check the + // pattern FieldDecl to see if it has one. + CXXRecordDecl *ParentRD = cast<CXXRecordDecl>(Field->getParent()); + + if (isTemplateInstantiation(ParentRD->getTemplateSpecializationKind())) { + CXXRecordDecl *ClassPattern = ParentRD->getTemplateInstantiationPattern(); + DeclContext::lookup_result Lookup = + ClassPattern->lookup(Field->getDeclName()); + assert(Lookup.size() == 1); + FieldDecl *Pattern = cast<FieldDecl>(Lookup[0]); + if (InstantiateInClassInitializer(Loc, Field, Pattern, + getTemplateInstantiationArgs(Field))) + return ExprError(); + return CXXDefaultInitExpr::Create(Context, Loc, Field); + } + + // DR1351: + // If the brace-or-equal-initializer of a non-static data member + // invokes a defaulted default constructor of its class or of an + // enclosing class in a potentially evaluated subexpression, the + // program is ill-formed. + // + // This resolution is unworkable: the exception specification of the + // default constructor can be needed in an unevaluated context, in + // particular, in the operand of a noexcept-expression, and we can be + // unable to compute an exception specification for an enclosed class. + // + // Any attempt to resolve the exception specification of a defaulted default + // constructor before the initializer is lexically complete will ultimately + // come here at which point we can diagnose it. + RecordDecl *OutermostClass = ParentRD->getOuterLexicalRecordContext(); + if (OutermostClass == ParentRD) { + Diag(Field->getLocEnd(), diag::err_in_class_initializer_not_yet_parsed) + << ParentRD << Field; + } else { + Diag(Field->getLocEnd(), + diag::err_in_class_initializer_not_yet_parsed_outer_class) + << ParentRD << OutermostClass << Field; + } + + return ExprError(); +} + void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) { if (VD->isInvalidDecl()) return; @@ -10834,8 +11318,7 @@ Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, DiagnoseSentinelCalls(Constructor, Loc, AllArgs); CheckConstructorCall(Constructor, - llvm::makeArrayRef<const Expr *>(AllArgs.data(), - AllArgs.size()), + llvm::makeArrayRef(AllArgs.data(), AllArgs.size()), Proto, Loc); return Invalid; @@ -12118,8 +12601,12 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D, } // Mark templated-scope function declarations as unsupported. - if (FD->getNumTemplateParameterLists()) + if (FD->getNumTemplateParameterLists() && SS.isValid()) { + Diag(FD->getLocation(), diag::warn_template_qualified_friend_unsupported) + << SS.getScopeRep() << SS.getRange() + << cast<CXXRecordDecl>(CurContext); FrD->setUnsupportedFriend(true); + } } return ND; @@ -12220,11 +12707,6 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { CheckExplicitlyDefaultedSpecialMember(MD); - // The exception specification is needed because we are defining the - // function. - ResolveExceptionSpec(DefaultLoc, - MD->getType()->castAs<FunctionProtoType>()); - if (MD->isInvalidDecl()) return; @@ -12538,7 +13020,7 @@ void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, Pos = VTablesUsed.insert(std::make_pair(Class, DefinitionRequired)); if (!Pos.second) { // If we already had an entry, check to see if we are promoting this vtable - // to required a definition. If so, we need to reappend to the VTableUses + // to require a definition. If so, we need to reappend to the VTableUses // list, since we may have already processed the first entry. if (DefinitionRequired && !Pos.first->second) { Pos.first->second = true; @@ -12739,10 +13221,10 @@ void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) { AllToInit.push_back(Member); // Be sure that the destructor is accessible and is marked as referenced. - if (const RecordType *RecordTy - = Context.getBaseElementType(Field->getType()) - ->getAs<RecordType>()) { - CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); + if (const RecordType *RecordTy = + Context.getBaseElementType(Field->getType()) + ->getAs<RecordType>()) { + CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); if (CXXDestructorDecl *Destructor = LookupDestructor(RD)) { MarkFunctionReferenced(Field->getLocation(), Destructor); CheckDestructorAccess(Field->getLocation(), Destructor, @@ -12780,7 +13262,7 @@ void DelegatingCycleHelper(CXXConstructorDecl* Ctor, // Avoid dereferencing a null pointer here. *TCanonical = Target? Target->getCanonicalDecl() : nullptr; - if (!Current.insert(Canonical)) + if (!Current.insert(Canonical).second) return; // We know that beyond here, we aren't chaining into a cycle. @@ -12898,6 +13380,7 @@ bool Sema::checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method) { FindCXXThisExpr Finder(*this); switch (Proto->getExceptionSpecType()) { + case EST_Unparsed: case EST_Uninstantiated: case EST_Unevaluated: case EST_BasicNoexcept: @@ -12934,27 +13417,27 @@ bool Sema::checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method) { else if (const auto *G = dyn_cast<PtGuardedByAttr>(A)) Arg = G->getArg(); else if (const auto *AA = dyn_cast<AcquiredAfterAttr>(A)) - Args = ArrayRef<Expr *>(AA->args_begin(), AA->args_size()); + Args = llvm::makeArrayRef(AA->args_begin(), AA->args_size()); else if (const auto *AB = dyn_cast<AcquiredBeforeAttr>(A)) - Args = ArrayRef<Expr *>(AB->args_begin(), AB->args_size()); + Args = llvm::makeArrayRef(AB->args_begin(), AB->args_size()); else if (const auto *ETLF = dyn_cast<ExclusiveTrylockFunctionAttr>(A)) { Arg = ETLF->getSuccessValue(); - Args = ArrayRef<Expr *>(ETLF->args_begin(), ETLF->args_size()); + Args = llvm::makeArrayRef(ETLF->args_begin(), ETLF->args_size()); } else if (const auto *STLF = dyn_cast<SharedTrylockFunctionAttr>(A)) { Arg = STLF->getSuccessValue(); - Args = ArrayRef<Expr *>(STLF->args_begin(), STLF->args_size()); + Args = llvm::makeArrayRef(STLF->args_begin(), STLF->args_size()); } else if (const auto *LR = dyn_cast<LockReturnedAttr>(A)) Arg = LR->getArg(); else if (const auto *LE = dyn_cast<LocksExcludedAttr>(A)) - Args = ArrayRef<Expr *>(LE->args_begin(), LE->args_size()); + Args = llvm::makeArrayRef(LE->args_begin(), LE->args_size()); else if (const auto *RC = dyn_cast<RequiresCapabilityAttr>(A)) - Args = ArrayRef<Expr *>(RC->args_begin(), RC->args_size()); + Args = llvm::makeArrayRef(RC->args_begin(), RC->args_size()); else if (const auto *AC = dyn_cast<AcquireCapabilityAttr>(A)) - Args = ArrayRef<Expr *>(AC->args_begin(), AC->args_size()); + Args = llvm::makeArrayRef(AC->args_begin(), AC->args_size()); else if (const auto *AC = dyn_cast<TryAcquireCapabilityAttr>(A)) - Args = ArrayRef<Expr *>(AC->args_begin(), AC->args_size()); + Args = llvm::makeArrayRef(AC->args_begin(), AC->args_size()); else if (const auto *RC = dyn_cast<ReleaseCapabilityAttr>(A)) - Args = ArrayRef<Expr *>(RC->args_begin(), RC->args_size()); + Args = llvm::makeArrayRef(RC->args_begin(), RC->args_size()); if (Arg && !Finder.TraverseStmt(Arg)) return true; @@ -12968,28 +13451,29 @@ bool Sema::checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method) { return false; } -void -Sema::checkExceptionSpecification(ExceptionSpecificationType EST, - ArrayRef<ParsedType> DynamicExceptions, - ArrayRef<SourceRange> DynamicExceptionRanges, - Expr *NoexceptExpr, - SmallVectorImpl<QualType> &Exceptions, - FunctionProtoType::ExtProtoInfo &EPI) { +void Sema::checkExceptionSpecification( + bool IsTopLevel, ExceptionSpecificationType EST, + ArrayRef<ParsedType> DynamicExceptions, + ArrayRef<SourceRange> DynamicExceptionRanges, Expr *NoexceptExpr, + SmallVectorImpl<QualType> &Exceptions, + FunctionProtoType::ExceptionSpecInfo &ESI) { Exceptions.clear(); - EPI.ExceptionSpecType = EST; + ESI.Type = EST; if (EST == EST_Dynamic) { Exceptions.reserve(DynamicExceptions.size()); for (unsigned ei = 0, ee = DynamicExceptions.size(); ei != ee; ++ei) { // FIXME: Preserve type source info. QualType ET = GetTypeFromParser(DynamicExceptions[ei]); - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - collectUnexpandedParameterPacks(ET, Unexpanded); - if (!Unexpanded.empty()) { - DiagnoseUnexpandedParameterPacks(DynamicExceptionRanges[ei].getBegin(), - UPPC_ExceptionType, - Unexpanded); - continue; + if (IsTopLevel) { + SmallVector<UnexpandedParameterPack, 2> Unexpanded; + collectUnexpandedParameterPacks(ET, Unexpanded); + if (!Unexpanded.empty()) { + DiagnoseUnexpandedParameterPacks( + DynamicExceptionRanges[ei].getBegin(), UPPC_ExceptionType, + Unexpanded); + continue; + } } // Check that the type is valid for an exception spec, and @@ -12997,11 +13481,10 @@ Sema::checkExceptionSpecification(ExceptionSpecificationType EST, if (!CheckSpecifiedExceptionType(ET, DynamicExceptionRanges[ei])) Exceptions.push_back(ET); } - EPI.NumExceptions = Exceptions.size(); - EPI.Exceptions = Exceptions.data(); + ESI.Exceptions = Exceptions; return; } - + if (EST == EST_ComputedNoexcept) { // If an error occurred, there's no expression here. if (NoexceptExpr) { @@ -13009,59 +13492,59 @@ Sema::checkExceptionSpecification(ExceptionSpecificationType EST, NoexceptExpr->getType()->getCanonicalTypeUnqualified() == Context.BoolTy) && "Parser should have made sure that the expression is boolean"); - if (NoexceptExpr && DiagnoseUnexpandedParameterPack(NoexceptExpr)) { - EPI.ExceptionSpecType = EST_BasicNoexcept; + if (IsTopLevel && NoexceptExpr && + DiagnoseUnexpandedParameterPack(NoexceptExpr)) { + ESI.Type = EST_BasicNoexcept; return; } - + if (!NoexceptExpr->isValueDependent()) NoexceptExpr = VerifyIntegerConstantExpression(NoexceptExpr, nullptr, diag::err_noexcept_needs_constant_expression, /*AllowFold*/ false).get(); - EPI.NoexceptExpr = NoexceptExpr; + ESI.NoexceptExpr = NoexceptExpr; } return; } } -/// IdentifyCUDATarget - Determine the CUDA compilation target for this function -Sema::CUDAFunctionTarget Sema::IdentifyCUDATarget(const FunctionDecl *D) { - // Implicitly declared functions (e.g. copy constructors) are - // __host__ __device__ - if (D->isImplicit()) - return CFT_HostDevice; - - if (D->hasAttr<CUDAGlobalAttr>()) - return CFT_Global; +void Sema::actOnDelayedExceptionSpecification(Decl *MethodD, + ExceptionSpecificationType EST, + SourceRange SpecificationRange, + ArrayRef<ParsedType> DynamicExceptions, + ArrayRef<SourceRange> DynamicExceptionRanges, + Expr *NoexceptExpr) { + if (!MethodD) + return; - if (D->hasAttr<CUDADeviceAttr>()) { - if (D->hasAttr<CUDAHostAttr>()) - return CFT_HostDevice; - return CFT_Device; - } + // Dig out the method we're referring to. + if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(MethodD)) + MethodD = FunTmpl->getTemplatedDecl(); - return CFT_Host; -} + CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(MethodD); + if (!Method) + return; -bool Sema::CheckCUDATarget(CUDAFunctionTarget CallerTarget, - CUDAFunctionTarget CalleeTarget) { - // CUDA B.1.1 "The __device__ qualifier declares a function that is... - // Callable from the device only." - if (CallerTarget == CFT_Host && CalleeTarget == CFT_Device) - return true; + // Check the exception specification. + llvm::SmallVector<QualType, 4> Exceptions; + FunctionProtoType::ExceptionSpecInfo ESI; + checkExceptionSpecification(/*IsTopLevel*/true, EST, DynamicExceptions, + DynamicExceptionRanges, NoexceptExpr, Exceptions, + ESI); - // CUDA B.1.2 "The __global__ qualifier declares a function that is... - // Callable from the host only." - // CUDA B.1.3 "The __host__ qualifier declares a function that is... - // Callable from the host only." - if ((CallerTarget == CFT_Device || CallerTarget == CFT_Global) && - (CalleeTarget == CFT_Host || CalleeTarget == CFT_Global)) - return true; + // Update the exception specification on the function type. + Context.adjustExceptionSpec(Method, ESI, /*AsWritten*/true); - if (CallerTarget == CFT_HostDevice && CalleeTarget != CFT_HostDevice) - return true; + if (Method->isStatic()) + checkThisInStaticMemberFunctionExceptionSpec(Method); - return false; + if (Method->isVirtual()) { + // Check overrides, which we previously had to delay. + for (CXXMethodDecl::method_iterator O = Method->begin_overridden_methods(), + OEnd = Method->end_overridden_methods(); + O != OEnd; ++O) + CheckOverridingFunctionExceptionSpec(Method, *O); + } } /// HandleMSProperty - Analyze a __delcspec(property) field of a C++ class. |