summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp24
1 files changed, 20 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index b74f6f94242..62e8fa03701 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1853,11 +1853,27 @@ void CodeGenModule::ConstructAttributeList(
if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
AddAttributesFromFunctionProtoType(
getContext(), FuncAttrs, Fn->getType()->getAs<FunctionProtoType>());
- // Don't use [[noreturn]] or _Noreturn for a call to a virtual function.
- // These attributes are not inherited by overloads.
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn);
- if (Fn->isNoReturn() && !(AttrOnCallSite && MD && MD->isVirtual()))
- FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
+ const bool IsVirtualCall = MD && MD->isVirtual();
+ // Don't use [[noreturn]], _Noreturn or [[no_builtin]] for a call to a
+ // virtual function. These attributes are not inherited by overloads.
+ if (!(AttrOnCallSite && IsVirtualCall)) {
+ if (Fn->isNoReturn())
+ FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
+
+ if (const auto *NBA = TargetDecl->getAttr<NoBuiltinAttr>()) {
+ bool HasWildcard = llvm::is_contained(NBA->builtinNames(), "*");
+ if (HasWildcard)
+ FuncAttrs.addAttribute("no-builtins");
+ else
+ for (StringRef BuiltinName : NBA->builtinNames()) {
+ SmallString<32> AttributeName;
+ AttributeName += "no-builtin-";
+ AttributeName += BuiltinName;
+ FuncAttrs.addAttribute(AttributeName);
+ }
+ }
+ }
}
// 'const', 'pure' and 'noalias' attributed functions are also nounwind.
OpenPOWER on IntegriCloud