From: Yap Zhi Heng <[email protected]>
GIMPLE output for literalpattern_neg.rs test case:
...
x = -55;
RUSTTMP.2 = x;
if (RUSTTMP.2 == 55) goto <D.113>; else goto <D.114>;
<D.113>:
{
RUSTTMP.1 = 1;
goto <D.107>;
}
<D.114>:
if (RUSTTMP.2 == -55) goto <D.115>; else goto <D.116>;
<D.115>:
{
RUSTTMP.1 = 0;
goto <D.107>;
}
<D.116>:
if (1 != 0) goto <D.117>; else goto <D.118>;
<D.117>:
{
RUSTTMP.1 = 1;
goto <D.107>;
}
...
gcc/rust/ChangeLog:
* parse/rust-parse-impl.h (parse_literal_or_range_pattern): Parse minus
sign
properly for LiteralPattern.
* ast/rust-pattern.h (LiteralPattern): Add has_minus boolean for
LiteralPattern.
* hir/tree/rust-hir-pattern.h (LiteralPattern): Ditto.
* ast/rust-pattern.cc (LiteralPattern::as_string): Update to include
minus sign
if present.
* hir/tree/rust-hir.cc (LiteralPattern::as_string): Ditto.
* hir/rust-ast-lower-pattern.cc (visit(LiteralPattern)): Pass has_minus
boolean
from AST to HIR.
* backend/rust-compile-pattern.cc
(CompilePatternCheckExpr::visit(LiteralPattern)):
Compile litexpr as negative if minus sign is present.
Signed-off-by: Yap Zhi Heng <[email protected]>
---
gcc/rust/ast/rust-pattern.cc | 2 +-
gcc/rust/ast/rust-pattern.h | 22 +++++++++++++++++--
gcc/rust/backend/rust-compile-pattern.cc | 2 ++
gcc/rust/hir/rust-ast-lower-pattern.cc | 3 ++-
gcc/rust/hir/tree/rust-hir-pattern.h | 14 ++++++++++--
gcc/rust/hir/tree/rust-hir.cc | 2 +-
gcc/rust/parse/rust-parse-impl.h | 2 +-
.../execute/torture/literalpattern_neg.rs | 9 ++++++++
8 files changed, 48 insertions(+), 8 deletions(-)
create mode 100644 gcc/testsuite/rust/execute/torture/literalpattern_neg.rs
diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index a2fe5d59081..80189d3746b 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -48,7 +48,7 @@ tokenid_to_rangekind (TokenId id)
std::string
LiteralPattern::as_string () const
{
- return lit.as_string ();
+ return (has_minus ? "-" : "") + lit.as_string ();
}
std::string
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 0da1981928f..3b1bd1c29ec 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -30,6 +30,7 @@ class LiteralPattern : public Pattern
Literal lit;
location_t locus;
NodeId node_id;
+ bool has_minus;
public:
std::string as_string () const override;
@@ -37,17 +38,34 @@ public:
// Constructor for a literal pattern
LiteralPattern (Literal lit, location_t locus)
: lit (std::move (lit)), locus (locus),
- node_id (Analysis::Mappings::get ().get_next_node_id ())
+ node_id (Analysis::Mappings::get ().get_next_node_id ()),
+ has_minus (false)
+ {}
+
+ LiteralPattern (Literal lit, location_t locus, bool has_minus)
+ : lit (std::move (lit)), locus (locus),
+ node_id (Analysis::Mappings::get ().get_next_node_id ()),
+ has_minus (has_minus)
{}
LiteralPattern (std::string val, Literal::LitType type, location_t locus,
PrimitiveCoreType type_hint)
: lit (Literal (std::move (val), type, type_hint)), locus (locus),
- node_id (Analysis::Mappings::get ().get_next_node_id ())
+ node_id (Analysis::Mappings::get ().get_next_node_id ()),
+ has_minus (false)
+ {}
+
+ LiteralPattern (std::string val, Literal::LitType type, location_t locus,
+ PrimitiveCoreType type_hint, bool has_minus)
+ : lit (Literal (std::move (val), type, type_hint)), locus (locus),
+ node_id (Analysis::Mappings::get ().get_next_node_id ()),
+ has_minus (has_minus)
{}
location_t get_locus () const override final { return locus; }
+ bool get_has_minus () const { return has_minus; }
+
void accept_vis (ASTVisitor &vis) override;
NodeId get_node_id () const override { return node_id; }
diff --git a/gcc/rust/backend/rust-compile-pattern.cc
b/gcc/rust/backend/rust-compile-pattern.cc
index 82333dc39c0..3a983e9bc88 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -87,6 +87,8 @@ CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
auto litexpr = std::make_unique<HIR::LiteralExpr> (
HIR::LiteralExpr (pattern.get_mappings (), pattern.get_literal (),
pattern.get_locus (), std::vector<AST::Attribute> ()));
+ if (pattern.get_has_minus ())
+ litexpr->set_negative ();
// Note: Floating point literals are currently accepted but will likely be
// forbidden in LiteralPatterns in a future version of Rust.
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc
b/gcc/rust/hir/rust-ast-lower-pattern.cc
index 4250adbfbab..c941a5c9af9 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -280,7 +280,8 @@ ASTLoweringPattern::visit (AST::LiteralPattern &pattern)
HIR::Literal l = lower_literal (pattern.get_literal ());
translated
- = new HIR::LiteralPattern (mapping, std::move (l), pattern.get_locus ());
+ = new HIR::LiteralPattern (mapping, std::move (l), pattern.get_locus (),
+ pattern.get_has_minus ());
}
void
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h
b/gcc/rust/hir/tree/rust-hir-pattern.h
index 89b9cc6a06c..a2c408fdc77 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -32,19 +32,27 @@ class LiteralPattern : public Pattern
Literal lit;
location_t locus;
Analysis::NodeMapping mappings;
+ bool has_minus;
public:
std::string as_string () const override;
// Constructor for a literal pattern
LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t
locus)
- : lit (std::move (lit)), locus (locus), mappings (mappings)
+ : lit (std::move (lit)), locus (locus), mappings (mappings),
+ has_minus (false)
+ {}
+
+ LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t
locus,
+ bool has_minus)
+ : lit (std::move (lit)), locus (locus), mappings (mappings),
+ has_minus (has_minus)
{}
LiteralPattern (Analysis::NodeMapping mappings, std::string val,
Literal::LitType type, location_t locus)
: lit (Literal (std::move (val), type, PrimitiveCoreType::CORETYPE_STR)),
- locus (locus), mappings (mappings)
+ locus (locus), mappings (mappings), has_minus (false)
{}
location_t get_locus () const override { return locus; }
@@ -65,6 +73,8 @@ public:
Literal &get_literal () { return lit; }
const Literal &get_literal () const { return lit; }
+ bool get_has_minus () const { return has_minus; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index ce10b02303c..57f560b06d3 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -2634,7 +2634,7 @@ StructPattern::as_string () const
std::string
LiteralPattern::as_string () const
{
- return lit.as_string ();
+ return (has_minus ? "-" : "") + lit.as_string ();
}
std::string
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index ec4c1c1d6c7..e7972770455 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -10345,7 +10345,7 @@
Parser<ManagedTokenSource>::parse_literal_or_range_pattern ()
return std::unique_ptr<AST::LiteralPattern> (
new AST::LiteralPattern (range_lower->get_str (), type,
range_lower->get_locus (),
- range_lower->get_type_hint ()));
+ range_lower->get_type_hint (), has_minus));
}
}
diff --git a/gcc/testsuite/rust/execute/torture/literalpattern_neg.rs
b/gcc/testsuite/rust/execute/torture/literalpattern_neg.rs
new file mode 100644
index 00000000000..3553c4a3462
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/literalpattern_neg.rs
@@ -0,0 +1,9 @@
+fn main() -> i32 {
+ let x = -55;
+
+ match x {
+ 55 => 1,
+ -55 => 0, // correct case
+ _ => 1
+ }
+}
\ No newline at end of file
--
2.50.1