summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp8
-rw-r--r--clang/test/CodeGenCXX/main-norecurse.cpp8
-rw-r--r--clang/test/CodeGenObjC/objc-literal-tests.m2
3 files changed, 17 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 1d3ad9bc4ad..b5812c8d314 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/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<FunctionDecl>(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/clang/test/CodeGenCXX/main-norecurse.cpp b/clang/test/CodeGenCXX/main-norecurse.cpp
new file mode 100644
index 00000000000..17d5ba89514
--- /dev/null
+++ b/clang/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/clang/test/CodeGenObjC/objc-literal-tests.m b/clang/test/CodeGenObjC/objc-literal-tests.m
index c53ee644f05..03286e24563 100644
--- a/clang/test/CodeGenObjC/objc-literal-tests.m
+++ b/clang/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{{.*}} }
OpenPOWER on IntegriCloud