From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31709 invoked by alias); 9 Jul 2012 14:20:08 -0000 Received: (qmail 31698 invoked by uid 22791); 9 Jul 2012 14:20:06 -0000 X-SWARE-Spam-Status: No, hits=-6.5 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,SPF_HELO_PASS,TW_YY,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 09 Jul 2012 14:19:52 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q69EJpRF019936 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 9 Jul 2012 10:19:52 -0400 Received: from barimba (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q69EJo2g018968 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Mon, 9 Jul 2012 10:19:50 -0400 From: Tom Tromey To: Jan Kratochvil Cc: gdb-patches@sourceware.org Subject: Re: Still regressing, now: Too few arguments in function call [Re: [0/5] FYI: fix typename parsing bugs] References: <87k3yhot2g.fsf@fleche.redhat.com> <20120707125749.GA11559@host2.jankratochvil.net> Date: Mon, 09 Jul 2012 14:20:00 -0000 In-Reply-To: <20120707125749.GA11559@host2.jankratochvil.net> (Jan Kratochvil's message of "Sat, 7 Jul 2012 14:57:49 +0200") Message-ID: <87eholkoe1.fsf@fleche.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-07/txt/msg00110.txt.bz2 >>>>> "Jan" == Jan Kratochvil writes: Jan> It still does not fix exactly the regression: Of course. Sorry about that. I missed that the '(void)' case requires special treatment. The appended fixes the problem. Built and regested on x86-64 Fedora 16. New tests included. I also tried it by hand using __errno_location. Tom b/gdb/ChangeLog: 2012-07-09 Tom Tromey * 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. b/gdb/testsuite/ChangeLog: 2012-07-09 Tom Tromey * 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. diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 14fd53d..0613799 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -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 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. */ diff --git a/gdb/eval.c b/gdb/eval.c index 13f997f..7d3a8b9 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -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); diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index cb25e71..8142ab9 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -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; diff --git a/gdb/testsuite/gdb.base/callfuncs.c b/gdb/testsuite/gdb.base/callfuncs.c index b4ab7d5..7fb5061 100644 --- a/gdb/testsuite/gdb.base/callfuncs.c +++ b/gdb/testsuite/gdb.base/callfuncs.c @@ -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. */ diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp index 66abee9..daaad1a 100644 --- a/gdb/testsuite/gdb.base/callfuncs.exp +++ b/gdb/testsuite/gdb.base/callfuncs.exp @@ -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" diff --git a/gdb/testsuite/gdb.base/whatis.exp b/gdb/testsuite/gdb.base/whatis.exp index 9365485..18edc4c 100644 --- a/gdb/testsuite/gdb.base/whatis.exp +++ b/gdb/testsuite/gdb.base/whatis.exp @@ -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"