* c-exp.y (check_parameter_typelist): New function.
authorTom Tromey <tromey@redhat.com>
Mon, 9 Jul 2012 14:20:52 +0000 (14:20 +0000)
committerTom Tromey <tromey@redhat.com>
Mon, 9 Jul 2012 14:20:52 +0000 (14:20 +0000)
(parameter_typelist): Call it.
* eval.c (make_params): Handle '(void)' case.
* gdbtypes.c (lookup_function_type_with_arguments): Handle
'(void)' case.
testsuite
* gdb.base/whatis.exp: Add error checks for improper 'void' uses.
* gdb.base/callfuncs.exp: Add cast-based test.
* gdb.base/callfuncs.c (voidfunc): New function.

gdb/ChangeLog
gdb/c-exp.y
gdb/eval.c
gdb/gdbtypes.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/callfuncs.c
gdb/testsuite/gdb.base/callfuncs.exp
gdb/testsuite/gdb.base/whatis.exp

index cab30f77336e8450c7964a208c92abb94b10db9f..0d1c151e608ebeb3cf3d53f22eef159f9837ad3f 100644 (file)
@@ -1,3 +1,11 @@
+2012-07-09  Tom Tromey  <tromey@redhat.com>
+
+       * c-exp.y (check_parameter_typelist): New function.
+       (parameter_typelist): Call it.
+       * eval.c (make_params): Handle '(void)' case.
+       * gdbtypes.c (lookup_function_type_with_arguments): Handle
+       '(void)' case.
+
 2012-07-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * common/linux-ptrace.c: Include gdb_assert.h.
index 14fd53d232b797e7967db3a16de478b5ea5e6760..0613799c27e27006c2751e5713024193a245b0a6 100644 (file)
@@ -165,6 +165,7 @@ void yyerror (char *);
 /* YYSTYPE gets defined by %union */
 static int parse_number (char *, int, int, YYSTYPE *);
 static struct stoken operator_stoken (const char *);
+static void check_parameter_typelist (VEC (type_ptr) *);
 %}
 
 %type <voidval> exp exp1 type_exp start variable qualified_name lcurly
@@ -1227,9 +1228,11 @@ typename:        TYPENAME
 
 parameter_typelist:
                nonempty_typelist
+                       { check_parameter_typelist ($1); }
        |       nonempty_typelist ',' DOTDOTDOT
                        {
                          VEC_safe_push (type_ptr, $1, NULL);
+                         check_parameter_typelist ($1);
                          $$ = $1;
                        }
        ;
@@ -1444,6 +1447,37 @@ operator_stoken (const char *op)
   return st;
 };
 
