<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 21, 2014 at 5:43 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Tue Jan 21 19:43:19 2014<br>
New Revision: 199782<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=199782&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=199782&view=rev</a><br>
Log:<br>
Enforce restrictions that 'main' is not allowed to be deleted, or to be used by<br>
the program, in C++. (We allow the latter as an extension, since we've always<br>
permitted it, and GCC does the same, and our supported C++ ABIs don't do<br>
anything special in main.)<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=199782&r1=199781&r2=199782&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=199782&r1=199781&r2=199782&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jan 21 19:43:19 2014<br>
@@ -425,6 +425,7 @@ def ext_noreturn_main : ExtWarn<<br>
 def note_main_remove_noreturn : Note<"remove '_Noreturn'">;<br>
 def err_constexpr_main : Error<<br>
   "'main' is not allowed to be declared constexpr">;<br>
+def err_deleted_main : Error<"'main' is not allowed to be deleted">;<br>
 def err_mainlike_template_decl : Error<"%0 cannot be a template">;<br>
 def err_main_returns_nonint : Error<"'main' must return 'int'">;<br>
 def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">,<br>
@@ -437,6 +438,8 @@ def warn_main_one_arg : Warning<"only on<br>
 def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 "<br>
     "parameter of 'main' (%select{argument count|argument array|environment|"<br>
     "platform-specific data}0) must be of type %1">;<br>
+def ext_main_used : Extension<<br>
+  "ISO C++ does not allow 'main' to be used by a program">, InGroup<Main>;<br>
<br>
 /// parser diagnostics<br>
 def ext_no_declarators : ExtWarn<"declaration does not declare anything">,<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=199782&r1=199781&r2=199782&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=199782&r1=199781&r2=199782&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jan 21 19:43:19 2014<br>
@@ -6809,6 +6809,8 @@ Sema::ActOnFunctionDeclarator(Scope *S,<br>
     }<br>
<br>
     // If a function is defined as defaulted or deleted, mark it as such now.<br>
+    // FIXME: Does this ever happen? ActOnStartOfFunctionDef forces the function<br>
+    // definition kind to FDK_Definition.<br></blockquote><div><br></div><div>One way to find out is to replace this with an assert that it doesn't happen and wait for a buildbot (or, if one was more socially responsible than me, run various test loads out-of-tree on the change) to fail...</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
     switch (D.getFunctionDefinitionKind()) {<br>
       case FDK_Declaration:<br>
       case FDK_Definition:<br>
@@ -7670,8 +7672,9 @@ static SourceRange getResultSourceRange(<br>
 }<br>
<br>
 void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {<br>
-  // C++11 [basic.start.main]p3:  A program that declares main to be inline,<br>
-  //   static or constexpr is ill-formed.<br>
+  // C++11 [basic.start.main]p3:<br>
+  //   A program that [...] declares main to be inline, static or<br>
+  //   constexpr is ill-formed.<br>
   // C11 6.7.4p4:  In a hosted environment, no function specifier(s) shall<br>
   //   appear in a declaration of main.<br>
   // static main is not an error under C99, but we should warn about it.<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=199782&r1=199781&r2=199782&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=199782&r1=199781&r2=199782&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Jan 21 19:43:19 2014<br>
@@ -11984,6 +11984,11 @@ void Sema::SetDeclDeleted(Decl *Dcl, Sou<br>
     }<br>
   }<br>
<br>
+  // C++11 [basic.start.main]p3:<br>
+  //   A program that defines main as deleted [...] is ill-formed.<br>
+  if (Fn->isMain())<br>
+    Diag(DelLoc, diag::err_deleted_main);<br>
+<br>
   Fn->setDeletedAsWritten();<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=199782&r1=199781&r2=199782&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=199782&r1=199781&r2=199782&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jan 21 19:43:19 2014<br>
@@ -264,13 +264,18 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *<br>
       SmallVectorImpl<PartialDiagnosticAt> &Suppressed = Pos->second;<br>
       for (unsigned I = 0, N = Suppressed.size(); I != N; ++I)<br>
         Diag(Suppressed[I].first, Suppressed[I].second);<br>
-<br>
+<br>
       // Clear out the list of suppressed diagnostics, so that we don't emit<br>
       // them again for this specialization. However, we don't obsolete this<br>
       // entry from the table, because we want to avoid ever emitting these<br>
       // diagnostics again.<br>
       Suppressed.clear();<br>
     }<br>
+<br>
+    // C++ [basic.start.main]p3:<br>
+    //   The function 'main' shall not be used within a program.<br>
+    if (cast<FunctionDecl>(D)->isMain())<br>
+      Diag(Loc, diag::ext_main_used);<br>
   }<br>
<br>
   // See if this is an auto-typed variable whose initializer we are parsing.<br>
<br>
<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>
</blockquote></div><br></div></div>