Handle sizeof(type) in Rust

PR rust/21764 notes that "sizeof" does not work correctly for all types
in Rust.  The bug turns out to be an error in the conversion of the AST
to gdb expressions.  This patch fixes the bug and also avoids generating
incorrect expressions in another case.

Tested on the buildbot.  I'm checking this in.

2017-07-14  Tom Tromey  <tom@tromey.com>

	PR rust/21764:
	* rust-exp.y (convert_ast_to_expression): Add "want_type"
	parameter.
	<UNOP_SIZEOF>: Split into separate case.
	<UNOP_VAR_VALUE>: Handle want_type.  Add error case.

2017-07-14  Tom Tromey  <tom@tromey.com>

	PR rust/21764:
	* gdb.rust/simple.exp: Add tests.
This commit is contained in:
Tom Tromey 2017-07-14 08:10:39 -06:00
parent 65547233e0
commit 8880f2a9cb
4 changed files with 36 additions and 7 deletions

View File

@ -1,3 +1,11 @@
2017-07-14 Tom Tromey <tom@tromey.com>
PR rust/21764:
* rust-exp.y (convert_ast_to_expression): Add "want_type"
parameter.
<UNOP_SIZEOF>: Split into separate case.
<UNOP_VAR_VALUE>: Handle want_type. Add error case.
2017-07-14 Tom Tromey <tom@tromey.com>
PR rust/21763:

View File

@ -2100,7 +2100,8 @@ convert_name (struct parser_state *state, const struct rust_op *operation)
static void convert_ast_to_expression (struct parser_state *state,
const struct rust_op *operation,
const struct rust_op *top);
const struct rust_op *top,
bool want_type = false);
/* A helper function that converts a vec of rust_ops to a gdb
expression. */
@ -2121,12 +2122,16 @@ convert_params_to_expression (struct parser_state *state,
OPERATION is the operation to lower. TOP is a pointer to the
top-most operation; it is used to handle the special case where the
top-most expression is an identifier and can be optionally lowered
to OP_TYPE. */
to OP_TYPE. WANT_TYPE is a flag indicating that, if the expression
is the name of a type, then emit an OP_TYPE for it (rather than
erroring). If WANT_TYPE is set, then the similar TOP handling is
not done. */
static void
convert_ast_to_expression (struct parser_state *state,
const struct rust_op *operation,
const struct rust_op *top)
const struct rust_op *top,
bool want_type)
{
switch (operation->opcode)
{
@ -2166,12 +2171,16 @@ convert_ast_to_expression (struct parser_state *state,
}
break;
case UNOP_SIZEOF:
convert_ast_to_expression (state, operation->left.op, top, true);
write_exp_elt_opcode (state, UNOP_SIZEOF);
break;
case UNOP_PLUS:
case UNOP_NEG:
case UNOP_COMPLEMENT:
case UNOP_IND:
case UNOP_ADDR:
case UNOP_SIZEOF:
convert_ast_to_expression (state, operation->left.op, top);
write_exp_elt_opcode (state, operation->opcode);
break;
@ -2337,7 +2346,8 @@ convert_ast_to_expression (struct parser_state *state,
if (type == NULL)
error (_("No symbol '%s' in current context"), varname);
if (TYPE_CODE (type) == TYPE_CODE_STRUCT
if (!want_type
&& TYPE_CODE (type) == TYPE_CODE_STRUCT
&& TYPE_NFIELDS (type) == 0)
{
/* A unit-like struct. */
@ -2346,13 +2356,16 @@ convert_ast_to_expression (struct parser_state *state,
write_exp_elt_longcst (state, 0);
write_exp_elt_opcode (state, OP_AGGREGATE);
}
else if (operation == top)
else if (want_type || operation == top)
{
write_exp_elt_opcode (state, OP_TYPE);
write_exp_elt_type (state, type);
write_exp_elt_opcode (state, OP_TYPE);
break;
}
else
error (_("Found type '%s', which can't be "
"evaluated in this context"),
varname);
}
}
break;

View File

@ -1,3 +1,8 @@
2017-07-14 Tom Tromey <tom@tromey.com>
PR rust/21764:
* gdb.rust/simple.exp: Add tests.
2017-07-14 Tom Tromey <tom@tromey.com>
* gdb.rust/simple.exp: Add regression test for PR rust/21763.

View File

@ -135,6 +135,9 @@ gdb_test "print simple::ByeBob\{field1: 0xff, field2:5\}" \
gdb_test "print simple::HiBob(0xff, 5)" \
"Type simple::HiBob is not a tuple struct"
gdb_test "print sizeof(simple::HiBob)" " = \[0-9\]+"
gdb_test "print simple::HiBob + 5" \
"Found type 'simple::HiBob', which can't be evaluated in this context"
gdb_test "print nosuchsymbol" \
"No symbol 'nosuchsymbol' in current context"