<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Jul 2, 2014 at 3:32 PM, Matt Calabrese <span dir="ltr"><<a href="mailto:rivorus@gmail.com" target="_blank">rivorus@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I'm probably mis-remembering, but I could have sworn that for built-in types, cv-qualification was always ignored in the return type such that "int foo()" and "int const foo()" were the same, with cv-qualification only mattering for class types.</div>
</blockquote><div><br></div><div>That's not quite what happens. A prvalue expression of non-class, non-array type has its cv-qualifiers discarded before anything else happens.</div><div><br></div><div>Given</div><div>
<br></div><div>  const int f();</div><div><br></div><div>the expression 'f();' has type 'int' (because the 'const' is discarded), but</div><div><br></div><div>  int f();</div><div><br></div><div>is ill-formed.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_extra"><div><div class="h5"><div class="gmail_quote">On Wed, Jul 2, 2014 at 12:07 AM, Alp Toker <span dir="ltr"><<a href="mailto:alp@nuanti.com" target="_blank">alp@nuanti.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: alp<br>
Date: Wed Jul  2 02:07:20 2014<br>
New Revision: 212171<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=212171&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=212171&view=rev</a><br>
Log:<br>
Don't accept qualified 'int' main return types in C++ or standard C mode<br>
<br>
C++ [basic.start.main]p1: "It shall have a return type of type int"<br>
<br>
ISO C is also clear about this, so only accept 'int' with qualifiers in GNUMode<br>
C.<br>
<br>
Modified:<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
    cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp<br>
    cfe/trunk/test/Sema/c89.c<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=212171&r1=212170&r2=212171&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=212171&r1=212170&r2=212171&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jul  2 02:07:20 2014<br>
@@ -7878,32 +7878,37 @@ void Sema::CheckMain(FunctionDecl* FD, c<br>
   assert(T->isFunctionType() && "function decl is not of function type");<br>
   const FunctionType* FT = T->castAs<FunctionType>();<br>
<br>
-  // All the standards say that main() should should return 'int'.<br>
-  if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy)) {<br>
+  if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {<br>
+    // In C with GNU extensions we allow main() to have non-integer return<br>
+    // type, but we should warn about the extension, and we disable the<br>
+    // implicit-return-zero rule.<br>
+<br>
+    // GCC in C mode accepts qualified 'int'.<br>
+    if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy))<br>
+      FD->setHasImplicitReturnZero(true);<br></blockquote></div></div></div></div></blockquote><div><br></div><div>Should we also produce an ExtWarn here if the type is not 'int'?</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_extra"><div><div class="h5"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    else {<br>
+      Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);<br>
+      SourceRange RTRange = FD->getReturnTypeSourceRange();<br>
+      if (RTRange.isValid())<br>
+        Diag(RTRange.getBegin(), diag::note_main_change_return_type)<br>
+            << FixItHint::CreateReplacement(RTRange, "int");<br>
+    }<br>
+  } else {<br>
     // In C and C++, main magically returns 0 if you fall off the end;<br>
     // set the flag which tells us that.<br>
     // This is C++ [basic.start.main]p5 and C99 5.1.2.2.3.<br>
-    FD->setHasImplicitReturnZero(true);<br>
-<br>
-  // In C with GNU extensions we allow main() to have non-integer return<br>
-  // type, but we should warn about the extension, and we disable the<br>
-  // implicit-return-zero rule.<br>
-  } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {<br>
-    Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);<br>
-<br>
-    SourceRange RTRange = FD->getReturnTypeSourceRange();<br>
-    if (RTRange.isValid())<br>
-      Diag(RTRange.getBegin(), diag::note_main_change_return_type)<br>
-          << FixItHint::CreateReplacement(RTRange, "int");<br>
-<br>
-  // Otherwise, this is just a flat-out error.<br>
-  } else {<br>
-    SourceRange RTRange = FD->getReturnTypeSourceRange();<br>
-    Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint)<br>
-        << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int")<br>
-                              : FixItHint());<br>
<br>
-    FD->setInvalidDecl(true);<br>
+    // All the standards say that main() should return 'int'.<br>
+    if (Context.hasSameType(FT->getReturnType(), Context.IntTy))<br>
+      FD->setHasImplicitReturnZero(true);<br>
+    else {<br>
+      // Otherwise, this is just a flat-out error.<br>
+      SourceRange RTRange = FD->getReturnTypeSourceRange();<br>
+      Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint)<br>
+          << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int")<br>
+                                : FixItHint());<br>
+      FD->setInvalidDecl(true);<br></blockquote></div></div></div></div></blockquote><div><br></div><div>Can we fold the two halves of this 'if' together? They look very similar...</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_extra"><div><div class="h5"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    }<br>
   }<br>
<br>
   // Treat protoless main() as nullary.<br>
<br>
Modified: cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp?rev=212171&r1=212170&r2=212171&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp?rev=212171&r1=212170&r2=212171&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp (original)<br>
+++ cfe/trunk/test/CXX/basic/basic.start/basic.start.main/p2.cpp Wed Jul  2 02:07:20 2014<br>
@@ -62,6 +62,8 @@ main( // expected-error {{first paramete<br>
 ) {<br>
 }<br>
<br>
+const int main(); // expected-error {{'main' must return 'int'}}<br>
+<br>
 #elif TEST7<br>
<br>
 // expected-no-diagnostics<br>
<br>
Modified: cfe/trunk/test/Sema/c89.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/c89.c?rev=212171&r1=212170&r2=212171&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/c89.c?rev=212171&r1=212170&r2=212171&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/Sema/c89.c (original)<br>
+++ cfe/trunk/test/Sema/c89.c Wed Jul  2 02:07:20 2014<br>
@@ -111,6 +111,8 @@ const array_of_pointer_to_CI mine3;<br>
<br>
 void main() {} /* expected-error {{'main' must return 'int'}} */<br>
<br>
+const int main() {} /* expected-error {{'main' must return 'int'}} */<br>
+<br>
 long long ll1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */<br>
          -42LL; /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */<br>
 unsigned long long ull1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div></div></div><span class="HOEnZb"><font color="#888888">-- <br>-Matt Calabrese
</font></span></div>
<br>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div></div>