diff options
author | George Burgess IV <george.burgess.iv@gmail.com> | 2015-12-02 21:58:08 +0000 |
---|---|---|
committer | George Burgess IV <george.burgess.iv@gmail.com> | 2015-12-02 21:58:08 +0000 |
commit | 3e3bb95b6951c313dd5dd1c099184c309a3952e2 (patch) | |
tree | 601f182e5509276b9319182864eac0e27a888b68 /clang/lib/Sema/SemaDeclAttr.cpp | |
parent | ba904d4ecf66528be5dadd60665d5a979ce6b1a4 (diff) | |
download | bcm5719-llvm-3e3bb95b6951c313dd5dd1c099184c309a3952e2.tar.gz bcm5719-llvm-3e3bb95b6951c313dd5dd1c099184c309a3952e2.zip |
Add the `pass_object_size` attribute to clang.
`pass_object_size` is our way of enabling `__builtin_object_size` to
produce high quality results without requiring inlining to happen
everywhere.
A link to the design doc for this attribute is available at the
Differential review link below.
Differential Revision: http://reviews.llvm.org/D13263
llvm-svn: 254554
Diffstat (limited to 'clang/lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index df1641af5f4..93e9eb15b36 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -809,6 +809,43 @@ static void handleEnableIfAttr(Sema &S, Decl *D, const AttributeList &Attr) { Attr.getAttributeSpellingListIndex())); } +static void handlePassObjectSizeAttr(Sema &S, Decl *D, + const AttributeList &Attr) { + if (D->hasAttr<PassObjectSizeAttr>()) { + S.Diag(D->getLocStart(), diag::err_attribute_only_once_per_parameter) + << Attr.getName(); + return; + } + + Expr *E = Attr.getArgAsExpr(0); + uint32_t Type; + if (!checkUInt32Argument(S, Attr, E, Type, /*Idx=*/1)) + return; + + // pass_object_size's argument is passed in as the second argument of + // __builtin_object_size. So, it has the same constraints as that second + // argument; namely, it must be in the range [0, 3]. + if (Type > 3) { + S.Diag(E->getLocStart(), diag::err_attribute_argument_outof_range) + << Attr.getName() << 0 << 3 << E->getSourceRange(); + return; + } + + // pass_object_size is only supported on constant pointer parameters; as a + // kindness to users, we allow the parameter to be non-const for declarations. + // At this point, we have no clue if `D` belongs to a function declaration or + // definition, so we defer the constness check until later. + if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) { + S.Diag(D->getLocStart(), diag::err_attribute_pointers_only) + << Attr.getName() << 1; + return; + } + + D->addAttr(::new (S.Context) + PassObjectSizeAttr(Attr.getRange(), S.Context, (int)Type, + Attr.getAttributeSpellingListIndex())); +} + static void handleConsumableAttr(Sema &S, Decl *D, const AttributeList &Attr) { ConsumableAttr::ConsumedState DefaultState; @@ -1162,10 +1199,12 @@ static bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &Attr, SourceRange TypeRange, bool isReturnValue = false) { if (!S.isValidPointerAttrType(T)) { - S.Diag(Attr.getLoc(), isReturnValue - ? diag::warn_attribute_return_pointers_only - : diag::warn_attribute_pointers_only) - << Attr.getName() << AttrParmRange << TypeRange; + if (isReturnValue) + S.Diag(Attr.getLoc(), diag::warn_attribute_return_pointers_only) + << Attr.getName() << AttrParmRange << TypeRange; + else + S.Diag(Attr.getLoc(), diag::warn_attribute_pointers_only) + << Attr.getName() << AttrParmRange << TypeRange << 0; return false; } return true; @@ -2724,7 +2763,7 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, if (prioritynum < 101 || prioritynum > 65535) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) - << E->getSourceRange(); + << E->getSourceRange() << Attr.getName() << 101 << 65535; Attr.setInvalid(); return; } @@ -3862,7 +3901,7 @@ static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, QualType BufferTy = getFunctionOrMethodParamType(D, ArgumentIdx); if (!BufferTy->isPointerType()) { S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only) - << Attr.getName(); + << Attr.getName() << 0; } } @@ -4972,6 +5011,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_CUDAConstant: handleSimpleAttribute<CUDAConstantAttr>(S, D, Attr); break; + case AttributeList::AT_PassObjectSize: + handlePassObjectSizeAttr(S, D, Attr); + break; case AttributeList::AT_Constructor: handleConstructorAttr(S, D, Attr); break; |