public inbox for gcc-rust@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Reject non-pure decimal tuple indexes.
@ 2021-06-25 17:57 Mark Wielaard
  2021-06-25 20:01 ` Mark Wielaard
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Wielaard @ 2021-06-25 17:57 UTC (permalink / raw)
  To: gcc-rust; +Cc: Mark Wielaard

Tuple indexes should be pure decimal integer literals. But the parser just sees an
integer literal. Fix this by introducing a new type hint CORETYPE_PURE_DECIMAL. This
doesn't conflict with any existing type hints since a pure decimal doesn't have a
type suffix.

Introduce a new method is_pure_decimal that the parser can use in parse_tuple_index_expr.
get_type_hint will return CORETYPE_UNKNOWN for pure decimals.

parse_decimal_int_or_float will check whether there are no execissive leading zeros.
parse_in_decimal checks the literal doesn't contain any underscores.

Add two testcases. bad_tuple_index.rs with all variants of integer literals which aren't
pure decimals. And tuple_index.rs with various correct tuple indexes.

Resolves: https://github.com/Rust-GCC/gccrs/issues/511
---
 gcc/rust/lex/rust-lex.cc                      | 33 ++++++----
 gcc/rust/lex/rust-lex.h                       |  2 +-
 gcc/rust/lex/rust-token.cc                    |  2 +
 gcc/rust/lex/rust-token.h                     | 14 +++-
 gcc/rust/parse/rust-parse-impl.h              |  6 ++
 gcc/testsuite/rust/compile/bad_tuple_index.rs | 66 +++++++++++++++++++
 .../rust/compile/torture/tuple_index.rs       | 32 +++++++++
 7 files changed, 142 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/bad_tuple_index.rs
 create mode 100644 gcc/testsuite/rust/compile/torture/tuple_index.rs

diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index b320401e3bb..860ac9f95f8 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -942,23 +942,26 @@ Lexer::parse_in_exponent_part ()
 	}
 
       // parse another decimal number for exponent
-      auto str_length_pair = parse_in_decimal ();
-      str += str_length_pair.first;
-      additional_length_offset += str_length_pair.second;
+      auto str_length = parse_in_decimal ();
+      str += std::get<0>(str_length);
+      additional_length_offset += std::get<1>(str_length);
     }
   return std::make_pair (str, additional_length_offset);
 }
 
 // Parses a decimal integer.
-std::pair<std::string, int>
+std::tuple<std::string, int, bool>
 Lexer::parse_in_decimal ()
 {
+  /* A pure decimal contains only digits.  */
+  bool pure_decimal = true;
   int additional_length_offset = 0;
   std::string str;
   while (ISDIGIT (current_char) || current_char == '_')
     {
       if (current_char == '_')
 	{
+	  pure_decimal = false;
 	  // don't add _ to number
 	  skip_input ();
 	  current_char = peek_input ();
@@ -974,7 +977,7 @@ Lexer::parse_in_decimal ()
       skip_input ();
       current_char = peek_input ();
     }
-  return std::make_pair (str, additional_length_offset);
+  return std::make_tuple (str, additional_length_offset, pure_decimal);
 }
 
 /* Parses escapes (and string continues) in "byte" strings and characters. Does
@@ -1842,13 +1845,14 @@ Lexer::parse_decimal_int_or_float (Location loc)
   str += current_char;
 
   int length = 1;
+  bool first_zero = current_char == '0';
 
   current_char = peek_input ();
 
   // parse initial decimal integer (or first integer part of float) literal
-  auto initial_decimal_pair = parse_in_decimal ();
-  str += initial_decimal_pair.first;
-  length += initial_decimal_pair.second;
+  auto initial_decimal = parse_in_decimal ();
+  str += std::get<0>(initial_decimal);
+  length += std::get<1>(initial_decimal);
 
   // detect float literal
   if (current_char == '.' && is_float_digit (peek_input (1)))
@@ -1862,9 +1866,9 @@ Lexer::parse_decimal_int_or_float (Location loc)
       length++;
 
       // parse another decimal number for float
-      auto second_decimal_pair = parse_in_decimal ();
-      str += second_decimal_pair.first;
-      length += second_decimal_pair.second;
+      auto second_decimal = parse_in_decimal ();
+      str += std::get<0>(second_decimal);
+      length += std::get<1>(second_decimal);
 
       // parse in exponent part if it exists
       auto exponent_pair = parse_in_exponent_part ();
@@ -1947,6 +1951,13 @@ Lexer::parse_decimal_int_or_float (Location loc)
       // parse in type suffix if it exists
       auto type_suffix_pair = parse_in_type_suffix ();
       PrimitiveCoreType type_hint = type_suffix_pair.first;
+      /* A "real" pure decimal doesn't have a suffix and no zero prefix.  */
+      if (type_hint == CORETYPE_UNKNOWN)
+	{
+	  bool pure_decimal = std::get<2>(initial_decimal);
+	  if (pure_decimal && (!first_zero || str.size() == 1))
+	    type_hint = CORETYPE_PURE_DECIMAL;
+	}
       length += type_suffix_pair.second;
 
       current_column += length;
diff --git a/gcc/rust/lex/rust-lex.h b/gcc/rust/lex/rust-lex.h
index ba37c63416d..902745fa1d5 100644
--- a/gcc/rust/lex/rust-lex.h
+++ b/gcc/rust/lex/rust-lex.h
@@ -71,7 +71,7 @@ private:
   // Builds a token from the input queue.
   TokenPtr build_token ();
 
-  std::pair<std::string, int> parse_in_decimal ();
+  std::tuple<std::string, int, bool> parse_in_decimal ();
   std::pair<std::string, int> parse_in_exponent_part ();
   std::pair<PrimitiveCoreType, int> parse_in_type_suffix ();
   std::tuple<char, int, bool> parse_escape (char opening_char);
diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc
index 7b5a305bbea..317416cb349 100644
--- a/gcc/rust/lex/rust-token.cc
+++ b/gcc/rust/lex/rust-token.cc
@@ -99,6 +99,8 @@ get_type_hint_string (PrimitiveCoreType type)
       return "u64";
     case CORETYPE_U128:
       return "u128";
+    case CORETYPE_PURE_DECIMAL:
+      return "pure_decimal";
     case CORETYPE_UNKNOWN:
     default:
       return "unknown";
diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h
index e8d5519e22a..f5ab0b75afb 100644
--- a/gcc/rust/lex/rust-token.h
+++ b/gcc/rust/lex/rust-token.h
@@ -57,6 +57,9 @@ enum PrimitiveCoreType
   CORETYPE_U32,
   CORETYPE_U64,
   CORETYPE_U128,
+  // Pure decimals are used for tuple index.
+  // Also means there is no type hint.
+  CORETYPE_PURE_DECIMAL,
   // arch-dependent pointer sizes
   CORETYPE_ISIZE = CORETYPE_INT,
   CORETYPE_USIZE = CORETYPE_UINT
@@ -391,7 +394,10 @@ return *str;
 }*/
 
   // Gets token's type hint info.
-  PrimitiveCoreType get_type_hint () const { return type_hint; }
+  PrimitiveCoreType get_type_hint () const
+  {
+    return type_hint == CORETYPE_PURE_DECIMAL ? CORETYPE_UNKNOWN : type_hint;
+  }
 
   // diagnostics (error reporting)
   const char *get_token_description () const
@@ -435,6 +441,12 @@ return *str;
   {
     return is_literal () || token_id == IDENTIFIER || token_id == LIFETIME;
   }
+
+  // Returns whether the token is a pure decimal int literal
+  bool is_pure_decimal () const
+  {
+    return type_hint == CORETYPE_PURE_DECIMAL;
+  }
 };
 } // namespace Rust
 
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 9a28f6cdb66..014beaf9e9c 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -14083,6 +14083,12 @@ Parser<ManagedTokenSource>::parse_tuple_index_expr (
   std::string index = index_tok->get_str ();
 
   // convert to integer
+  if (!index_tok->is_pure_decimal ())
+    {
+      Error error (index_tok->get_locus (),
+		   "tuple index should be a pure decimal literal");
+      add_error (std::move (error));
+    }
   int index_int = atoi (index.c_str ());
 
   Location locus = tuple_expr->get_locus_slow ();
diff --git a/gcc/testsuite/rust/compile/bad_tuple_index.rs b/gcc/testsuite/rust/compile/bad_tuple_index.rs
new file mode 100644
index 00000000000..c3bd1e91d10
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_tuple_index.rs
@@ -0,0 +1,66 @@
+fn main()
+{
+  // tuples
+  let z = ();
+
+  let o = (0,);
+  /* Binary, Octal and Hex literals are invalid.  */
+  let _fb = o.0b0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fo = o.0o0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fh = o.0x0; // { dg-error "tuple index should be a pure decimal literal" }
+
+  /* No underscores.  */
+  let _fua = o.0_; // { dg-error "tuple index should be a pure decimal literal" }
+
+  /* Suffix is not allowed.  */
+  let _fu8 = o.0u8; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi8 = o.0i8; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu16 = o.0u16; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi16 = o.0i16; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu32 = o.0u32; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi32 = o.0i32; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu64 = o.0u64; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi64 = o.0i64; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu128 = o.0u128; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi128 = o.0i128; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fusize = o.0usize; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fisize = o.0isize; // { dg-error "tuple index should be a pure decimal literal" }
+
+  let t = (0,1);
+  /* No extra zero prefix.  */
+  let _s = t.01; // { dg-error "tuple index should be a pure decimal literal" }
+
+  let m = (0,1,2,3,4,5,6,7,8,9,10);
+  /* No extra zero prefix.  */
+  let _l = m.010; // { dg-error "tuple index should be a pure decimal literal" }
+
+  /* No underscores.  */
+  let _lu = m.1_0; // { dg-error "tuple index should be a pure decimal literal" }
+
+  // tuple structs
+  struct E();
+  let _e = E();
+
+  struct O(i32);
+  let so = O(0);
+  /* No leading zeros, no underscores.  */
+  let _sf = so.0_0; // { dg-error "tuple index should be a pure decimal literal" }
+  /* Binary, Octal and Hex literals are invalid.  */
+  let _sb = so.0b0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _so = so.0o0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _sh = so.0x0; // { dg-error "tuple index should be a pure decimal literal" }
+
+  struct T(i32,i32);
+  let st = T(0,1);
+  /* Suffix is not allowed.  */
+  let _stfu32 = st.1u32; // { dg-error "tuple index should be a pure decimal literal" }
+  let _stfi32 = st.1i32; // { dg-error "tuple index should be a pure decimal literal" }
+
+  struct M(i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32);
+  let sm = M(0,1,2,3,4,5,6,7,8,9,10);
+  /* No underscores. */
+  let _sl2 = sm.1_0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _sl3 = sm.10_; // { dg-error "tuple index should be a pure decimal literal" }
+
+  z
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple_index.rs b/gcc/testsuite/rust/compile/torture/tuple_index.rs
new file mode 100644
index 00000000000..f904fae9b5b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple_index.rs
@@ -0,0 +1,32 @@
+fn main()
+{
+  // tuples
+  let z = ();
+
+  let o = (0,);
+  let _f = o.0;
+
+  let t = (0,1);
+  let _s = t.1;
+
+  let m = (0,1,2,3,4,5,6,7,8,9,10);
+  let _l = m.10;
+
+  // tuple structs
+  struct E();
+  let _e = E();
+
+  struct O(i32);
+  let so = O(0);
+  let _sf = so.0;
+
+  struct T(i32,i32);
+  let st = T(0,1);
+  let _fs = st.1;
+
+  struct M(i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32);
+  let sm = M(0,1,2,3,4,5,6,7,8,9,10);
+  let _sl = sm.10;
+
+  z
+}
-- 
2.32.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Reject non-pure decimal tuple indexes.
  2021-06-25 17:57 [PATCH] Reject non-pure decimal tuple indexes Mark Wielaard
@ 2021-06-25 20:01 ` Mark Wielaard
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Wielaard @ 2021-06-25 20:01 UTC (permalink / raw)
  To: gcc-rust

