parser: Move outer attrs properly intoto AssignmentExpr

AssignmentExpressions could not access their outer attributes properly,
since they were being eagerly moved into the `IdentifierExpr` type they
are based on. The base `OperatorExpr` class would thus end up with an
empty vector of outer attributes
This commit is contained in:
Arthur Cohen 2022-03-25 09:50:48 +01:00
parent 2249a4d512
commit 6c99a5a8f1
3 changed files with 25 additions and 10 deletions

View File

@ -704,8 +704,9 @@ public:
// Call OperatorExpr constructor to initialise left_expr
AssignmentExpr (std::unique_ptr<Expr> value_to_assign_to,
std::unique_ptr<Expr> value_to_assign, Location locus)
: OperatorExpr (std::move (value_to_assign_to), std::vector<Attribute> (),
std::unique_ptr<Expr> value_to_assign,
std::vector<Attribute> outer_attribs, Location locus)
: OperatorExpr (std::move (value_to_assign_to), std::move (outer_attribs),
locus),
right_expr (std::move (value_to_assign))
{}

View File

@ -11694,7 +11694,7 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_without_block ()
{
// should be expr without block
std::unique_ptr<AST::ExprWithoutBlock> expr
= parse_expr_without_block ();
= parse_expr_without_block (std::move (outer_attrs));
if (lexer.peek_token ()->get_id () == SEMICOLON)
{
@ -11739,7 +11739,7 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_without_block ()
// FIXME: old code was good until composability was required
// return parse_path_based_stmt_or_expr(std::move(outer_attrs));
std::unique_ptr<AST::ExprWithoutBlock> expr
= parse_expr_without_block ();
= parse_expr_without_block (std::move (outer_attrs));
if (lexer.peek_token ()->get_id () == SEMICOLON)
{
@ -11762,7 +11762,7 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr_without_block ()
* expression then make it statement if semi afterwards */
std::unique_ptr<AST::ExprWithoutBlock> expr
= parse_expr_without_block ();
= parse_expr_without_block (std::move (outer_attrs));
if (lexer.peek_token ()->get_id () == SEMICOLON)
{
@ -12437,7 +12437,7 @@ Parser<ManagedTokenSource>::parse_expr (int right_binding_power,
// parse null denotation (unary part of expression)
std::unique_ptr<AST::Expr> expr
= null_denotation (current_token, std::move (outer_attrs), restrictions);
= null_denotation (current_token, {}, restrictions);
if (expr == nullptr)
{
@ -12452,8 +12452,8 @@ Parser<ManagedTokenSource>::parse_expr (int right_binding_power,
current_token = lexer.peek_token ();
lexer.skip_token ();
expr = left_denotation (current_token, std::move (expr), AST::AttrVec (),
restrictions);
expr = left_denotation (current_token, std::move (expr),
std::move (outer_attrs), restrictions);
if (expr == nullptr)
{
@ -13786,7 +13786,7 @@ template <typename ManagedTokenSource>
std::unique_ptr<AST::AssignmentExpr>
Parser<ManagedTokenSource>::parse_assig_expr (
const_TokenPtr tok ATTRIBUTE_UNUSED, std::unique_ptr<AST::Expr> left,
AST::AttrVec outer_attrs ATTRIBUTE_UNUSED, ParseRestrictions restrictions)
AST::AttrVec outer_attrs, ParseRestrictions restrictions)
{
// parse RHS (as tok has already been consumed in parse_expression)
std::unique_ptr<AST::Expr> right
@ -13799,7 +13799,8 @@ Parser<ManagedTokenSource>::parse_assig_expr (
Location locus = left->get_locus ();
return std::unique_ptr<AST::AssignmentExpr> (
new AST::AssignmentExpr (std::move (left), std::move (right), locus));
new AST::AssignmentExpr (std::move (left), std::move (right),
std::move (outer_attrs), locus));
}
/* Returns the left binding power for the given CompoundAssignmentExpr type.

View File

@ -0,0 +1,13 @@
// { dg-additional-options "-w -frust-cfg=A" }
fn main() -> i32 {
let mut a = 0;
#[cfg(A)]
a = 3;
#[cfg(B)]
a = 40;
a - 3
}