summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-08-01 00:33:25 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-08-01 00:33:25 +0000
commitf4e248c23e05e374910a8becbb91f5d3d7a76a01 (patch)
tree1a3f3fff462a6670e6dc5a7f3770882462294302 /clang/lib/Sema/SemaDecl.cpp
parenteb159e56a65d71afd2db913ea389866295a24c00 (diff)
downloadbcm5719-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.cpp21
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,
OpenPOWER on IntegriCloud