[-- Attachment #1: Type: text/plain, Size: 185 bytes --]

Hi,

Attached is a slightly updated version for some whitespace issues.
There are spaces after the std::get<i> and the is_pure_decimal
function is now fully on one line.

Cheers,

Mark

[-- Attachment #2: 0001-Reject-non-pure-decimal-tuple-indexes.patch --]
[-- Type: text/x-diff, Size: 11556 bytes --]

From 60cb8cc43b91ff8a00be45be1106f95f161e9c8d Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Fri, 25 Jun 2021 19:37:11 +0200
Subject: [PATCH] Reject non-pure decimal tuple indexes.

Tuple indexes should be pure decimal integer literals. But the parser just sees an
integer literal. Fix this by introducing a new type hint CORETYPE_PURE_DECIMAL. This
doesn't conflict with any existing type hints since a pure decimal doesn't have a
type suffix.

Introduce a new method is_pure_decimal that the parser can use in parse_tuple_index_expr.
get_type_hint will return CORETYPE_UNKNOWN for pure decimals.

parse_decimal_int_or_float will check whether there are no execissive leading zeros.
parse_in_decimal checks the literal doesn't contain any underscores.

Add two testcases. bad_tuple_index.rs with all variants of integer literals which aren't
pure decimals. And tuple_index.rs with various correct tuple indexes.

Resolves: https://github.com/Rust-GCC/gccrs/issues/511
---
 gcc/rust/lex/rust-lex.cc                      | 33 ++++++----
 gcc/rust/lex/rust-lex.h                       |  2 +-
 gcc/rust/lex/rust-token.cc                    |  2 +
 gcc/rust/lex/rust-token.h                     | 11 +++-
 gcc/rust/parse/rust-parse-impl.h              |  6 ++
 gcc/testsuite/rust/compile/bad_tuple_index.rs | 66 +++++++++++++++++++
 .../rust/compile/torture/tuple_index.rs       | 32 +++++++++
 7 files changed, 139 insertions(+), 13 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/bad_tuple_index.rs
 create mode 100644 gcc/testsuite/rust/compile/torture/tuple_index.rs

diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index b320401e3bb..d1384168731 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -942,23 +942,26 @@ Lexer::parse_in_exponent_part ()
 	}
 
       // parse another decimal number for exponent
-      auto str_length_pair = parse_in_decimal ();
-      str += str_length_pair.first;
-      additional_length_offset += str_length_pair.second;
+      auto str_length = parse_in_decimal ();
+      str += std::get<0> (str_length);
+      additional_length_offset += std::get<1> (str_length);
     }
   return std::make_pair (str, additional_length_offset);
 }
 
 // Parses a decimal integer.
