This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR c++/13101


Hello,

Without this patch, gcc issues a warning when compiling the following declaration:

extern void(*const ptr)() = 0;

The warning is:

warning: ‘ptr’ initialized and declared ‘extern’

Even though that construction is valid.

For instance, the following construction compiles fine:

extern const int ptr = 0;

What is happening is that when the variable declaration is a function pointer declaration, g++ forgets to look at the "cv qualifiers" of the declaration-id, whereas it does it properly for declarations that are not function pointers.

The attached patch fixes that PR 13101 in trunk.


Cheers,


Dodji.
gcc/cp/ChangeLog:
2008-07-02 Dodji Seketeli <dseketel@redhat.com>

	PR c++/13101
	* decl.c (grokdeclarator): For pointer to function declarations,
	  take cv quals of the declarator-id in account before warning
	  about initializing variables of storage class 'extern'.

gcc/testsuite/ChangeLog:
2008-07-02 Dodji Seketeli <dseketel@redhat.com>

	PR c++/13101
	* g++.dg/parse/func-ptr-decl.C: New test.


diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index c6ae93e..00ac364 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7418,6 +7418,10 @@ grokdeclarator (const cp_declarator *declarator,
   bool type_was_error_mark_node = false;
   bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
   bool set_no_warning = false;
+  bool is_function_pointer = false;
+  /* cv-qualifiers that apply to the type, when it's a pointer to function,
+     like in: void (*const ptr) ().  */
+  cp_cv_quals ptr_to_function_quals = TYPE_UNQUALIFIED;
 
   signed_p = declspecs->specs[(int)ds_signed];
   unsigned_p = declspecs->specs[(int)ds_unsigned];
@@ -7452,6 +7456,16 @@ grokdeclarator (const cp_declarator *declarator,
 	      if (sfk == sfk_destructor)
 		flags = DTOR_FLAG;
 	    }
+	  else if (id_declarator->declarator
+		   && id_declarator->declarator->kind == cdk_pointer)
+	    {
+	      /* This is a function pointer declaration.
+		 We need to record the cv quals of the declarator id.
+		 Those will be used later in this function.  */
+		 is_function_pointer = true;
+		 ptr_to_function_quals =
+		    id_declarator->declarator->u.pointer.qualifiers;
+	    }
 	  break;
 
 	case cdk_id:
@@ -7985,7 +7999,9 @@ grokdeclarator (const cp_declarator *declarator,
 	{
 	  /* It's common practice (and completely valid) to have a const
 	     be initialized and declared extern.  */
-	  if (!(type_quals & TYPE_QUAL_CONST))
+	  if (!(type_quals & TYPE_QUAL_CONST)
+	      && !(is_function_pointer
+		   && ptr_to_function_quals & TYPE_QUAL_CONST))
 	    warning (0, "%qs initialized and declared %<extern%>", name);
 	}
       else
diff --git a/gcc/testsuite/g++.dg/parse/func-ptr-decl.C b/gcc/testsuite/g++.dg/parse/func-ptr-decl.C
new file mode 100644
index 0000000..4600b34
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/func-ptr-decl.C
@@ -0,0 +1,7 @@
+// Contributed by Dodji Seketeli <dseketel@redhat.com>
+// Origin: PR C++/13101
+// { dg-do compile }
+
+extern void(*ptr0)() = 0; // { dg-error "warning: 'ptr0' initialized and declared 'extern'" }
+extern void(*const ptr1)() = 0; // { dg-bogus "warning: 'ptr1' initialized and declared â??externâ??" }
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]