diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-08-01 00:33:25 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-08-01 00:33:25 +0000 |
commit | f4e248c23e05e374910a8becbb91f5d3d7a76a01 (patch) | |
tree | 1a3f3fff462a6670e6dc5a7f3770882462294302 /clang/lib/Sema/SemaDecl.cpp | |
parent | eb159e56a65d71afd2db913ea389866295a24c00 (diff) | |
download | bcm5719-llvm-f4e248c23e05e374910a8becbb91f5d3d7a76a01.tar.gz bcm5719-llvm-f4e248c23e05e374910a8becbb91f5d3d7a76a01.zip |
[P0936R0] add [[clang::lifetimebound]] attribute
This patch adds support for a new attribute, [[clang::lifetimebound]], that
indicates that the lifetime of a function result is related to one of the
function arguments. When walking an initializer to make sure that the lifetime
of the initial value is at least as long as the lifetime of the initialized
object, we step through parameters (including the implicit object parameter of
a non-static member function) that are marked with this attribute.
There's nowhere to write an attribute on the implicit object parameter, so in
lieu of that, it may be applied to a function type (where it appears
immediately after the cv-qualifiers and ref-qualifier, which is as close to a
declaration of the implicit object parameter as we have). I'm currently
modeling this in the AST as the attribute appertaining to the function type.
Differential Revision: https://reviews.llvm.org/D49922
llvm-svn: 338464
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ccdb4d288e9..50ea98e7f60 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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, |