]> granicus.if.org Git - clang/commitdiff
Don't accept qualified 'int' main return types in C++ or standard C mode
authorAlp Toker <alp@nuanti.com>
Wed, 2 Jul 2014 07:07:20 +0000 (07:07 +0000)
committerAlp Toker <alp@nuanti.com>
Wed, 2 Jul 2014 07:07:20 +0000 (07:07 +0000)
C++ [basic.start.main]p1: "It shall have a return type of type int"

ISO C is also clear about this, so only accept 'int' with qualifiers in GNUMode
C.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@212171 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/CXX/basic/basic.start/basic.start.main/p2.cpp
test/Sema/c89.c

index 849926327d0814e937feea7307e87e0e20a139d5..791b4daf01ea9bd4699713df0bb266ba26e96d8c 100644 (file)
@@ -7878,32 +7878,37 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
   assert(T->isFunctionType() && "function decl is not of function type");
   const FunctionType* FT = T->castAs<FunctionType>();
 
-  // All the standards say that main() should should return 'int'.
-  if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy)) {
+  if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
+    // In C with GNU extensions we allow main() to have non-integer return
+    // type, but we should warn about the extension, and we disable the
+    // implicit-return-zero rule.
+
+    // GCC in C mode accepts qualified 'int'.
+    if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy))
+      FD->setHasImplicitReturnZero(true);
+    else {
+      Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
+      SourceRange RTRange = FD->getReturnTypeSourceRange();
+      if (RTRange.isValid())
+        Diag(RTRange.getBegin(), diag::note_main_change_return_type)
+            << FixItHint::CreateReplacement(RTRange, "int");
+    }
+  } else {
     // In C and C++, main magically returns 0 if you fall off the end;
     // set the flag which tells us that.
     // This is C++ [basic.start.main]p5 and C99 5.1.2.2.3.
-    FD->setHasImplicitReturnZero(true);
-
-  // In C with GNU extensions we allow main() to have non-integer return
-  // type, but we should warn about the extension, and we disable the
-  // implicit-return-zero rule.
-  } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
-    Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
 
-    SourceRange RTRange = FD->getReturnTypeSourceRange();
-    if (RTRange.isValid())
-      Diag(RTRange.getBegin(), diag::note_main_change_return_type)
-          << FixItHint::CreateReplacement(RTRange, "int");
-
-  // Otherwise, this is just a flat-out error.
-  } else {
-    SourceRange RTRange = FD->getReturnTypeSourceRange();
-    Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint)
-        << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int")
-                              : FixItHint());
-
-    FD->setInvalidDecl(true);
+    // All the standards say that main() should return 'int'.
+    if (Context.hasSameType(FT->getReturnType(), Context.IntTy))
+      FD->setHasImplicitReturnZero(true);
+    else {
+      // Otherwise, this is just a flat-out error.
+      SourceRange RTRange = FD->getReturnTypeSourceRange();
+      Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint)
+          << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int")
+                                : FixItHint());
+      FD->setInvalidDecl(true);
+    }
   }
 
   // Treat protoless main() as nullary.
index 5c7d60c1df4c3396c642550f5703b44e9790dc25..42e87e5431f2a5ba056416ca994d510f4224dc86 100644 (file)
@@ -62,6 +62,8 @@ main( // expected-error {{first parameter of 'main' (argument count) must be of
 ) {
 }
 
+const int main(); // expected-error {{'main' must return 'int'}}
+
 #elif TEST7
 
 // expected-no-diagnostics
index b746d383f3069f339fc8e7dd9e8e2e4bea82774d..c9e81f1c41ca9877cb6a120df9dea65c044de905 100644 (file)
@@ -111,6 +111,8 @@ const array_of_pointer_to_CI mine3;
 
 void main() {} /* expected-error {{'main' must return 'int'}} */
 
+const int main() {} /* expected-error {{'main' must return 'int'}} */
+
 long long ll1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
          -42LL; /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
 unsigned long long ull1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */