]> granicus.if.org Git - clang/commitdiff
[C++] Add the "norecurse" attribute to main() if in C++ mode
authorJames Molloy <james.molloy@arm.com>
Thu, 12 Nov 2015 15:36:04 +0000 (15:36 +0000)
committerJames Molloy <james.molloy@arm.com>
Thu, 12 Nov 2015 15:36:04 +0000 (15:36 +0000)
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
test/CodeGenCXX/main-norecurse.cpp [new file with mode: 0644]
test/CodeGenObjC/objc-literal-tests.m

index 1d3ad9bc4adc1f05a76cc68874dbc4533033cb6a..b5812c8d314279f24092eb79ebf7a452657ad8c1 100644 (file)
@@ -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/test/CodeGenCXX/main-norecurse.cpp b/test/CodeGenCXX/main-norecurse.cpp
new file mode 100644 (file)
index 0000000..17d5ba8
--- /dev/null
@@ -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{{.*}} }
index c53ee644f05937e7f93b2025245e709c377e14fc..03286e24563e1aacbb098512f2ad241476d9eb47 100644 (file)
@@ -94,4 +94,4 @@ void baz(void) {
   bar(^(void) { return YES; });
 }
 
-// CHECK: attributes [[NUW]] = { nounwind{{.*}} }
+// CHECK: attributes [[NUW]] = { {{(norecurse )?}}nounwind{{.*}} }