Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asm! macro failed to exhaustively parse all of options(), clobber_abis() and register operands #3057

Open
badumbatish opened this issue Jun 18, 2024 · 0 comments

Comments

@badumbatish
Copy link
Contributor

Current implementation of asm! macro will fail to exhaustively parse all of options(), clobber_abis() and register operands.

For example,

In parsing this,

fn main() {
    unsafe {
        asm!("nop", options(nomem), options(nomem));
    }
}

instead of

fn main() {
    unsafe {
        asm!("nop", options(nomem, nomem),);
    }
}

The asm! macro won't error out the duplication error since after the first options, it bubbles up to the first layer.

Here in parse_asm_arg(), when the parser successfully parses clobber_abi or options, it returns to the first layer right away instead of parsing until it have converged to a NON_COMMITTED after all paths have been taken.

token = parser.peek_current_token ();
      if (token->get_id () == COMMA && token->get_id () == last_token_id)
	{
	  parser.skip_token ();
	  break;
	}

      // Ok after the left paren is good, we better be parsing correctly
      // everything in here, which is operand in ABNF

      // TODO: Parse clobber abi, eat the identifier named "clobber_abi" if true
      if (check_identifier (parser, "clobber_abi"))
	{
	  auto expected = parse_clobber_abi (inline_asm_ctx);
	  if (expected || expected.error () == COMMITTED)
	    return expected;

	  continue;
	}

      // TODO: Parse options
      if (check_identifier (parser, "options"))
	{
	  auto expected = parse_options (inline_asm_ctx);
	  if (expected || expected.error () == COMMITTED)
	    return expected;

	  continue;
	}

      // Ok after we have check that neither clobber_abi nor options works, the
      // only other logical choice is reg_operand
      // std::cout << "reg_operand" << std::endl;

      // TODO: BUBBLE UP THIS EXPECTED(...)
      auto expected = parse_reg_operand (inline_asm_ctx);
      if (expected || expected.error () == COMMITTED)
	return expected;

To enlighten the second point, another case that might happen is that the parser have exhausted all the path, and since every path returns a NONCOMMITTED error, this means that no tokens have been consumed, and the while loop will keep on looping forever.

For the 2nd case it is advised to add an rust_unreachable() in fixing the parser.

The issue is first mentioned in #3053

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants