On 12.02.2012 07:39, Chandler Carruth wrote:
On Sat, Feb 11, 2012 at 5:31 AM, Vasiliy Korchagin <[email protected] <mailto:[email protected]>> wrote:

    I agree, without setting implicit return zero bit changes in
    codegen are not necessary. New version of patch is attached.


The warning you're adding, as David suggested, should be under a separate flag.

It should also be an extwarn as this is technically a language extension, and it should be enabled by default (you may already have that, just want it clarified).

--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -5795,8 +5795,13 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
   const FunctionType* FT = T->getAs<FunctionType>();
if (!Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) {
-    Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
-    FD->setInvalidDecl(true);
+    if (getLangOptions().C99) {
+      // In C we allow main() to have non-integer return type.
+      Diag(FD->getTypeSpecStartLoc(), diag::warn_main_returns_nonint);

If you want this to be enabled in all C modes, you should accept more than just C99: "!getLangOptions().CPlusPlus" is a good candidate here.

@@ -7204,7 +7209,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
     if (FD->isMain()) {
       // 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);
+      if (!getLangOptions().C99)
+        FD->setHasImplicitReturnZero(true);

This isn't correct. You need to be checking for a non-int return type here, not for C99. If the function has an int return type we want the implicit return zero.
Now new warning is under the separate flag ("-Wmain-return-type") and it is an extwarn and it is enabled by default. Also problems with C modes and implicit return zero are fixed. New patch is attached.

Vasiliy Korchagin,
The Institute for System Programming of the Russian Academy of Sciences
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 4fa1982..3f73a67 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -104,6 +104,7 @@ def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args",
                                       [CXX98CompatLocalTypeTemplateArgs]>;
 def MalformedWarningCheck : DiagGroup<"malformed-warning-check">;
 def Main : DiagGroup<"main">;
+def MainReturnType : DiagGroup<"main-return-type">;
 def MissingBraces : DiagGroup<"missing-braces">;
 def MissingDeclarations: DiagGroup<"missing-declarations">;
 def : DiagGroup<"missing-format-attribute">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index c35968c..5e5f100 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -348,6 +348,8 @@ def err_constexpr_main : Error<
   "'main' is not allowed to be declared constexpr">;
 def err_main_template_decl : Error<"'main' cannot be a template">;
 def err_main_returns_nonint : Error<"'main' must return 'int'">;
+def warn_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">,
+    InGroup<MainReturnType>;
 def err_main_surplus_args : Error<"too many parameters (%0) for 'main': "
     "must be 0, 2, or 3">;
 def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index feffaf1..48f6e1c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -5794,8 +5794,14 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
   const FunctionType* FT = T->getAs<FunctionType>();
 
   if (!Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) {
-    Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
-    FD->setInvalidDecl(true);
+    if (getLangOptions().CPlusPlus) {
+      Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
+      FD->setInvalidDecl(true);
+    } else {
+      // In C we allow main() to have non-integer return type, but we should
+      // warn about it.
+      Diag(FD->getTypeSpecStartLoc(), diag::warn_main_returns_nonint);
+    }
   }
 
   // Treat protoless main() as nullary.
@@ -7256,7 +7262,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
     if (FD->isMain()) {
       // 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);
+      if (FD->getResultType()->isIntegerType())
+        FD->setHasImplicitReturnZero(true);
       WP.disableCheckFallThrough();
     } else if (FD->hasAttr<NakedAttr>()) {
       // If the function is marked 'naked', don't complain about missing return
diff --git a/test/Sema/warn-main-returns-nonint.c b/test/Sema/warn-main-returns-nonint.c
new file mode 100644
index 0000000..e1dc114
--- /dev/null
+++ b/test/Sema/warn-main-returns-nonint.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void main() {} // expected-warning {{return type of 'main' is not 'int'}}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to