From 2b0f6ba4417d17b4b1f6713796bb65e43cc255f6 Mon Sep 17 00:00:00 2001 From: James Molloy Date: Thu, 12 Nov 2015 15:36:04 +0000 Subject: [PATCH] [C++] Add the "norecurse" attribute to main() if in C++ mode The C++ spec (3.6.1.3) says "The function `main` shall not be used within a program". This implies that it cannot recurse, so add the norecurse attribute to help the midend out a bit. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@252902 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenFunction.cpp | 8 ++++++++ test/CodeGenCXX/main-norecurse.cpp | 8 ++++++++ test/CodeGenObjC/objc-literal-tests.m | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 test/CodeGenCXX/main-norecurse.cpp diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 1d3ad9bc4a..b5812c8d31 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -716,6 +716,14 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, } } + // If we're in C++ mode and the function name is "main", it is guaranteed + // to be norecurse by the standard (3.6.1.3 "The function main shall not be + // used within a program"). + if (getLangOpts().CPlusPlus) + if (const FunctionDecl *FD = dyn_cast_or_null(D)) + if (FD->isMain()) + Fn->addFnAttr(llvm::Attribute::NoRecurse); + llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn); // Create a marker to make it easy to insert allocas into the entryblock diff --git a/test/CodeGenCXX/main-norecurse.cpp b/test/CodeGenCXX/main-norecurse.cpp new file mode 100644 index 0000000000..17d5ba8951 --- /dev/null +++ b/test/CodeGenCXX/main-norecurse.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +// CHECK: define i{{.*}} @main({{.*}}) #0 +int main(int argc, char **argv) { + return 1; +} + +// CHECK: attributes #0 = { norecurse{{.*}} } diff --git a/test/CodeGenObjC/objc-literal-tests.m b/test/CodeGenObjC/objc-literal-tests.m index c53ee644f0..03286e2456 100644 --- a/test/CodeGenObjC/objc-literal-tests.m +++ b/test/CodeGenObjC/objc-literal-tests.m @@ -94,4 +94,4 @@ void baz(void) { bar(^(void) { return YES; }); } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { {{(norecurse )?}}nounwind{{.*}} } -- 2.40.0