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/SemaDecl.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/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a6f2d5d6450..af5fdc95c90 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2621,6 +2621,21 @@ static bool checkUsingShadowRedecl(Sema &S, UsingShadowDecl *OldS, return false; } +static bool hasIdenticalPassObjectSizeAttrs(const FunctionDecl *A, + const FunctionDecl *B) { + assert(A->getNumParams() == B->getNumParams()); + + auto AttrEq = [](const ParmVarDecl *A, const ParmVarDecl *B) { + const auto *AttrA = A->getAttr<PassObjectSizeAttr>(); + const auto *AttrB = B->getAttr<PassObjectSizeAttr>(); + if (AttrA == AttrB) + return true; + return AttrA && AttrB && AttrA->getType() == AttrB->getType(); + }; + + return std::equal(A->param_begin(), A->param_end(), B->param_begin(), AttrEq); +} + /// MergeFunctionDecl - We just parsed a function 'New' from /// declarator D which has the same name and scope as a previous /// declaration 'Old'. Figure out how to resolve this situation, @@ -2799,7 +2814,17 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, Old->isInlined() && !Old->hasAttr<GNUInlineAttr>()) { UndefinedButUsed.erase(Old->getCanonicalDecl()); } - + + // If pass_object_size params don't match up perfectly, this isn't a valid + // redeclaration. + if (Old->getNumParams() > 0 && Old->getNumParams() == New->getNumParams() && + !hasIdenticalPassObjectSizeAttrs(Old, New)) { + Diag(New->getLocation(), diag::err_different_pass_object_size_params) + << New->getDeclName(); + Diag(OldLocation, PrevDiag) << Old << Old->getType(); + return true; + } + if (getLangOpts().CPlusPlus) { // (C++98 13.1p2): // Certain function declarations cannot be overloaded: |