This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR c++/13101
- From: Dodji Seketeli <dseketel at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 03 Jul 2008 00:09:33 +0200
- Subject: [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â??" }
+