This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA 2/3] c++/13356: set/show check type


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  <keiths@redhat.com>

	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  <keiths@redhat.com>

	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.
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<char const**> (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"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]