Patchwork [C++] PR 24449

login
register
mail settings
Submitter Paolo Carlini
Date Oct. 12, 2012, 11:33 a.m.
Message ID <5077FFFE.3030709@oracle.com>
Download mbox | patch
Permalink /patch/191097/
State New
Headers show

Comments

Paolo Carlini - Oct. 12, 2012, 11:33 a.m.
Hi,

a pretty old and minor issue, but it seems easy to fix.

When we check for wrong declarations of ::main in grokfndecl we use 
processing_template_decl to reject ::main as template and we end up 
wrongly rejecting:

template <class T> class Foob
{
   friend int main();
};

(whereas we normally accept:

class Fooa
{
   friend int main();
};
)

using the more accurate PROCESSING_REAL_TEMPLATE_DECL_P() correctly does 
the trick, AFAICS.

Tested x86_64-linux.

Thanks,
Paolo.

//////////////////////////
/cp
2012-10-12  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/24449
	* decl.c (grokfndecl): When checking for ::main declarations
	use PROCESSING_REAL_TEMPLATE_DECL_P().

/testsuite
2012-10-12  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/24449
	* g++.dg/parse/friend-main.C: New.
Jason Merrill - Oct. 12, 2012, 1:46 p.m.
OK.

Jason

Patch

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 192392)
+++ cp/decl.c	(working copy)
@@ -7416,7 +7416,7 @@  grokfndecl (tree ctype,
 
   if (ctype == NULL_TREE && DECL_MAIN_P (decl))
     {
-      if (processing_template_decl)
+      if (PROCESSING_REAL_TEMPLATE_DECL_P())
 	error ("cannot declare %<::main%> to be a template");
       if (inlinep)
 	error ("cannot declare %<::main%> to be inline");
Index: testsuite/g++.dg/parse/friend-main.C
===================================================================
--- testsuite/g++.dg/parse/friend-main.C	(revision 0)
+++ testsuite/g++.dg/parse/friend-main.C	(working copy)
@@ -0,0 +1,30 @@ 
+// PR c++/24449
+
+class Fooa
+{
+  friend int main();
+};
+
+template <class T> class Foob
+{
+  friend int main();
+  int i;
+};
+
+int main()
+{
+  Foob<void> a;
+  a.i = 7;
+}
+
+class Fooc
+{
+  template<class T> friend int main(); // { dg-error "cannot declare .::main. to be a template" }
+};
+
+template<class T> class Food
+{
+  template<class U> friend int main(); // { dg-error "cannot declare .::main. to be a template" }
+};
+
+template<class U> int main() {} // { dg-error "cannot declare .::main. to be a template" }