diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 10 |
3 files changed, 17 insertions, 8 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index f9ad9461095..ed2a0c36fd2 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1812,6 +1812,7 @@ bool FunctionDecl::isGlobal() const { bool FunctionDecl::isNoReturn() const { return hasAttr<NoReturnAttr>() || hasAttr<CXX11NoReturnAttr>() || + hasAttr<C11NoReturnAttr>() || getType()->getAs<FunctionType>()->getNoReturnAttr(); } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index c29230f75bf..e7b543a78cf 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -983,19 +983,17 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice); if (TargetDecl->hasAttr<NoThrowAttr>()) FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); - else if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) { + if (TargetDecl->hasAttr<NoReturnAttr>()) + FuncAttrs.addAttribute(llvm::Attribute::NoReturn); + + if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) { const FunctionProtoType *FPT = Fn->getType()->getAs<FunctionProtoType>(); if (FPT && FPT->isNothrow(getContext())) FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); + if (Fn->isNoReturn()) + FuncAttrs.addAttribute(llvm::Attribute::NoReturn); } - if (TargetDecl->hasAttr<NoReturnAttr>() || - TargetDecl->hasAttr<CXX11NoReturnAttr>()) - FuncAttrs.addAttribute(llvm::Attribute::NoReturn); - - if (TargetDecl->hasAttr<ReturnsTwiceAttr>()) - FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice); - // 'const' and 'pure' attribute functions are also nounwind. if (TargetDecl->hasAttr<ConstAttr>()) { FuncAttrs.addAttribute(llvm::Attribute::ReadNone); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 2c09c88b201..c94bf5f092f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1900,6 +1900,11 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { ++I; continue; // regular attr merging will take care of validating this. } + // C's _Noreturn is allowed to be added to a function after it is defined. + if (isa<C11NoReturnAttr>(NewAttribute)) { + ++I; + continue; + } S.Diag(NewAttribute->getLocation(), diag::warn_attribute_precede_definition); S.Diag(Def->getLocation(), diag::note_previous_definition); @@ -5889,6 +5894,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewFD->setDeclsInPrototypeScope(DeclsInPrototypeScope); DeclsInPrototypeScope.clear(); + if (D.getDeclSpec().isNoreturnSpecified()) + NewFD->addAttr( + ::new(Context) C11NoReturnAttr(D.getDeclSpec().getNoreturnSpecLoc(), + Context)); + // Process the non-inheritable attributes on this declaration. ProcessDeclAttributes(S, NewFD, D, /*NonInheritable=*/true, /*Inheritable=*/false); |