diff options
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ccdb4d288e..50ea98e7f6 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6008,6 +6008,27 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { << Attr; ND.dropAttr<NotTailCalledAttr>(); } + + // Check the attributes on the function type, if any. + if (const auto *FD = dyn_cast<FunctionDecl>(&ND)) { + for (TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc(); + auto ATL = TL.getAsAdjusted<AttributedTypeLoc>(); + TL = ATL.getModifiedLoc()) { + // The [[lifetimebound]] attribute can be applied to the implicit object + // parameter of a non-static member function (other than a ctor or dtor) + // by applying it to the function type. + if (ATL.getAttrKind() == AttributedType::attr_lifetimebound) { + const auto *MD = dyn_cast<CXXMethodDecl>(FD); + if (!MD || MD->isStatic()) { + S.Diag(ATL.getAttrNameLoc(), diag::err_lifetimebound_no_object_param) + << !MD << ATL.getLocalSourceRange(); + } else if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) { + S.Diag(ATL.getAttrNameLoc(), diag::err_lifetimebound_ctor_dtor) + << isa<CXXDestructorDecl>(MD) << ATL.getLocalSourceRange(); + } + } + } + } } static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl, |