gdb/testsuite: add new test for comparing char types in Python
authorAndrew Burgess <aburgess@redhat.com>
Fri, 25 Feb 2022 11:03:03 +0000 (11:03 +0000)
committerAndrew Burgess <aburgess@redhat.com>
Mon, 7 Mar 2022 19:42:08 +0000 (19:42 +0000)
There's an interesting property of the 'char' type in C and C++, the
three types 'char', 'unsigned char', and 'signed char', are all
considered distinct.

In contrast, and 'int' is signed by default, and so 'int' and 'signed
int' are considered the same type.

This commit adds a test to ensure that this edge case is visible to a
user from Python.

It is worth noting that for any particular compiler implementation (or
the flags a compiler was invoked with), a 'char' will be either signed
or unsigned; it has to be one or the other, and a user can access this
information by using the Type.is_signed property.  However, for
something like function overload resolution, the 'char' type is
considered distinct from the signed and unsigned variants.

There's no change to GDB with this commit, this is just adding a new
test to guard some existing functionality.

gdb/testsuite/gdb.python/py-type.exp

index 86cf8f3ff6994682613ebe7aa5e34f3daa29f9bc..5613bc024f6f6b8c45fd8312c4d6c9c4aeea54d2 100644 (file)
@@ -296,6 +296,38 @@ proc test_is_signed {lang} {
     gdb_test "python print(gdb.parse_and_eval ('&uu').type.is_signed == False)" "True"
 }
 
+# Compare the types of different symbols from the inferior, we're
+# checking that the types of different sybols of the same declared
+# type, are equal (in Python).
+proc test_type_equality {} {
+
+    foreach_with_prefix type { char int } {
+       gdb_test_no_output "python v1 = gdb.parse_and_eval('global_unsigned_${type}')"
+       gdb_test_no_output "python v2 = gdb.parse_and_eval('global_${type}')"
+       gdb_test_no_output "python v3 = gdb.parse_and_eval('global_signed_${type}')"
+
+       gdb_test_no_output "python t1 = v1.type"
+       gdb_test_no_output "python t2 = v2.type"
+       gdb_test_no_output "python t3 = v3.type"
+
+       if { $type == "char" } {
+           # In C/C++ there's an interesting property of 'char' based types;
+           # 'signed char', 'unsigned char', and 'char' are all distinct
+           # types.  Weird, right?  Here we check that this property is
+           # visible to Python code.
+           gdb_test "python print(t1 != t2)" "True"
+           gdb_test "python print(t1 != t3)" "True"
+           gdb_test "python print(t2 != t3)" "True"
+       } else {
+           # For 'int' type, when neither signed or unsigned is given
+           # we expect the type to be signed by default.
+           gdb_test "python print(t1 != t2)" "True"
+           gdb_test "python print(t1 != t3)" "True"
+           gdb_test "python print(t2 == t3)" "True"
+       }
+    }
+}
+
 # Test the gdb.Type.is_scalar property.
 proc test_is_scalar { lang } {
     if {$lang == "c++"} {
@@ -347,6 +379,7 @@ if { [build_inferior "${binfile}" "c"] == 0 } {
       test_enums
       test_is_scalar "c"
       test_is_signed "c"
+      test_type_equality
   }
 }
 
@@ -362,5 +395,6 @@ if { [build_inferior "${binfile}-cxx" "c++"] == 0 } {
       test_enums
       test_is_scalar "c++"
       test_is_signed "c++"
+      test_type_equality
   }
 }