-/* Copyright 1999, 2004, 2007 Free Software Foundation, Inc.
+/* Copyright 1999-2020 Free Software Foundation, Inc.
This file is part of GDB.
struct _struct_n_pointer *next;
};
+struct anonymous {
+ int a;
+ struct {
+ int b;
+ char *c;
+ union {
+ int d;
+ void *e;
+ char f;
+ struct {
+ char g;
+ const char **h;
+ simpleton ***simple;
+ };
+ };
+ };
+};
+
void do_locals_tests (void);
void do_block_tests (void);
void subroutine1 (int, long *);
{
int linteger = 0;
int *lpinteger = 0;
- char lcharacter = 0;
+ char lcharacter[2] = { 0, 0 };
char *lpcharacter = 0;
long llong = 0;
long *lplong = 0;
float *lpfloat = 0;
double ldouble = 0;
double *lpdouble = 0;
- struct _simple_struct lsimple;
- struct _simple_struct *lpsimple;
- void (*func) (void);
+ struct _simple_struct lsimple = { 0 };
+ struct _simple_struct *lpsimple = 0;
+ void (*func) (void) = 0;
/* Simple assignments */
linteger = 1234;
lpinteger = &linteger;
- lcharacter = 'a';
- lpcharacter = &lcharacter;
+ lcharacter[0] = 'a';
+ lpcharacter = lcharacter;
llong = 2121L;
lplong = &llong;
lfloat = 2.1;
lsimple.unsigned_integer = 255;
lsimple.character = 'a';
lsimple.signed_character = 21;
- lsimple.char_ptr = &lcharacter;
+ lsimple.char_ptr = lcharacter;
lpsimple = &lsimple;
func = nothing;
/* Check pointers */
linteger = 4321;
- lcharacter = 'b';
+ lcharacter[0] = 'b';
llong = 1212L;
lfloat = 1.2;
ldouble = 5.498548281828172;
{
}
+struct _struct_decl
+nothing1 (int a, char *b, long c)
+{
+ struct _struct_decl foo;
+
+ return foo;
+}
+
+struct _struct_decl *
+nothing2 (int a, char *b, long c)
+{
+ return (struct _struct_decl *) 0;
+}
+
void
subroutine1 (int i, long *l)
{
int *foo;
int bar;
- struct _struct_decl struct_declarations;
- memset (&struct_declarations, 0, sizeof (struct_declarations));
+ /* Avoid pointing into NULL, as that is editable on some
+ systems. */
+ int dummy;
+ int *dummy_ptr = &dummy;
+
+ struct _struct_decl struct_declarations = { 0, 0, NULL, 0, &dummy_ptr };
weird = &struct_declarations;
struct_declarations.integer = 123;
struct_declarations.long_array[9] = 1234;
weird->func_ptr = nothing;
+ weird->func_ptr_struct = nothing1;
+ weird->func_ptr_ptr = nothing2;
/* Struct/pointer/array tests */
a0[0] = '0';
int v2 = 4;
/*:
- mi_create_varobj V1 v1 "create varobj for v1"
- mi_create_varobj V2 v2 "create varobj for v2"
-
- mi_list_varobj_children "V1" {
- {"V1.i" "i" "0" "int"}
- {"V1.nested" "nested" "2" "struct {...}"}
- } "list children of v1"
-
- mi_list_varobj_children "V1.nested" {
- {"V1.nested.j" "j" "0" "int"}
- {"V1.nested.k" "k" "0" "int"}
- } "list children of v1.nested"
-
- mi_check_varobj_value V1.i 1 "check V1.i: 1"
- mi_check_varobj_value V1.nested.j 2 "check V1.nested.j: 2"
- mi_check_varobj_value V1.nested.k 3 "check V1.nested.k: 3"
- mi_check_varobj_value V2 4 "check V2: 4"
+ with_test_prefix "create varobj V1 and V2" {
+ mi_create_varobj V1 v1 "create varobj for v1"
+ mi_create_varobj V2 v2 "create varobj for v2"
+
+ mi_list_varobj_children "V1" {
+ {"V1.i" "i" "0" "int"}
+ {"V1.nested" "nested" "2" "struct {...}"}
+ } "list children of v1"
+
+ mi_list_varobj_children "V1.nested" {
+ {"V1.nested.j" "j" "0" "int"}
+ {"V1.nested.k" "k" "0" "int"}
+ } "list children of v1.nested"
+
+ mi_check_varobj_value V1.i 1 "check V1.i: 1"
+ mi_check_varobj_value V1.nested.j 2 "check V1.nested.j: 2"
+ mi_check_varobj_value V1.nested.k 3 "check V1.nested.k: 3"
+ mi_check_varobj_value V2 4 "check V2: 4"
+ }
:*/
v2 = 5;
/*:
v1.nested.j = 8;
v1.nested.k = 9;
/*:
- set_frozen V1 1
- mi_varobj_update * {} "update varobjs: nothing changed"
- mi_check_varobj_value V1.i 1 "check V1.i: 1"
- mi_check_varobj_value V1.nested.j 2 "check V1.nested.j: 2"
- mi_check_varobj_value V1.nested.k 3 "check V1.nested.k: 3"
+ with_test_prefix "frozen V1" {
+ set_frozen V1 1
+ mi_varobj_update * {} "update varobjs: nothing changed"
+ mi_check_varobj_value V1.i 1 "check V1.i: 1"
+ mi_check_varobj_value V1.nested.j 2 "check V1.nested.j: 2"
+ mi_check_varobj_value V1.nested.k 3 "check V1.nested.k: 3"
+ }
# Check that explicit update for elements of structures
# works.
- # Update v1.j
- mi_varobj_update V1.nested.j {V1.nested.j} "update V1.nested.j"
- mi_check_varobj_value V1.i 1 "check V1.i: 1"
- mi_check_varobj_value V1.nested.j 8 "check V1.nested.j: 8"
- mi_check_varobj_value V1.nested.k 3 "check V1.nested.k: 3"
- # Update v1.nested, check that children is updated.
- mi_varobj_update V1.nested {V1.nested.k} "update V1.nested"
- mi_check_varobj_value V1.i 1 "check V1.i: 1"
- mi_check_varobj_value V1.nested.j 8 "check V1.nested.j: 8"
- mi_check_varobj_value V1.nested.k 9 "check V1.nested.k: 9"
- # Update v1.i
- mi_varobj_update V1.i {V1.i} "update V1.i"
- mi_check_varobj_value V1.i 7 "check V1.i: 7"
+ with_test_prefix "update v1.j" {
+ # Update v1.j
+ mi_varobj_update V1.nested.j {V1.nested.j} "update V1.nested.j"
+ mi_check_varobj_value V1.i 1 "check V1.i: 1"
+ mi_check_varobj_value V1.nested.j 8 "check V1.nested.j: 8"
+ mi_check_varobj_value V1.nested.k 3 "check V1.nested.k: 3"
+ }
+ with_test_prefix "update v1.nested" {
+ # Update v1.nested, check that children is updated.
+ mi_varobj_update V1.nested {V1.nested.k} "update V1.nested"
+ mi_check_varobj_value V1.i 1 "check V1.i: 1"
+ mi_check_varobj_value V1.nested.j 8 "check V1.nested.j: 8"
+ mi_check_varobj_value V1.nested.k 9 "check V1.nested.k: 9"
+ }
+ with_test_prefix "update v1.i" {
+ # Update v1.i
+ mi_varobj_update V1.i {V1.i} "update V1.i"
+ mi_check_varobj_value V1.i 7 "check V1.i: 7"
+ }
:*/
v1.i = 10;
v1.nested.j = 11;
v1.nested.k = 12;
/*:
# Check that unfreeze itself does not updates the values.
- set_frozen V1 0
- mi_check_varobj_value V1.i 7 "check V1.i: 7"
- mi_check_varobj_value V1.nested.j 8 "check V1.nested.j: 8"
- mi_check_varobj_value V1.nested.k 9 "check V1.nested.k: 9"
- mi_varobj_update V1 {V1.i V1.nested.j V1.nested.k} "update V1"
- mi_check_varobj_value V1.i 10 "check V1.i: 10"
- mi_check_varobj_value V1.nested.j 11 "check V1.nested.j: 11"
- mi_check_varobj_value V1.nested.k 12 "check V1.nested.k: 12"
+ with_test_prefix "unfrozen V1" {
+ set_frozen V1 0
+ mi_check_varobj_value V1.i 7 "check V1.i: 7"
+ mi_check_varobj_value V1.nested.j 8 "check V1.nested.j: 8"
+ mi_check_varobj_value V1.nested.k 9 "check V1.nested.k: 9"
+ mi_varobj_update V1 {V1.i V1.nested.j V1.nested.k} "update V1"
+ mi_check_varobj_value V1.i 10 "check V1.i: 10"
+ mi_check_varobj_value V1.nested.j 11 "check V1.nested.j: 11"
+ mi_check_varobj_value V1.nested.k 12 "check V1.nested.k: 12"
+ }
:*/
/*: END: frozen :*/
}
+void do_at_tests_callee ()
+{
+ /* This is a test of wrong DWARF data being assigned to expression.
+ The DWARF location expression is bound to symbol when expression
+ is parsed. So, if we create floating varobj in one function,
+ and then try to reevaluate it in other frame without reparsing
+ the expression, we will access local variables using DWARF
+ location expression from the original frame, and are likely
+ to grab wrong symbol. To reliably reproduce this bug, we need
+ to wrap our variable with a bunch of buffers, so that those
+ buffers are accessed instead of the real one. */
+ int buffer1 = 10;
+ int buffer2 = 11;
+ int buffer3 = 12;
+ int i = 7;
+ int buffer4 = 13;
+ int buffer5 = 14;
+ int buffer6 = 15;
+ i++; /* breakpoint inside callee */
+ i++;
+}
+
+void do_at_tests ()
+{
+ int x;
+ /*: BEGIN: floating :*/
+ int i = 10;
+ int y = 15;
+ /*:
+ mi_create_floating_varobj F i "create floating varobj"
+ :*/
+ i++;
+ /*:
+ mi_varobj_update F {F} "update F (1)"
+ mi_check_varobj_value F 11 "check F (1)"
+ :*/
+ i++;
+ {
+ double i = 15;
+ /*:
+ mi_varobj_update_with_type_change F "double" "0" "update F (2)"
+ mi_check_varobj_value F 15 "check F (2)"
+ :*/
+ i += 2.0;
+ }
+ {
+ float i = 19;
+ /*:
+ mi_gdb_test "-var-update --all-values F" {.*value="19".*} "update F (--all-values)"
+ :*/
+ i += 2.0;
+ }
+ i++;
+ /*:
+ mi_varobj_update_with_type_change F "int" "0" "update F (3)"
+ mi_check_varobj_value F 13 "check F (3)"
+ :*/
+ i++;
+ do_at_tests_callee ();
+ i++;
+ /*: END: floating :*/
+}
+
+/* Some header appear to define uint already, so apply some
+ uglification. Note that without uglification, the compile
+ does not fail, rather, we don't test what we want because
+ something else calls check_typedef on 'uint' already. */
+typedef unsigned int uint_for_mi_testing;
+
+struct Data {
+ int alloc;
+ uint_for_mi_testing sharable : 4;
+};
+
+/* Accessing a value of a bitfield whose type is a typed used to
+ result in division by zero. See:
+
+ http://sourceware.org/bugzilla/show_bug.cgi?id=10884
+
+ This tests for this bug. */
+
+void do_bitfield_tests ()
+{
+ /*: BEGIN: bitfield :*/
+ struct Data d = {0, 3};
+ /*:
+ mi_create_varobj V d "create varobj for Data"
+ mi_list_varobj_children "V" {
+ {"V.alloc" "alloc" "0" "int"}
+ {"V.sharable" "sharable" "0" "uint_for_mi_testing"}
+ } "list children of Data"
+ mi_check_varobj_value V.sharable 3 "access bitfield"
+ :*/
+ return;
+ /*: END: bitfield :*/
+}
+
+void
+do_anonymous_type_tests (void)
+{
+ struct anonymous *anon;
+ struct anonymous **ptr;
+ struct
+ {
+ int x;
+ struct
+ {
+ int a;
+ };
+ struct
+ {
+ int b;
+ };
+ } v = {1, {2}, {3}};
+
+ anon = malloc (sizeof (struct anonymous));
+ anon->a = 1;
+ anon->b = 2;
+ anon->c = (char *) 3;
+ anon->d = 4;
+ anon->g = '5';
+ anon->h = (const char **) 6;
+ anon->simple = (simpleton ***) 7;
+
+ ptr = &anon;
+ free (anon);
+ return; /* anonymous type tests breakpoint */
+}
+
+void
+do_nested_struct_union_tests (void)
+{
+ struct s_a
+ {
+ int a;
+ };
+ struct s_b
+ {
+ int b;
+ };
+ union u_ab
+ {
+ struct s_a a;
+ struct s_b b;
+ };
+ struct ss
+ {
+ struct s_a a1;
+ struct s_b b1;
+ union u_ab u1;
+
+ /* Anonymous union. */
+ union
+ {
+ struct s_a a2;
+ struct s_b b2;
+ };
+
+ union
+ {
+ struct s_a a3;
+ struct s_b b3;
+ } u2;
+ };
+
+ typedef struct
+ {
+ int a;
+ } td_s_a;
+
+ typedef struct
+ {
+ int b;
+ } td_s_b;
+
+ typedef union
+ {
+ td_s_a a;
+ td_s_b b;
+ } td_u_ab;
+
+ struct ss var;
+ struct
+ {
+ td_u_ab ab;
+ } var2;
+
+ struct ss *ss_ptr;
+
+ memset (&var, 0, sizeof (var));
+ memset (&var2, 0, sizeof (var2));
+ ss_ptr = &var;
+
+ return; /* nested struct union tests breakpoint */
+}
+
int
main (int argc, char *argv [])
{
do_children_tests ();
do_special_tests ();
do_frozen_tests ();
+ do_at_tests ();
+ do_bitfield_tests ();
+ do_anonymous_type_tests ();
+ do_nested_struct_union_tests ();
exit (0);
}