diff options
| author | Erik Pilkington <erik.pilkington@gmail.com> | 2019-02-11 23:21:39 +0000 |
|---|---|---|
| committer | Erik Pilkington <erik.pilkington@gmail.com> | 2019-02-11 23:21:39 +0000 |
| commit | e3cd735ea6378e5dd7765828f560ed49be845a95 (patch) | |
| tree | 91101427ae598d9ea6ced7a2e44f0f4f209fe4a9 /clang/lib/Sema | |
| parent | 796ac80b863ed92c3d8bcc296f678ff416afc8a8 (diff) | |
| download | bcm5719-llvm-e3cd735ea6378e5dd7765828f560ed49be845a95.tar.gz bcm5719-llvm-e3cd735ea6378e5dd7765828f560ed49be845a95.zip | |
Add a new attribute, fortify_stdlib
This attribute applies to declarations of C stdlib functions
(sprintf, memcpy...) that have known fortified variants
(__sprintf_chk, __memcpy_chk, ...). When applied, clang will emit
calls to the fortified variant functions instead of calls to the
defaults.
In GCC, this is done by adding gnu_inline-style wrapper functions,
but that doesn't work for us for variadic functions because we don't
support __builtin_va_arg_pack (and have no intention to).
This attribute takes two arguments, the first is 'type' argument
passed through to __builtin_object_size, and the second is a flag
argument that gets passed through to the variadic checking variants.
rdar://47905754
Differential revision: https://reviews.llvm.org/D57918
llvm-svn: 353765
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index bb69070b264..7f0ccdc6e75 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6419,6 +6419,31 @@ static void handleObjCExternallyRetainedAttr(Sema &S, Decl *D, handleSimpleAttribute<ObjCExternallyRetainedAttr>(S, D, AL); } +static void handleFortifyStdLib(Sema &S, Decl *D, const ParsedAttr &AL) { + auto *FD = cast<FunctionDecl>(D); + unsigned VariantID = Builtin::getFortifiedVariantFunction(FD->getBuiltinID()); + if (VariantID == 0) { + S.Diag(D->getLocation(), diag::err_fortify_std_lib_bad_decl); + return; + } + + uint32_t BOSType, Flag; + if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), BOSType, 0, true) || + !checkUInt32Argument(S, AL, AL.getArgAsExpr(1), Flag, 1, true)) + return; + + if (BOSType > 3) { + S.Diag(AL.getArgAsExpr(0)->getBeginLoc(), + diag::err_attribute_argument_outof_range) + << AL << 0 << 3; + return; + } + + D->addAttr(::new (S.getASTContext()) FortifyStdLibAttr( + AL.getLoc(), S.getASTContext(), BOSType, Flag, + AL.getAttributeSpellingListIndex())); +} + //===----------------------------------------------------------------------===// // Top Level Sema Entry Points //===----------------------------------------------------------------------===// @@ -7148,6 +7173,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_ObjCExternallyRetained: handleObjCExternallyRetainedAttr(S, D, AL); break; + + case ParsedAttr::AT_FortifyStdLib: + handleFortifyStdLib(S, D, AL); + break; } } |

