* 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.
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.
This commit is contained in:
Tom Tromey 2012-07-09 14:20:52 +00:00
parent 1416057852
commit e314d62968
8 changed files with 95 additions and 6 deletions

View 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.

View 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. */

View 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);

View 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;

View 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.

View 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. */

View 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"

View 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"