aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjjasmine <tanghocle456@gmail.com>2024-06-16 21:23:21 -0700
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-17 16:35:51 +0100
commitbad8b19ced134598a2fe332f97cac8862deec615 (patch)
tree47e5c95c002645a9d66ba4afc5a465221cca8655 /gcc
parent95c31e91eab710135b684344ff088d6ba52abf41 (diff)
downloadgcc-bad8b19ced134598a2fe332f97cac8862deec615.zip
gcc-bad8b19ced134598a2fe332f97cac8862deec615.tar.gz
gcc-bad8b19ced134598a2fe332f97cac8862deec615.tar.bz2
gccrs: Added a test that is expected to fail
gcc/rust/ChangeLog: * expand/rust-macro-builtins-asm.cc (parse_clobber_abi): added comments (parse_options): Likewise (parse_asm_arg): Likewise (parse_asm): Likewise * expand/rust-macro-builtins-asm.h: Likewise gcc/testsuite/ChangeLog: * rust/compile/inline_asm_illegal_options.rs: new test * rust/compile/inline_asm_illegal_operands.rs: New test. This is expected to fail but we couldn't resolve parse_expr()'s general functionality yet Signed-off-by: badumbatish <tanghocle456@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.cc51
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.h14
-rw-r--r--gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs24
-rw-r--r--gcc/testsuite/rust/compile/inline_asm_illegal_options.rs2
4 files changed, 60 insertions, 31 deletions
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 05d8f86..dbbe0fa 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -49,8 +49,6 @@ parse_clobber_abi (InlineAsmContext inline_asm_ctx)
auto token = parser.peek_current_token ();
if (!parser.skip_token (LEFT_PAREN))
{
- // TODO: Raise error exactly like rustc if left parenthesis is not
- // encountered.
token = parser.peek_current_token ();
// TODO: Error reporting shifted to the left 1 character, I'm not sure
@@ -71,8 +69,6 @@ parse_clobber_abi (InlineAsmContext inline_asm_ctx)
if (parser.skip_token (RIGHT_PAREN))
{
- // TODO: We encountered a "clobber_abi()", which should be illegal?
- // https://github.com/rust-lang/rust/blob/c00957a3e269219413041a4e3565f33b1f9d0779/compiler/rustc_builtin_macros/src/asm.rs#L381
rust_error_at (
parser.peek_current_token ()->get_locus (),
"at least one abi must be provided as an argument to %<clobber_abi%>");
@@ -491,9 +487,9 @@ parse_options (InlineAsmContext &inline_asm_ctx)
// Parse everything commitedly
if (!parser.skip_token (LEFT_PAREN))
{
- // We have shifted `options` to search for the left parenthesis next, we
- // should error out if this is not possible.
- // TODO: report some error.
+ auto local_token = parser.peek_current_token ();
+ rust_error_at (local_token->get_locus (), "expected %qs, found %qs", "(",
+ local_token->as_string ().c_str ());
return tl::unexpected<InlineAsmParseError> (COMMITTED);
}
@@ -538,7 +534,6 @@ parse_options (InlineAsmContext &inline_asm_ctx)
}
else
{
- // TODO: Unexpected error, please return the correct error
rust_error_at (token->get_locus (),
"expected one of %qs, %qs, %qs, %qs, %qs, %qs, %qs, "
"%qs, %qs, or %qs, found %qs",
@@ -562,7 +557,6 @@ parse_options (InlineAsmContext &inline_asm_ctx)
rust_unreachable ();
token = parser.peek_current_token ();
return tl::unexpected<InlineAsmParseError> (COMMITTED);
- ;
}
}
@@ -678,34 +672,45 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
// 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
+ // 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;
+ // The error type is definitely non-committed (we have checked above),
+ // we are allowed to keep on parsing
}
- // TODO: Parse options
if (check_identifier (parser, "options"))
{
auto expected = parse_options (inline_asm_ctx);
if (expected || expected.error () == COMMITTED)
return expected;
- continue;
+ // The error type is definitely non-committed (we have checked above),
+ // we are allowed to keep on parsing
}
// 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;
+
+ // Since parse_reg_operand is the last thing we've considered,
+ // The non-committed parse error type means that we have exhausted our
+ // search path
+
+ // We then should return the error of COMMITTED, even though we have not
+ // committed to anything So that the error bubbles up and we recover from
+ // this error gracefully
+ rust_error_at (token->get_locus (),
+ "expected operand, clobber_abi, options, or additional "
+ "template string");
+ return tl::unexpected<InlineAsmParseError> (COMMITTED);
}
return tl::expected<InlineAsmContext, InlineAsmParseError> (inline_asm_ctx);
}
@@ -715,19 +720,12 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
AST::InvocKind semicolon, AST::AsmKind is_global_asm)
{
// From the rule of asm.
- // We first peek and see if it is a format string or not.
- // If yes, we process the first ever format string, and move on to the
- // recurrent of format string Else we exit out
-
- // After that, we peek and see if it is a reoccuring stream of format string
- // or not. If it is, keep on going to do this format string. Else, move on
+ // We first parse all formatted strings. If we fail, then we return
+ // tl::nullopt
- // After that, we peek and see if it is a reoccuring stream of operands or not
- // If it is, keep on going to do this operand thingy.
- // Else, move on
+ // We then parse the asm arguments. If we fail, then we return tl::nullopt
- // We check if there is an optional "," at the end, per ABNF spec.
- // If it is, consume it.
+ // We then validate. If we fail, then we return tl::nullopt
// Done
MacroInvocLexer lex (invoc.get_delim_tok_tree ().to_token_stream ());
@@ -738,7 +736,6 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
is_global_asm == AST::AsmKind::Global);
auto inline_asm_ctx = InlineAsmContext (inline_asm, parser, last_token_id);
- // operands stream, also handles the optional ","
tl::expected<InlineAsmContext, InlineAsmParseError> resulting_context
= tl::expected<InlineAsmContext, InlineAsmParseError> (inline_asm_ctx);
resulting_context.and_then (parse_format_strings)
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h b/gcc/rust/expand/rust-macro-builtins-asm.h
index 201f807..32a8d0b 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -6,11 +6,19 @@
#include "rust-macro-invoc-lexer.h"
#include "rust/ast/rust-expr.h"
namespace Rust {
-// All the operands are called asm_args in rustc asm.rs, we create a struct that
-// can store all of these AsmArgs This replaces the phase where we have to parse
-// all operands.
+
enum InlineAsmParseError
{
+ // Enum for InlineAsmParseError
+
+ // Currently with two error, COMMITTED AND NONCOMMITTED (to a token),
+ // which directs the parser to either bubbles the error up, or keep on going
+ // (vertical or horizontal)
+
+ // COMMITTED can be use as a way for parser to bubble up
+ // after it has exhausted its search space despite it not having committed to
+ // any token
+
COMMITTED,
NONCOMMITED,
};
diff --git a/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs b/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs
new file mode 100644
index 0000000..5a13fb9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_illegal_operands.rs
@@ -0,0 +1,24 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+ () => {}
+}
+
+fn main() {
+ let mut _x: u64 = 4;
+ unsafe {
+ asm!(
+ "add {x}, {1}",
+ x = in(reg) _x,
+ x = in(reg) _x, // { dg-error {duplicate argument named 'x'} "" { xfail *-*-* } .-1 }
+ );
+
+ asm!(
+ "mov {x}, {x}",
+ x = inout("eax") _x, // { dg-error {explicit register arguments cannot have names} "" { xfail *-*-* } .-1 }
+ x = inout(reg) _x, // It then proceeds to parse this line, resulting in only 1 error instead of duplication error as well.
+ );
+ }
+ _x = 1;
+} \ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/inline_asm_illegal_options.rs b/gcc/testsuite/rust/compile/inline_asm_illegal_options.rs
index 2cf354d..ef54641 100644
--- a/gcc/testsuite/rust/compile/inline_asm_illegal_options.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_illegal_options.rs
@@ -11,6 +11,6 @@ fn main() {
asm!("nop", options(noreturn, noreturn)); // { dg-error "the 'noreturn' option was already provided" }
asm!("nop", options(xxx)); // { dg-error "expected one of '\\)', 'att_syntax', 'may_unwind', 'nomem', 'noreturn', 'nostack', 'preserves_flags', 'pure', 'raw', or 'readonly', found 'xxx'" }
asm!("nop", options(+)); // { dg-error "expected one of '\\)', 'att_syntax', 'may_unwind', 'nomem', 'noreturn', 'nostack', 'preserves_flags', 'pure', 'raw', or 'readonly', found '\\+'" }
-
+ asm!("nop", options+); // { dg-error "expected '\\(', found '\\+'" }
}
} \ No newline at end of file