+/* Validate a parameter typelist.  */
+
+static void
+check_parameter_typelist (VEC (type_ptr) *params)
+{
+  struct type *type;
+  int ix;
+
+  for (ix = 0; VEC_iterate (type_ptr, params, ix, type); ++ix)
+    {
+      if (type != NULL && TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
+       {
+         if (ix == 0)
+           {
+             if (VEC_length (type_ptr, params) == 1)
+               {
+                 /* Ok.  */
+                 break;
+               }
+             VEC_free (type_ptr, params);
+             error (_("parameter types following 'void'"));
+           }
+         else
+           {
+             VEC_free (type_ptr, params);
+             error (_("'void' invalid as parameter type"));
+           }
+       }
+    }
+}
+
 /* Take care of parsing a number (anything that starts with a digit).
    Set yylval and return the token type; update lexptr.
    LEN is the number of characters in it.  */
index 13f997f5b127c87650ab9acaa18b22a4340bfc5f..7d3a8b96e3628237b7e644008ed3470538f0a2ec 100644 (file)
@@ -769,11 +769,23 @@ make_params (int num_types, struct type **param_types)
   TYPE_CODE (type) = TYPE_CODE_METHOD;
   TYPE_VPTR_FIELDNO (type) = -1;
   TYPE_CHAIN (type) = type;
-  if (num_types > 0 && param_types[num_types - 1] == NULL)
+  if (num_types > 0)
     {
-      --num_types;
-      TYPE_VARARGS (type) = 1;
+      if (param_types[num_types - 1] == NULL)
+       {
+         --num_types;
+         TYPE_VARARGS (type) = 1;
+       }
+      else if (TYPE_CODE (check_typedef (param_types[num_types - 1]))
+              == TYPE_CODE_VOID)
+       {
+         --num_types;
+         /* Caller should have ensured this.  */
+         gdb_assert (num_types == 0);
+         TYPE_PROTOTYPED (type) = 1;
+       }
     }
+
   TYPE_NFIELDS (type) = num_types;
   TYPE_FIELDS (type) = (struct field *)
     TYPE_ZALLOC (type, sizeof (struct field) * num_types);
index cb25e71fc7c5c5d02727290ea4196b70573176b2..8142ab9cb3ae503cab639765de8bd330097e1b46 100644 (file)
@@ -474,10 +474,21 @@ lookup_function_type_with_arguments (struct type *type,
   struct type *fn = make_function_type (type, (struct type **) 0);
   int i;
 
-  if (nparams > 0 && param_types[nparams - 1] == NULL)
+  if (nparams > 0)
     {
-      --nparams;
-      TYPE_VARARGS (fn) = 1;
+      if (param_types[nparams - 1] == NULL)
+       {
+         --nparams;
+         TYPE_VARARGS (fn) = 1;
+       }
+      else if (TYPE_CODE (check_typedef (param_types[nparams - 1]))
+              == TYPE_CODE_VOID)
+       {
+         --nparams;
+         /* Caller should have ensured this.  */
+         gdb_assert (nparams == 0);
+         TYPE_PROTOTYPED (fn) = 1;
+       }
     }
 
   TYPE_NFIELDS (fn) = nparams;
index cb0918b03f4021cd100df18fca8cd6edfdc1e006..2f249a9fc9d6e950e6ff75cd8a4d35b553e3fad3 100644 (file)
@@ -1,3 +1,9 @@
+2012-07-09  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.base/whatis.exp: Add error checks for improper 'void' uses.
+       * gdb.base/callfuncs.exp: Add cast-based test.
+       * gdb.base/callfuncs.c (voidfunc): New function.
+
 2012-07-08  Doug Evans  <dje@google.com>
 
        * gdb.dwarf2/dw4-sig-type-unused.S: Fix typo.
index b4ab7d5fe7cf65284adf854c0a5d669e894cb34a..7fb5061866dc215a58a73283b518d879dde313e1 100644 (file)
@@ -641,6 +641,13 @@ struct struct_with_fnptr function_struct = { doubleit };
 
 struct struct_with_fnptr *function_struct_ptr = &function_struct;
 
+int *
+voidfunc (void)
+{
+  static int twentythree = 23;
+  return &twentythree;
+}
+
 /* Gotta have a main to be able to generate a linked, runnable
    executable, and also provide a useful place to set a breakpoint. */
 
index 66abee932fee2ec9e2a408ec0a15c174b704f9be..daaad1aebe2138529f32d5d57ba65e93f9c834fd 100644 (file)
@@ -539,3 +539,6 @@ if {![target_info exists gdb,nosignals] && ![istarget "*-*-uclinux*"]} {
 # handling vs. local labels `.L'... as `Lcallfunc' starts with `L'.
 
 gdb_test "print callfunc (Lcallfunc, 5)" " = 12"
+
+# Regression test for function pointer cast.
+gdb_test "print *((int *(*) (void)) voidfunc)()" " = 23"
index 9365485367bdc9fa8e33e91c757bb26204091fc1..18edc4c48b3f28ede87dd3e6dea16e28b9279dac 100644 (file)
@@ -499,3 +499,11 @@ gdb_test "whatis int (*)(int, int)" \
 gdb_test "whatis int (*)(const int *, ...)" \
     "type = int \\(\\*\\)\\(const int \\*, \\.\\.\\.\\)" \
     "whatis applied to pointer to function taking const int ptr and varargs and returning int"
+
+gdb_test "whatis int (*)(void, int, int)" \
+    "parameter types following 'void'" \
+    "whatis applied to function with types trailing 'void'"
+
+gdb_test "whatis int (*)(int, void, int)" \
+    "'void' invalid as parameter type" \
+    "whatis applied to function with 'void' parameter type"