-std::pair<std::string, int>
+std::tuple<std::string, int, bool>
 Lexer::parse_in_decimal ()
 {
+  /* A pure decimal contains only digits.  */
+  bool pure_decimal = true;
   int additional_length_offset = 0;
   std::string str;
   while (ISDIGIT (current_char) || current_char == '_')
     {
       if (current_char == '_')
 	{
+	  pure_decimal = false;
 	  // don't add _ to number
 	  skip_input ();
 	  current_char = peek_input ();
@@ -974,7 +977,7 @@ Lexer::parse_in_decimal ()
       skip_input ();
       current_char = peek_input ();
     }
-  return std::make_pair (str, additional_length_offset);
+  return std::make_tuple (str, additional_length_offset, pure_decimal);
 }
 
 /* Parses escapes (and string continues) in "byte" strings and characters. Does
@@ -1842,13 +1845,14 @@ Lexer::parse_decimal_int_or_float (Location loc)
   str += current_char;
 
   int length = 1;
+  bool first_zero = current_char == '0';
 
   current_char = peek_input ();
 
   // parse initial decimal integer (or first integer part of float) literal
-  auto initial_decimal_pair = parse_in_decimal ();
-  str += initial_decimal_pair.first;
-  length += initial_decimal_pair.second;
+  auto initial_decimal = parse_in_decimal ();
+  str += std::get<0> (initial_decimal);
+  length += std::get<1> (initial_decimal);
 
   // detect float literal
   if (current_char == '.' && is_float_digit (peek_input (1)))
@@ -1862,9 +1866,9 @@ Lexer::parse_decimal_int_or_float (Location loc)
       length++;
 
       // parse another decimal number for float
-      auto second_decimal_pair = parse_in_decimal ();
-      str += second_decimal_pair.first;
-      length += second_decimal_pair.second;
+      auto second_decimal = parse_in_decimal ();
+      str += std::get<0> (second_decimal);
+      length += std::get<1> (second_decimal);
 
       // parse in exponent part if it exists
       auto exponent_pair = parse_in_exponent_part ();
@@ -1947,6 +1951,13 @@ Lexer::parse_decimal_int_or_float (Location loc)
       // parse in type suffix if it exists
       auto type_suffix_pair = parse_in_type_suffix ();
       PrimitiveCoreType type_hint = type_suffix_pair.first;
+      /* A "real" pure decimal doesn't have a suffix and no zero prefix.  */
+      if (type_hint == CORETYPE_UNKNOWN)
+	{
+	  bool pure_decimal = std::get<2> (initial_decimal);
+	  if (pure_decimal && (!first_zero || str.size () == 1))
+	    type_hint = CORETYPE_PURE_DECIMAL;
+	}
       length += type_suffix_pair.second;
 
       current_column += length;
diff --git a/gcc/rust/lex/rust-lex.h b/gcc/rust/lex/rust-lex.h
index ba37c63416d..902745fa1d5 100644
--- a/gcc/rust/lex/rust-lex.h
+++ b/gcc/rust/lex/rust-lex.h
@@ -71,7 +71,7 @@ private:
   // Builds a token from the input queue.
   TokenPtr build_token ();
 
-  std::pair<std::string, int> parse_in_decimal ();
+  std::tuple<std::string, int, bool> parse_in_decimal ();
   std::pair<std::string, int> parse_in_exponent_part ();
   std::pair<PrimitiveCoreType, int> parse_in_type_suffix ();
   std::tuple<char, int, bool> parse_escape (char opening_char);
diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc
index 7b5a305bbea..317416cb349 100644
--- a/gcc/rust/lex/rust-token.cc
+++ b/gcc/rust/lex/rust-token.cc
@@ -99,6 +99,8 @@ get_type_hint_string (PrimitiveCoreType type)
       return "u64";
     case CORETYPE_U128:
       return "u128";
+    case CORETYPE_PURE_DECIMAL:
+      return "pure_decimal";
     case CORETYPE_UNKNOWN:
     default:
       return "unknown";
diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h
index e8d5519e22a..771910119b7 100644
--- a/gcc/rust/lex/rust-token.h
+++ b/gcc/rust/lex/rust-token.h
@@ -57,6 +57,9 @@ enum PrimitiveCoreType
   CORETYPE_U32,
   CORETYPE_U64,
   CORETYPE_U128,
+  // Pure decimals are used for tuple index.
+  // Also means there is no type hint.
+  CORETYPE_PURE_DECIMAL,
   // arch-dependent pointer sizes
   CORETYPE_ISIZE = CORETYPE_INT,
   CORETYPE_USIZE = CORETYPE_UINT
@@ -391,7 +394,10 @@ return *str;
 }*/
 
   // Gets token's type hint info.
