Hi,
On 06/12/2014 11:20 PM, Jason Merrill wrote:
On 06/12/2014 03:14 PM, Paolo Carlini wrote:
... in terms of code proper, the below is much better, IMHO. Assuming,
as I understand, we have no reason to call the rather heavy same_type_p
when we already know that VOID_TYPE_P (type) is true...
same_type_p is not so heavy since it just compares TYPE_CANONICAL, but
I wonder why we don't use == for the normal case, and then
typedef_variant_p to diagnose a typedef.
Ah great, I was missing a number of details here (yesterday realized
myself the big one, TYPE_CANONICAL, but something still seemed weird
with a full same_type_p after VOID_TYPE_P...). There is a minor
difference from the user point of view that we talk about typedef-name
also in case of more than one parameter - not even C allows that ;) -
but I think it's fine, considering the code simplification.
Thanks!
Paolo.
//////////////////////////
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 211609)
+++ cp/decl.c (working copy)
@@ -11137,12 +11137,23 @@ grokparms (tree parmlist, tree *parms)
type = TREE_TYPE (decl);
if (VOID_TYPE_P (type))
{
- if (same_type_p (type, void_type_node)
- && DECL_SELF_REFERENCE_P (type)
- && !DECL_NAME (decl) && !result && TREE_CHAIN (parm) ==
void_list_node)
+ if (type == void_type_node
+ && !DECL_NAME (decl) && !result
+ && TREE_CHAIN (parm) == void_list_node)
/* this is a parmlist of `(void)', which is ok. */
break;
- cxx_incomplete_type_error (decl, type);
+ else if (typedef_variant_p (type))
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "invalid use of typedef-name for type "
+ "%<void%> in parameter declaration");
+ else if (cv_qualified_p (type))
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "invalid use of cv-qualified type %<void%> "
+ "in parameter declaration");
+ else
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "invalid use of type %<void%> in parameter "
+ "declaration");
/* It's not a good idea to actually create parameters of
type `void'; other parts of the compiler assume that a
void type terminates the parameter list. */
Index: testsuite/g++.dg/conversion/err-recover1.C
===================================================================
--- testsuite/g++.dg/conversion/err-recover1.C (revision 211609)
+++ testsuite/g++.dg/conversion/err-recover1.C (working copy)
@@ -1,6 +1,6 @@
// PR c++/42219
-void foo(const void); // { dg-error "incomplete|const" }
+void foo(const void); // { dg-error "invalid use of cv-qualified" }
void bar()
{
Index: testsuite/g++.dg/other/void3.C
===================================================================
--- testsuite/g++.dg/other/void3.C (revision 0)
+++ testsuite/g++.dg/other/void3.C (working copy)
@@ -0,0 +1,4 @@
+// PR c++/33101
+
+typedef void v;
+typedef v (*pf)(v); // { dg-error "invalid use of typedef-name" }