From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12459 invoked by alias); 16 Aug 2012 20:15:34 -0000 Received: (qmail 12419 invoked by uid 22791); 16 Aug 2012 20:15:30 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS 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; Thu, 16 Aug 2012 20:15:12 +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 q7GKFBbA010691 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 16 Aug 2012 16:15:11 -0400 Received: from valrhona.uglyboxes.com (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 q7GKF97g021085 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 16 Aug 2012 16:15:10 -0400 Message-ID: <502D54CD.1050405@redhat.com> Date: Thu, 16 Aug 2012 20:15:00 -0000 From: Keith Seitz User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20120605 Thunderbird/13.0 MIME-Version: 1.0 To: "gp >> \"gdb-patches@sourceware.org ml\"" Subject: [RFA 2/3] c++/13356: set/show check type Content-Type: multipart/mixed; boundary="------------050605080606020100070601" X-IsSubscribed: yes 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-08/txt/msg00461.txt.bz2 This is a multi-part message in MIME format. --------------050605080606020100070601 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1264 Hi, This patch is the real meat of the bug, in which the user yearns for a way to permit some specialized type conversions which violate the standard. I've introduced a new badness level for this conversion, and return it when strict type checking is disabled. Most of the rest of the patch is the "new" set/show check type command and tests. Documentation is in the next patch. Comments/questions/concerns? Keith ChangeLog 2012-08-16 Keith Seitz PR c++/13356 * gdbtypes.c (strict_type_checking): New variable. (show_strict_type_checking): New function. (rank_one_type): Return NS_POINTER_INTEGER_CONVERSION_BADNESS if strict type checking is disabled. (_initialize_gdbtypes): Add "check type" subcommand. * gdbtypes.h (NS_INTEGER_POINTER_CONVERSION_BADNESS): New struct. teestuite/ChangeLog 2012-08-16 Keith Seitz PR c++/13356 * gdb.base/default.exp: Update all "check type" tests. * gdb.base/help.exp: Likewise. * gdb.base/setshow.exp: Likewise. * gdb.cp/converts.cc (foo1_type_check): New function. (foo2_type_check): New function. (foo3_type_check): New function. (main): Call new functions. * converts.exp: Add tests for integer-to-pointer conversions with/without strict type-checking. --------------050605080606020100070601 Content-Type: text/x-patch; name="13356-strict-type-checking.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="13356-strict-type-checking.patch" Content-length: 15786 diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 119a658..21d9043 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -59,6 +59,7 @@ const struct rank BASE_CONVERSION_BADNESS = {2,0}; const struct rank REFERENCE_CONVERSION_BADNESS = {2,0}; const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0}; const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0}; +const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0}; /* Floatformat pairs. */ const struct floatformat *floatformats_ieee_half[BFD_ENDIAN_UNKNOWN] = { @@ -119,6 +120,10 @@ static int opaque_type_resolution = 1; unsigned int overload_debug = 0; +/* A flag to enable strict type checking. */ + +static int strict_type_checking = 1; + /* A function to show whether opaque types are resolved. */ static void @@ -141,6 +146,15 @@ show_overload_debug (struct ui_file *file, int from_tty, value); } +/* A function to show the status of strict type checking. */ + +static void +show_strict_type_checking (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Strict type checking is %s.\n"), value); +} + /* Allocate a new OBJFILE-associated type structure and fill it with some defaults. Space for the type structure is allocated @@ -2507,12 +2521,20 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value) case TYPE_CODE_FUNC: return rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL); case TYPE_CODE_INT: - if (value != NULL && TYPE_CODE (value_type (value)) == TYPE_CODE_INT - && value_as_long (value) == 0) + if (value != NULL && TYPE_CODE (value_type (value)) == TYPE_CODE_INT) { - /* Null pointer conversion: allow it to be cast to a pointer. - [4.10.1 of C++ standard draft n3290] */ - return NULL_POINTER_CONVERSION_BADNESS; + if (value_as_long (value) == 0) + { + /* Null pointer conversion: allow it to be cast to a pointer. + [4.10.1 of C++ standard draft n3290] */ + return NULL_POINTER_CONVERSION_BADNESS; + } + else + { + /* If type checking is disabled, allow the conversion. */ + if (!strict_type_checking) + return NS_INTEGER_POINTER_CONVERSION_BADNESS; + } } /* fall through */ case TYPE_CODE_ENUM: @@ -4068,4 +4090,13 @@ _initialize_gdbtypes (void) NULL, NULL, show_opaque_type_resolution, &setlist, &showlist); + + /* Add an option to permit non-strict type checking. */ + add_setshow_boolean_cmd ("type", class_support, + &strict_type_checking, + _("Set strict type checking."), + _("Show strict type checking."), + NULL, NULL, + show_strict_type_checking, + &setchecklist, &showchecklist); } diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index afe0103..991026b 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -1616,6 +1616,9 @@ extern const struct rank NULL_POINTER_CONVERSION; /* Converting a pointer to an int is usually OK. */ extern const struct rank NS_POINTER_CONVERSION_BADNESS; +/* Badness of converting a (non-zero) integer constant + to a pointer. */ +extern const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS; extern struct rank sum_ranks (struct rank a, struct rank b); extern int compare_ranks (struct rank a, struct rank b); diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp index 5a73fcc..cc66da2 100644 --- a/gdb/testsuite/gdb.base/default.exp +++ b/gdb/testsuite/gdb.base/default.exp @@ -495,12 +495,13 @@ gdb_test "section" "Must specify section name and its virtual address.*" "sectio gdb_test "set annotate" "Argument required .integer to set it to.*" "set annotate" #test set args gdb_test_no_output "set args" "set args" -#test set check "c" abbreviation -gdb_test "set c" "\"set check\" must be followed by the name of a check subcommand.(\[^\r\n\]*\[\r\n\])+List of set check subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by set check subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set check \"c\" abbreviation" -#test set check "ch" abbreviation -gdb_test "set ch" "\"set check\" must be followed by the name of a check subcommand.(\[^\r\n\]*\[\r\n\])+List of set check subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by set check subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set check \"ch\" abbreviation" -#test set check -gdb_test "set check" "\"set check\" must be followed by the name of a check subcommand.(\[^\r\n\]*\[\r\n\])+List of set check subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by set check subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." "set check" + +# Test set check abbreviations +foreach x {"c" "ch" "check"} { + gdb_test "set $x" "\"set check\" must be followed by the name of a check subcommand.(\[^\r\n\]*\[\r\n\])+List of set check subcommands:(\[^\r\n\]*\[\r\n\])+set check range -- Set range checking(\[^\r\n\]*\[\r\n\])+set check type -- Set strict type checking(\[^\r\n\]*\[\r\n\])+Type \"help set check\" followed by set check subcommand name for full documentation.(\[^\r\n\]*\[\r\n\])+Command name abbreviations are allowed if unambiguous." \ + "set check \"$x\" abbreviation" +} + #test set check range gdb_test "set check range" ".*" "set check range" #test set check type @@ -577,16 +578,17 @@ gdb_test "shell echo Hi dad!" "Hi dad!" "shell echo Hi dad!" gdb_test "show annotate" "Annotation_level is 0." "show annotate" #test show args gdb_test "show args" "Argument list to give program being debugged when it is started is \"\"." "show args" -#test show check "c" abbreviation -gdb_test "show c" "range: *Range checking is \"auto; currently off\".(\[^\r\n\]*\[\r\n\])+type: *Type checking is \"auto; currently off\".*" "show check \"c\" abbreviation" -#test show check "ch" abbreviation -gdb_test "show ch" "range: *Range checking is \"auto; currently off\".(\[^\r\n\]*\[\r\n\])+type: *Type checking is \"auto; currently off\"." "show check \"ch\" abbreviation" -#test show check -gdb_test "show check" "range: *Range checking is \"auto; currently off\".(\[^\r\n\]*\[\r\n\])+type: *Type checking is \"auto; currently off\"." "show check" + +# test show check abbreviations +foreach x {"c" "ch" "check"} { + gdb_test "show $x" "range: *Range checking is \"auto; currently off\".(\[^\r\n\]*\[\r\n\])+type: *Strict type checking is on\..*" \ + "show check \"$x\" abbreviation" +} + #test show check range gdb_test "show check range" "Range checking is \"auto; currently off\"." "show check range" #test show check type -gdb_test "show check type" "Type checking is \"auto; currently off\"." "show check type" +gdb_test "show check type" "Strict type checking is on\." "show check type" #test show commands gdb_test "show commands" ".*" "show commands" #test show complaints diff --git a/gdb/testsuite/gdb.base/help.exp b/gdb/testsuite/gdb.base/help.exp index 547495b..d69414c 100644 --- a/gdb/testsuite/gdb.base/help.exp +++ b/gdb/testsuite/gdb.base/help.exp @@ -376,22 +376,26 @@ gdb_test "help section" "Change the base address of section SECTION of the exec gdb_test "help set annotate" "Set annotation_level\.\[\r\n\]+0 == normal; 1 == fullname \\(for use when running under emacs\\)\[\r\n\]+2 == output annotated suitably for use by programs that control GDB\." "help set annotate" # test help set args gdb_test "help set args" "Set argument list to give program being debugged when it is started\.\[\r\n\]+Follow this command with any number of args, to be passed to the program\." -# test help set check "c" abbreviation -test_prefix_command_help {"set c" "set check"} { - "Set the status of the type/range checker\.\[\r\n\]+" -} "help set check \"c\" abbreviation" -# test help set check "ch" abbreviation -test_prefix_command_help {"set ch" "set check"} { - "Set the status of the type/range checker\.\[\r\n\]+" -} "help set check \"ch\" abbreviation" -# test help set check + +# Test help set check abbreviations +foreach x {"c" "ch"} { + test_prefix_command_help [list "set $x" "set check"] { + "Set the status of the type/range checker\.\[\r\n\]+" + } "help set check \"$x\" abbreviation" +} + +# Test help set check test_prefix_command_help {"set check"} { "Set the status of the type/range checker\.\[\r\n\]+" } + # test help set check range gdb_test "help set check range" "Set range checking\. \\(on/warn/off/auto\\)" "help set check range" -# test help set check type -gdb_test "help set check type" "Set type checking\. \\(on/warn/off/auto\\)." "help set check type" + +# Test help set check type +gdb_test "help set check type" "Set strict type checking\." \ + "help set check type" + # test help set complaints gdb_test "help set complaints" "Set max number of complaints about incorrect symbols\." "help set complaints" # test help set confirm @@ -487,18 +491,25 @@ gdb_test "help shell" "Execute the rest of the line as a shell command\.\[\r\n\] gdb_test "help show annotate" "Show annotation_level\.\[\r\n\]+0 == normal; 1 == fullname \\(for use when running under emacs\\)\[\r\n\]+2 == output annotated suitably for use by programs that control GDB\." "help show annotate" # test help show args gdb_test "help show args" "Show argument list to give program being debugged when it is started\.\[\r\n\]+Follow this command with any number of args, to be passed to the program\." -# test help show check "c" abbreviation -test_prefix_command_help {"show c" "show check"} { - "Show the status of the type/range checker\.\[\r\n\]+" -} "help show check \"c\" abbreviation" + +# Test help show check abbreviations +foreach x {"c" "check"} { + test_prefix_command_help [list "show $x" "show check"] { + "Show the status of the type/range checker\.\[\r\n\]+" + } "help show check \"$x\" abbreviation" +} + # test help show check test_prefix_command_help {"show check"} { "Show the status of the type/range checker\.\[\r\n\]+" } # test help show check range gdb_test "help show check range" "Show range checking\. \\(on/warn/off/auto\\)" "help show check range" + # test help show check type -gdb_test "help show check type" "Show type checking\. \\(on/warn/off/auto\\)" "help show check type" +gdb_test "help show check type" "Show strict type checking\." \ + "help show check type" + # test help show commands gdb_test "help show commands" "Show the history of commands you typed\.\[\r\n\]+You can supply a command number to start with, or a `\[+\]' to start after\[\r\n\]+the previous command number shown\." "help show commands" # test help show complaints diff --git a/gdb/testsuite/gdb.base/setshow.exp b/gdb/testsuite/gdb.base/setshow.exp index 9af5c30..d33e185 100644 --- a/gdb/testsuite/gdb.base/setshow.exp +++ b/gdb/testsuite/gdb.base/setshow.exp @@ -114,19 +114,22 @@ gdb_test "show check range" "Range checking is \"off\"\..*" "show check range (o #test set check range auto gdb_test_no_output "set check range auto" "set check range auto" #test show check range auto -gdb_test "show check range" "Range checking is \"auto; currently .*" "show check range (auto)" -#test set check type on -gdb_test "set check type on" ".*" "set check type on" -#test show check type on -gdb_test "show check type" "Type checking is \"on\"..*" "show check type (on)" -#test set check type off with trailing space -gdb_test_no_output "set check type off " "set check type off" -#test show check type off -gdb_test "show check type" "Type checking is \"off\"..*" "show check type (off)" -#test set check type auto -gdb_test_no_output "set check type auto" "set check type auto" -#test show check type -gdb_test "show check type" "Type checking is \"auto; currently .*" "show check type (auto)" +gdb_test "show check range" "Range checking is \"auto; currently .*" "show check range (auto)" + +# Test set check type on +gdb_test "set check type on" ".*" "set check type on" + +# Test show check type on +gdb_test "show check type" "Strict type checking is on\..*" \ + "show check type (on)" + +# Test set check type off with trailing space +gdb_test_no_output "set check type off " "set check type off" + +# Test show check type off +gdb_test "show check type" "Strict type checking is off\..*" \ + "show check type (off)" + #test set complaints 100 gdb_test_no_output "set complaints 100" "set complaints 100" #test show complaints 100 diff --git a/gdb/testsuite/gdb.cp/converts.cc b/gdb/testsuite/gdb.cp/converts.cc index 26a45f5..ecebbf8 100644 --- a/gdb/testsuite/gdb.cp/converts.cc +++ b/gdb/testsuite/gdb.cp/converts.cc @@ -27,6 +27,10 @@ int foo3_1 (int a, const char **b) { return 31; } int foo3_2 (int a, int b) { return 32; } int foo3_2 (int a, const char **b) { return 320; } +int foo1_type_check (char *a) { return 1000; } +int foo2_type_check (char *a, char *b) { return 1001; } +int foo3_type_check (char *a, char *b, char *c) { return 1002; } + int main() { @@ -62,5 +66,9 @@ int main() foo3_2 (0, static_cast (0)); foo3_2 (0, 0); + foo1_type_check (a); + foo2_type_check (a, a); + foo3_type_check (a, a, a); + return 0; // end of main } diff --git a/gdb/testsuite/gdb.cp/converts.exp b/gdb/testsuite/gdb.cp/converts.exp index 9b8df58..414e2d0 100644 --- a/gdb/testsuite/gdb.cp/converts.exp +++ b/gdb/testsuite/gdb.cp/converts.exp @@ -70,9 +70,37 @@ gdb_test_multiple "p foo3_1 (0, 0)" $t { pass $t } } + gdb_test "p foo3_1 (0, 1)" \ "Cannot resolve function foo3_1 to any overloaded instance" gdb_test "p foo3_1 (0, (const char**) 1)" " = 31" gdb_test "p foo3_2 (0, 0)" "= 32" gdb_test "p foo3_2 (0, (char const**) 0)" " = 320" +# Test for strict type checking +set error_str "Cannot resolve function %s to any overloaded instance" +gdb_test "show check type" "Strict type checking is on\." +gdb_test "p foo1_type_check (123)" [format $error_str "foo1_type_check"] +gdb_test "p foo2_type_check (0, 1)" [format $error_str "foo2_type_check"] +gdb_test "p foo2_type_check (1, 0)" [format $error_str "foo2_type_check"] +gdb_test "p foo2_type_check (1, 1)" [format $error_str "foo2_type_check"] +gdb_test "p foo3_type_check (0, 0, 1)" [format $error_str "foo3_type_check"] +gdb_test "p foo3_type_check (0, 1, 0)" [format $error_str "foo3_type_check"] +gdb_test "p foo3_type_check (1, 0, 0)" [format $error_str "foo3_type_check"] +gdb_test "p foo3_type_check (0, 1, 1)" [format $error_str "foo3_type_check"] +gdb_test "p foo3_type_check (1, 1, 0)" [format $error_str "foo3_type_check"] +gdb_test "p foo3_type_check (1, 1, 1)" [format $error_str "foo3_type_check"] + +gdb_test_no_output "set check type off" +gdb_test "show check type" "Strict type checking is off\." +gdb_test "p foo1_type_check (123)" " = 1000" +gdb_test "p foo2_type_check (0, 1)" " = 1001" +gdb_test "p foo2_type_check (1, 0)" " = 1001" +gdb_test "p foo2_type_check (1, 1)" " = 1001" +gdb_test "p foo3_type_check (0, 0, 1)" " = 1002" +gdb_test "p foo3_type_check (0, 1, 0)" " = 1002" +gdb_test "p foo3_type_check (1, 0, 0)" " = 1002" +gdb_test "p foo3_type_check (0, 1, 1)" " = 1002" +gdb_test "p foo3_type_check (1, 1, 0)" " = 1002" +gdb_test "p foo3_type_check (1, 1, 1)" " = 1002" +gdb_test "p foo3_2 (1,1)" " = 32" --------------050605080606020100070601--