-  PrimitiveCoreType get_type_hint () const { return type_hint; }
+  PrimitiveCoreType get_type_hint () const
+  {
+    return type_hint == CORETYPE_PURE_DECIMAL ? CORETYPE_UNKNOWN : type_hint;
+  }
 
   // diagnostics (error reporting)
   const char *get_token_description () const
@@ -435,6 +441,9 @@ return *str;
   {
     return is_literal () || token_id == IDENTIFIER || token_id == LIFETIME;
   }
+
+  // Returns whether the token is a pure decimal int literal
+  bool is_pure_decimal () const { return type_hint == CORETYPE_PURE_DECIMAL; }
 };
 } // namespace Rust
 
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 9a28f6cdb66..014beaf9e9c 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -14083,6 +14083,12 @@ Parser<ManagedTokenSource>::parse_tuple_index_expr (
   std::string index = index_tok->get_str ();
 
   // convert to integer
+  if (!index_tok->is_pure_decimal ())
+    {
+      Error error (index_tok->get_locus (),
+		   "tuple index should be a pure decimal literal");
+      add_error (std::move (error));
+    }
   int index_int = atoi (index.c_str ());
 
   Location locus = tuple_expr->get_locus_slow ();
diff --git a/gcc/testsuite/rust/compile/bad_tuple_index.rs b/gcc/testsuite/rust/compile/bad_tuple_index.rs
new file mode 100644
index 00000000000..c3bd1e91d10
--- /dev/null
+++ b/gcc/testsuite/rust/compile/bad_tuple_index.rs
@@ -0,0 +1,66 @@
+fn main()
+{
+  // tuples
+  let z = ();
+
+  let o = (0,);
+  /* Binary, Octal and Hex literals are invalid.  */
+  let _fb = o.0b0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fo = o.0o0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fh = o.0x0; // { dg-error "tuple index should be a pure decimal literal" }
+
+  /* No underscores.  */
+  let _fua = o.0_; // { dg-error "tuple index should be a pure decimal literal" }
+
+  /* Suffix is not allowed.  */
+  let _fu8 = o.0u8; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi8 = o.0i8; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu16 = o.0u16; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi16 = o.0i16; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu32 = o.0u32; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi32 = o.0i32; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu64 = o.0u64; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi64 = o.0i64; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fu128 = o.0u128; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fi128 = o.0i128; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fusize = o.0usize; // { dg-error "tuple index should be a pure decimal literal" }
+  let _fisize = o.0isize; // { dg-error "tuple index should be a pure decimal literal" }
+
+  let t = (0,1);
+  /* No extra zero prefix.  */
+  let _s = t.01; // { dg-error "tuple index should be a pure decimal literal" }
+
+  let m = (0,1,2,3,4,5,6,7,8,9,10);
+  /* No extra zero prefix.  */
+  let _l = m.010; // { dg-error "tuple index should be a pure decimal literal" }
+
+  /* No underscores.  */
+  let _lu = m.1_0; // { dg-error "tuple index should be a pure decimal literal" }
+
+  // tuple structs
+  struct E();
+  let _e = E();
+
+  struct O(i32);
+  let so = O(0);
+  /* No leading zeros, no underscores.  */
+  let _sf = so.0_0; // { dg-error "tuple index should be a pure decimal literal" }
+  /* Binary, Octal and Hex literals are invalid.  */
+  let _sb = so.0b0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _so = so.0o0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _sh = so.0x0; // { dg-error "tuple index should be a pure decimal literal" }
+
+  struct T(i32,i32);
+  let st = T(0,1);
+  /* Suffix is not allowed.  */
+  let _stfu32 = st.1u32; // { dg-error "tuple index should be a pure decimal literal" }
+  let _stfi32 = st.1i32; // { dg-error "tuple index should be a pure decimal literal" }
+
+  struct M(i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32);
+  let sm = M(0,1,2,3,4,5,6,7,8,9,10);
+  /* No underscores. */
+  let _sl2 = sm.1_0; // { dg-error "tuple index should be a pure decimal literal" }
+  let _sl3 = sm.10_; // { dg-error "tuple index should be a pure decimal literal" }
+
+  z
+}
diff --git a/gcc/testsuite/rust/compile/torture/tuple_index.rs b/gcc/testsuite/rust/compile/torture/tuple_index.rs
new file mode 100644
index 00000000000..f904fae9b5b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/tuple_index.rs
@@ -0,0 +1,32 @@
+fn main()
+{
+  // tuples
+  let z = ();
+
+  let o = (0,);
+  let _f = o.0;
+
+  let t = (0,1);
+  let _s = t.1;
+
+  let m = (0,1,2,3,4,5,6,7,8,9,10);
+  let _l = m.10;
+
+  // tuple structs
+  struct E();
+  let _e = E();
+
+  struct O(i32);
+  let so = O(0);
+  let _sf = so.0;
+
+  struct T(i32,i32);
+  let st = T(0,1);
+  let _fs = st.1;
+
+  struct M(i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32);
+  let sm = M(0,1,2,3,4,5,6,7,8,9,10);
+  let _sl = sm.10;
+
+  z
+}
-- 
2.32.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-06-25 20:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-25 17:57 [PATCH] Reject non-pure decimal tuple indexes Mark Wielaard
2021-06-25 20:01 ` Mark Wielaard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).