]> granicus.if.org Git - clang/commitdiff
Disable all recognition of main() in -ffreestanding. Addresses bug #4720.
authorJohn McCall <rjmccall@apple.com>
Sat, 15 Aug 2009 02:09:25 +0000 (02:09 +0000)
committerJohn McCall <rjmccall@apple.com>
Sat, 15 Aug 2009 02:09:25 +0000 (02:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79070 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
lib/AST/Decl.cpp
lib/CodeGen/Mangle.cpp
lib/Sema/SemaDecl.cpp
test/Sema/freemain.c [new file with mode: 0644]

index 697c561cb791fecadf527b488292bb9ddb4bed0f..d603e677b2193b2728a4ca76e08af1a576f9b27f 100644 (file)
@@ -850,7 +850,7 @@ public:
 
   /// \brief Determines whether this is a function "main", which is
   /// the entry point into an executable program.
-  bool isMain() const;
+  bool isMain(ASTContext &Context) const;
 
   /// \brief Determines whether this function is a function with
   /// external, C linkage.
index 6d2f2301ba40d10696ab1d7b38ce6fd70f747947..c91cb1dba2e1b89375ac75e3e413ab72e18c2576 100644 (file)
@@ -414,8 +414,9 @@ void FunctionDecl::setBody(Stmt *B) {
     EndRangeLoc = B->getLocEnd();
 }
 
-bool FunctionDecl::isMain() const {
-  return getDeclContext()->getLookupContext()->isTranslationUnit() &&
+bool FunctionDecl::isMain(ASTContext &Context) const {
+  return !Context.getLangOptions().Freestanding &&
+    getDeclContext()->getLookupContext()->isTranslationUnit() &&
     getIdentifier() && getIdentifier()->isStr("main");
 }
 
index 341e230e904518a504ed790431d104a6fbe60598..71b84e70013c7defad35913b437de375cb6162dc 100644 (file)
@@ -91,7 +91,7 @@ bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) {
   // name mangling (always).
   if (!FD->hasAttr<OverloadableAttr>()) {
     // C functions are not mangled, and "main" is never mangled.
-    if (!Context.getLangOptions().CPlusPlus || FD->isMain())
+    if (!Context.getLangOptions().CPlusPlus || FD->isMain(Context))
       return false;
     
     // No mangling in an "implicit extern C" header. 
index ab5578b378d7919f4948046115a8096ed68a45b0..d75f322aa55276a8644eb2b42de20f2b7df32562 100644 (file)
@@ -2766,7 +2766,7 @@ void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
     return NewFD->setInvalidDecl();
   }
 
-  if (NewFD->isMain()) CheckMain(NewFD);
+  if (NewFD->isMain(Context)) CheckMain(NewFD);
 
   // Semantic checking for this function declaration (in isolation).
   if (getLangOptions().CPlusPlus) {
@@ -3542,7 +3542,7 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
   //   definition itself provides a prototype. The aim is to detect
   //   global functions that fail to be declared in header files.
   if (!FD->isInvalidDecl() && FD->isGlobal() && !isa<CXXMethodDecl>(FD) &&
-      !FD->isMain()) {
+      !FD->isMain(Context)) {
     bool MissingPrototype = true;
     for (const FunctionDecl *Prev = FD->getPreviousDeclaration();
          Prev; Prev = Prev->getPreviousDeclaration()) {
@@ -3608,7 +3608,7 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
   Stmt *Body = BodyArg.takeAs<Stmt>();
   if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(dcl)) {
     FD->setBody(Body);
-    if (FD->isMain())
+    if (FD->isMain(Context))
       // C and C++ allow for main to automagically return 0.
       // Implements C++ [basic.start.main]p5 and C99 5.1.2.2.3.
       FD->setHasImplicitReturnZero(true);
diff --git a/test/Sema/freemain.c b/test/Sema/freemain.c
new file mode 100644 (file)
index 0000000..a2364df
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: clang-cc -fsyntax-only -verify -ffreestanding %s
+
+// Tests that -ffreestanding disables all special treatment of main().
+
+void* allocate(long size);
+
+void* main(void* context, long size) {
+  if (context) return allocate(size);
+} // expected-warning {{control may reach end of non-void function}}