summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
authorGeorge Burgess IV <george.burgess.iv@gmail.com>2015-12-02 21:58:08 +0000
committerGeorge Burgess IV <george.burgess.iv@gmail.com>2015-12-02 21:58:08 +0000
commit3e3bb95b6951c313dd5dd1c099184c309a3952e2 (patch)
tree601f182e5509276b9319182864eac0e27a888b68 /clang/lib/Sema/SemaDeclAttr.cpp
parentba904d4ecf66528be5dadd60665d5a979ce6b1a4 (diff)
downloadbcm5719-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.cpp54
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;
OpenPOWER on IntegriCloud