From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by sourceware.org (Postfix) with ESMTPS id E1EEF384F027; Wed, 24 Aug 2022 12:00:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E1EEF384F027 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=googlemail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=googlemail.com Received: by mail-wr1-x429.google.com with SMTP id bs25so20503508wrb.2; Wed, 24 Aug 2022 05:00:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20210112; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc; bh=ToySAx65SIKAJDX8LQ2D5Y+sKCaHzlfNDg4SctYvC5k=; b=CXbQUZTB0Irw7HqofvirUJJepvRUK/+KUekst7Gqn90XrulVV+eIamiroNqz3Hnj2J SR8uQQFM4HA0ePmu32v+Dan7wVbqntnjb/qlElfYNB1aCNDPqwx7QpIYor8lXlZjaaWd UNywJoyHZT0yhaxy2cs7uOJh4+bAYGccpETkeVgbPgNSYR3tcBkbwK9oIrDnn5VzhtuA yBhf47B12wQTmrMC7nouc73j8BkuWVTKFHEtnc1k2iY/tGdrzySAbG17SnrneSnvLj3C w8+IUhDPIP2A4WHgJpagelfdpGNYFpPeABLqR6rY1riU3fL3bWrA4XnEGSjtp/fs9jhN pQVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc; bh=ToySAx65SIKAJDX8LQ2D5Y+sKCaHzlfNDg4SctYvC5k=; b=k+T6ifij51bCcKnVENY6dct08Mz/g51lgJx+VlG8YpuE9aW/3ZMk6DE5VRgODMKtmp +oam/qx3zkcHWEQ5w2Dg+Wi0dxiQ+4sXmRhgnl+yzMd+qL80yc4Ud8vdtK8cc2AN1P+c ODiI2/KltkXgGvyzKahuMu99/vTGJZjKtBGdhNcaB6AluzHCFu8+Z8wrJ4Vxb7l02GsY M5K1gDB8aui6uxiRtwk/wGAava6ponOfyEElZJuklc4OAjnbzqhZkXTkoFyuNrOTOReU /V5TeC15fwDM4qThh5sXAsh5Q0V2kW4uX5ZMBFGfhCRU4BMevI7A5aJvu2OTO0kVrXNN WZcw== X-Gm-Message-State: ACgBeo0N6Ra4fkXO6cQ/62ra3q97OD8Xq+KHhcZGipPdR1nHZFPkyBz+ SaGQyAV5A1ImT/fjaB0BzAk68V9dHqM= X-Google-Smtp-Source: AA6agR47rHWn1kt8WmWZhXpCgU5uCJgKSBRkQ1xzlRSaTIy56/jAsRLhpgoqyzG79oiFBv1NaTyCvA== X-Received: by 2002:a5d:6a50:0:b0:225:5dd6:873f with SMTP id t16-20020a5d6a50000000b002255dd6873fmr6497346wrw.101.1661342433777; Wed, 24 Aug 2022 05:00:33 -0700 (PDT) Received: from localhost.localdomain ([86.14.124.218]) by smtp.gmail.com with ESMTPSA id cc19-20020a5d5c13000000b0022571d43d32sm1697676wrb.21.2022.08.24.05.00.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Aug 2022 05:00:33 -0700 (PDT) From: herron.philip@googlemail.com X-Google-Original-From: philip.herron@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Philip Herron , Arthur Cohen , Thomas Schwinge , Mark Wielaard , =?UTF-8?q?Marc=20Poulhi=C3=A8s?= Subject: [PATCH Rust front-end v2 06/37] gccrs: Add execution test cases Date: Wed, 24 Aug 2022 12:59:25 +0100 Message-Id: <20220824115956.737931-7-philip.herron@embecosm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220824115956.737931-1-philip.herron@embecosm.com> References: <20220824115956.737931-1-philip.herron@embecosm.com> Reply-To: philip.herron@embecosm.com MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Philip Herron This is similar to the compile/torture/*.rs test cases but all of these are dg-execute testcases so they get compiled, linked and executed by default, all the while being compiled with the matrix of torture options. The only caveat here is that currently gccrs does not currently support the main shim yet so we have a C-style main function here returning zero which is not supported in Rustc. Co-authored-by: Arthur Cohen Co-authored-by: Thomas Schwinge Co-authored-by: Mark Wielaard Co-authored-by: Marc Poulhiès --- .../rust/execute/torture/block_expr1.rs | 8 + .../rust/execute/torture/builtin_macro_cfg.rs | 32 ++++ .../execute/torture/builtin_macro_concat.rs | 29 +++ .../rust/execute/torture/builtin_macro_env.rs | 31 ++++ .../torture/builtin_macro_include_bytes.rs | 46 +++++ .../torture/builtin_macro_include_str.rs | 27 +++ .../execute/torture/builtin_macro_line.rs | 25 +++ .../rust/execute/torture/builtin_macros1.rs | 21 +++ .../rust/execute/torture/builtin_macros3.rs | 28 +++ gcc/testsuite/rust/execute/torture/cfg1.rs | 32 ++++ gcc/testsuite/rust/execute/torture/cfg2.rs | 31 ++++ gcc/testsuite/rust/execute/torture/cfg3.rs | 37 ++++ gcc/testsuite/rust/execute/torture/cfg4.rs | 38 ++++ gcc/testsuite/rust/execute/torture/cfg5.rs | 13 ++ .../rust/execute/torture/coercion1.rs | 41 +++++ .../rust/execute/torture/coercion2.rs | 39 ++++ .../rust/execute/torture/const_fold1.rs | 13 ++ .../rust/execute/torture/const_fold2.rs | 16 ++ .../execute/torture/copy_nonoverlapping1.rs | 17 ++ .../rust/execute/torture/empty_main.rs | 3 + .../rust/execute/torture/execute.exp | 33 ++++ .../rust/execute/torture/exit_error.rs | 5 + .../rust/execute/torture/extern_mod4.rs | 19 ++ gcc/testsuite/rust/execute/torture/func1.rs | 5 + .../rust/execute/torture/helloworld1.rs | 15 ++ .../rust/execute/torture/helloworld2.rs | 15 ++ .../rust/execute/torture/include.txt | 1 + gcc/testsuite/rust/execute/torture/index1.rs | 28 +++ .../rust/execute/torture/issue-1120.rs | 123 +++++++++++++ .../rust/execute/torture/issue-1133.rs | 146 +++++++++++++++ .../rust/execute/torture/issue-1198.rs | 75 ++++++++ .../rust/execute/torture/issue-1231.rs | 36 ++++ .../rust/execute/torture/issue-1232.rs | 159 ++++++++++++++++ .../rust/execute/torture/issue-1249.rs | 39 ++++ .../rust/execute/torture/issue-1436.rs | 172 ++++++++++++++++++ .../rust/execute/torture/issue-1496.rs | 75 ++++++++ .../rust/execute/torture/issue-647.rs | 33 ++++ .../rust/execute/torture/issue-845.rs | 47 +++++ .../rust/execute/torture/issue-851.rs | 35 ++++ .../rust/execute/torture/issue-858.rs | 32 ++++ .../rust/execute/torture/issue-976.rs | 14 ++ .../rust/execute/torture/issue-995.rs | 9 + gcc/testsuite/rust/execute/torture/macros1.rs | 13 ++ .../rust/execute/torture/macros10.rs | 22 +++ .../rust/execute/torture/macros11.rs | 25 +++ .../rust/execute/torture/macros12.rs | 22 +++ .../rust/execute/torture/macros13.rs | 22 +++ .../rust/execute/torture/macros14.rs | 22 +++ .../rust/execute/torture/macros16.rs | 14 ++ .../rust/execute/torture/macros17.rs | 17 ++ .../rust/execute/torture/macros18.rs | 14 ++ .../rust/execute/torture/macros19.rs | 14 ++ gcc/testsuite/rust/execute/torture/macros2.rs | 40 ++++ .../rust/execute/torture/macros20.rs | 14 ++ .../rust/execute/torture/macros21.rs | 15 ++ .../rust/execute/torture/macros22.rs | 27 +++ .../rust/execute/torture/macros23.rs | 19 ++ .../rust/execute/torture/macros24.rs | 9 + .../rust/execute/torture/macros25.rs | 13 ++ .../rust/execute/torture/macros26.rs | 12 ++ .../rust/execute/torture/macros27.rs | 24 +++ .../rust/execute/torture/macros28.rs | 13 ++ .../rust/execute/torture/macros29.rs | 24 +++ gcc/testsuite/rust/execute/torture/macros3.rs | 61 +++++++ .../rust/execute/torture/macros30.rs | 25 +++ .../rust/execute/torture/macros31.rs | 32 ++++ gcc/testsuite/rust/execute/torture/macros4.rs | 15 ++ gcc/testsuite/rust/execute/torture/macros5.rs | 13 ++ gcc/testsuite/rust/execute/torture/macros6.rs | 12 ++ gcc/testsuite/rust/execute/torture/macros7.rs | 28 +++ gcc/testsuite/rust/execute/torture/macros8.rs | 27 +++ gcc/testsuite/rust/execute/torture/macros9.rs | 28 +++ gcc/testsuite/rust/execute/torture/match1.rs | 58 ++++++ gcc/testsuite/rust/execute/torture/match2.rs | 41 +++++ gcc/testsuite/rust/execute/torture/match3.rs | 51 ++++++ .../rust/execute/torture/match_bool1.rs | 49 +++++ .../rust/execute/torture/match_byte1.rs | 56 ++++++ .../rust/execute/torture/match_char1.rs | 56 ++++++ .../rust/execute/torture/match_int1.rs | 109 +++++++++++ .../rust/execute/torture/match_loop1.rs | 56 ++++++ .../rust/execute/torture/match_range1.rs | 37 ++++ .../rust/execute/torture/match_range2.rs | 45 +++++ .../rust/execute/torture/match_tuple1.rs | 45 +++++ gcc/testsuite/rust/execute/torture/method1.rs | 27 +++ gcc/testsuite/rust/execute/torture/method2.rs | 76 ++++++++ gcc/testsuite/rust/execute/torture/method3.rs | 78 ++++++++ gcc/testsuite/rust/execute/torture/method4.rs | 78 ++++++++ gcc/testsuite/rust/execute/torture/mod1.rs | 21 +++ .../rust/execute/torture/modules/mod.rs | 3 + .../execute/torture/operator_overload_1.rs | 36 ++++ .../execute/torture/operator_overload_10.rs | 75 ++++++++ .../execute/torture/operator_overload_11.rs | 37 ++++ .../execute/torture/operator_overload_12.rs | 31 ++++ .../execute/torture/operator_overload_2.rs | 38 ++++ .../execute/torture/operator_overload_3.rs | 55 ++++++ .../execute/torture/operator_overload_4.rs | 33 ++++ .../execute/torture/operator_overload_5.rs | 33 ++++ .../execute/torture/operator_overload_6.rs | 37 ++++ .../execute/torture/operator_overload_7.rs | 42 +++++ .../execute/torture/operator_overload_8.rs | 58 ++++++ .../execute/torture/operator_overload_9.rs | 58 ++++++ .../rust/execute/torture/slice-magic.rs | 106 +++++++++++ .../rust/execute/torture/slice-magic2.rs | 106 +++++++++++ gcc/testsuite/rust/execute/torture/slice1.rs | 27 +++ .../rust/execute/torture/str-layout1.rs | 57 ++++++ .../rust/execute/torture/str-zero.rs | 26 +++ gcc/testsuite/rust/execute/torture/trait1.rs | 52 ++++++ gcc/testsuite/rust/execute/torture/trait10.rs | 41 +++++ gcc/testsuite/rust/execute/torture/trait11.rs | 38 ++++ gcc/testsuite/rust/execute/torture/trait12.rs | 38 ++++ gcc/testsuite/rust/execute/torture/trait13.rs | 48 +++++ gcc/testsuite/rust/execute/torture/trait2.rs | 37 ++++ gcc/testsuite/rust/execute/torture/trait3.rs | 43 +++++ gcc/testsuite/rust/execute/torture/trait4.rs | 34 ++++ gcc/testsuite/rust/execute/torture/trait5.rs | 39 ++++ gcc/testsuite/rust/execute/torture/trait6.rs | 39 ++++ gcc/testsuite/rust/execute/torture/trait7.rs | 39 ++++ gcc/testsuite/rust/execute/torture/trait8.rs | 39 ++++ gcc/testsuite/rust/execute/torture/trait9.rs | 35 ++++ .../rust/execute/torture/transmute1.rs | 23 +++ .../rust/execute/torture/wrapping_op1.rs | 14 ++ .../rust/execute/torture/wrapping_op2.rs | 20 ++ gcc/testsuite/rust/execute/xfail/macro1.rs | 32 ++++ 123 files changed, 4631 insertions(+) create mode 100644 gcc/testsuite/rust/execute/torture/block_expr1.rs create mode 100644 gcc/testsuite/rust/execute/torture/builtin_macro_cfg.rs create mode 100644 gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs create mode 100644 gcc/testsuite/rust/execute/torture/builtin_macro_env.rs create mode 100644 gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs create mode 100644 gcc/testsuite/rust/execute/torture/builtin_macro_include_str.rs create mode 100644 gcc/testsuite/rust/execute/torture/builtin_macro_line.rs create mode 100644 gcc/testsuite/rust/execute/torture/builtin_macros1.rs create mode 100644 gcc/testsuite/rust/execute/torture/builtin_macros3.rs create mode 100644 gcc/testsuite/rust/execute/torture/cfg1.rs create mode 100644 gcc/testsuite/rust/execute/torture/cfg2.rs create mode 100644 gcc/testsuite/rust/execute/torture/cfg3.rs create mode 100644 gcc/testsuite/rust/execute/torture/cfg4.rs create mode 100644 gcc/testsuite/rust/execute/torture/cfg5.rs create mode 100644 gcc/testsuite/rust/execute/torture/coercion1.rs create mode 100644 gcc/testsuite/rust/execute/torture/coercion2.rs create mode 100644 gcc/testsuite/rust/execute/torture/const_fold1.rs create mode 100644 gcc/testsuite/rust/execute/torture/const_fold2.rs create mode 100644 gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs create mode 100644 gcc/testsuite/rust/execute/torture/empty_main.rs create mode 100644 gcc/testsuite/rust/execute/torture/execute.exp create mode 100644 gcc/testsuite/rust/execute/torture/exit_error.rs create mode 100644 gcc/testsuite/rust/execute/torture/extern_mod4.rs create mode 100644 gcc/testsuite/rust/execute/torture/func1.rs create mode 100644 gcc/testsuite/rust/execute/torture/helloworld1.rs create mode 100644 gcc/testsuite/rust/execute/torture/helloworld2.rs create mode 100644 gcc/testsuite/rust/execute/torture/include.txt create mode 100644 gcc/testsuite/rust/execute/torture/index1.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-1120.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-1133.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-1198.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-1231.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-1232.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-1249.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-1436.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-1496.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-647.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-845.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-851.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-858.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-976.rs create mode 100644 gcc/testsuite/rust/execute/torture/issue-995.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros1.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros10.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros11.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros12.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros13.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros14.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros16.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros17.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros18.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros19.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros2.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros20.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros21.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros22.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros23.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros24.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros25.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros26.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros27.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros28.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros29.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros3.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros30.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros31.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros4.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros5.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros6.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros7.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros8.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros9.rs create mode 100644 gcc/testsuite/rust/execute/torture/match1.rs create mode 100644 gcc/testsuite/rust/execute/torture/match2.rs create mode 100644 gcc/testsuite/rust/execute/torture/match3.rs create mode 100644 gcc/testsuite/rust/execute/torture/match_bool1.rs create mode 100644 gcc/testsuite/rust/execute/torture/match_byte1.rs create mode 100644 gcc/testsuite/rust/execute/torture/match_char1.rs create mode 100644 gcc/testsuite/rust/execute/torture/match_int1.rs create mode 100644 gcc/testsuite/rust/execute/torture/match_loop1.rs create mode 100644 gcc/testsuite/rust/execute/torture/match_range1.rs create mode 100644 gcc/testsuite/rust/execute/torture/match_range2.rs create mode 100644 gcc/testsuite/rust/execute/torture/match_tuple1.rs create mode 100644 gcc/testsuite/rust/execute/torture/method1.rs create mode 100644 gcc/testsuite/rust/execute/torture/method2.rs create mode 100644 gcc/testsuite/rust/execute/torture/method3.rs create mode 100644 gcc/testsuite/rust/execute/torture/method4.rs create mode 100644 gcc/testsuite/rust/execute/torture/mod1.rs create mode 100644 gcc/testsuite/rust/execute/torture/modules/mod.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_1.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_10.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_11.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_12.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_2.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_3.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_4.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_5.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_6.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_7.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_8.rs create mode 100644 gcc/testsuite/rust/execute/torture/operator_overload_9.rs create mode 100644 gcc/testsuite/rust/execute/torture/slice-magic.rs create mode 100644 gcc/testsuite/rust/execute/torture/slice-magic2.rs create mode 100644 gcc/testsuite/rust/execute/torture/slice1.rs create mode 100644 gcc/testsuite/rust/execute/torture/str-layout1.rs create mode 100644 gcc/testsuite/rust/execute/torture/str-zero.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait1.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait10.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait11.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait12.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait13.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait2.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait3.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait4.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait5.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait6.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait7.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait8.rs create mode 100644 gcc/testsuite/rust/execute/torture/trait9.rs create mode 100644 gcc/testsuite/rust/execute/torture/transmute1.rs create mode 100644 gcc/testsuite/rust/execute/torture/wrapping_op1.rs create mode 100644 gcc/testsuite/rust/execute/torture/wrapping_op2.rs create mode 100644 gcc/testsuite/rust/execute/xfail/macro1.rs diff --git a/gcc/testsuite/rust/execute/torture/block_expr1.rs b/gcc/testsuite/rust/execute/torture/block_expr1.rs new file mode 100644 index 00000000000..d561f8cab59 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/block_expr1.rs @@ -0,0 +1,8 @@ +fn main() -> i32 { + let ret = { + 1; + 2; + 0 + }; + ret +} diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_cfg.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_cfg.rs new file mode 100644 index 00000000000..fad2daef6bc --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/builtin_macro_cfg.rs @@ -0,0 +1,32 @@ +// { dg-additional-options "-w -frust-cfg=A" } +// { dg-output "A\n" } +#[rustc_builtin_macro] +macro_rules! cfg { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: &str) { + unsafe { + printf( + "%s\n" as *const str as *const i8, + s as *const str as *const i8, + ); + } +} + +fn main() -> i32 { + let cfg = cfg!(A); + if cfg { + print("A"); + } + let cfg = cfg!(B); + if cfg { + print("B"); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs new file mode 100644 index 00000000000..9b33924f5a1 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/builtin_macro_concat.rs @@ -0,0 +1,29 @@ +// { dg-output "\ntest10btrue2.15\ntest10bfalse2.151\n" } +#[rustc_builtin_macro] +macro_rules! concat { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: &str) { + unsafe { + printf( + "%s\n" as *const str as *const i8, + s as *const str as *const i8, + ); + } +} + +fn main() -> i32 { + let a = concat!(); + let b = concat!("test", 10, 'b', true, 2.15); + let c = concat!("test", 10, 'b', false, 2.15, 1u64); + print(a); + print(b); + print(c); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_env.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_env.rs new file mode 100644 index 00000000000..a5c80b25728 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/builtin_macro_env.rs @@ -0,0 +1,31 @@ +// { dg-output "VALUE\nVALUE\n" } +// { dg-set-compiler-env-var ENV_MACRO_TEST "VALUE" } +#[rustc_builtin_macro] +macro_rules! env { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: &str) { + unsafe { + printf( + "%s\n" as *const str as *const i8, + s as *const str as *const i8, + ); + } +} + +fn main() -> i32 { + let val0 = env!("ENV_MACRO_TEST"); + + print(val0); + + let val1 = env!("ENV_MACRO_TEST",); + + print(val1); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs new file mode 100644 index 00000000000..087f0220de5 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs @@ -0,0 +1,46 @@ +// { dg-output "104\n33\n1\n" } +#[rustc_builtin_macro] +macro_rules! include_bytes { + () => {{}}; +} + +extern "C" { + fn printf(s: *const i8, ...); +} + +fn print_int(value: i32) { + let s = "%d\n\0" as *const str as *const i8; + unsafe { + printf(s, value); + } +} + +fn main() -> i32 { + let bytes = include_bytes!("include.txt"); + + print_int(bytes[0] as i32); + print_int(bytes[14] as i32); + + let the_bytes = b"hello, include!\n"; + + let x = bytes[0] == the_bytes[0] + && bytes[1] == the_bytes[1] + && bytes[2] == the_bytes[2] + && bytes[3] == the_bytes[3] + && bytes[4] == the_bytes[4] + && bytes[5] == the_bytes[5] + && bytes[6] == the_bytes[6] + && bytes[7] == the_bytes[7] + && bytes[8] == the_bytes[8] + && bytes[9] == the_bytes[9] + && bytes[10] == the_bytes[10] + && bytes[11] == the_bytes[11] + && bytes[12] == the_bytes[12] + && bytes[13] == the_bytes[13] + && bytes[14] == the_bytes[14] + && bytes[15] == the_bytes[15]; + + print_int(x as i32); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_include_str.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_include_str.rs new file mode 100644 index 00000000000..6f9871d379c --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/builtin_macro_include_str.rs @@ -0,0 +1,27 @@ +// { dg-output "hello, include!\n" } +#[rustc_builtin_macro] +macro_rules! include_str { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: &str) { + unsafe { + printf( + "%s" as *const str as *const i8, + s as *const str as *const i8, + ); + } +} + +fn main() -> i32 { + // include_str! (and include_bytes!) allow for an optional trailing comma. + let my_str = include_str!("include.txt",); + + print(my_str); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_line.rs b/gcc/testsuite/rust/execute/torture/builtin_macro_line.rs new file mode 100644 index 00000000000..02541ed52e2 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/builtin_macro_line.rs @@ -0,0 +1,25 @@ +// { dg-output "18\n21\n" } +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: u32) { + unsafe { + printf("%u\n\0" as *const str as *const i8, s); + } +} + +#[rustc_builtin_macro] +macro_rules! line { + () => {{}}; +} + +fn main() -> i32 { + let a = line!(); + print(a); + + let b = line!(); + print(b); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/builtin_macros1.rs b/gcc/testsuite/rust/execute/torture/builtin_macros1.rs new file mode 100644 index 00000000000..5976478e426 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/builtin_macros1.rs @@ -0,0 +1,21 @@ +// { dg-output "rust/execute/torture/builtin_macros1.rs" } +#[rustc_builtin_macro] +macro_rules! file { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: &str) { + unsafe { + printf("%s\n\0" as *const str as *const i8, s); + } +} + +fn main() -> i32 { + print(file!()); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/builtin_macros3.rs b/gcc/testsuite/rust/execute/torture/builtin_macros3.rs new file mode 100644 index 00000000000..24555cbdb8a --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/builtin_macros3.rs @@ -0,0 +1,28 @@ +// { dg-output "14\n42\n" } +#[rustc_builtin_macro] +macro_rules! column { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: u32) { + unsafe { + printf("%u\n\0" as *const str as *const i8, s); + } +} + +fn main() -> i32 { + let c0 = column!(); + + print(c0); + + let c1 = column!(); + + print(c1); + + 0 +} + diff --git a/gcc/testsuite/rust/execute/torture/cfg1.rs b/gcc/testsuite/rust/execute/torture/cfg1.rs new file mode 100644 index 00000000000..d3c56295503 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/cfg1.rs @@ -0,0 +1,32 @@ +// { dg-additional-options "-w -frust-cfg=A" } +// { dg-output "test1\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +#[cfg(A)] +fn test() { + unsafe { + let a = "test1\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } +} + +#[cfg(B)] +fn test() { + unsafe { + let a = "test2\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } +} + +fn main() -> i32 { + test(); + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/cfg2.rs b/gcc/testsuite/rust/execute/torture/cfg2.rs new file mode 100644 index 00000000000..5048bcb2791 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/cfg2.rs @@ -0,0 +1,31 @@ +// { dg-additional-options "-w -frust-cfg=A" } +// { dg-output "test1\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn test() { + #[cfg(A)] + unsafe { + let a = "test1\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + #[cfg(B)] + unsafe { + let a = "test2\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } +} + +fn main() -> i32 { + test(); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/cfg3.rs b/gcc/testsuite/rust/execute/torture/cfg3.rs new file mode 100644 index 00000000000..89312344b23 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/cfg3.rs @@ -0,0 +1,37 @@ +// { dg-additional-options "-w -frust-cfg=A" } +// { dg-output "test1\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(i32); +impl Foo { + #[cfg(A)] + fn test(&self) { + unsafe { + let a = "test1\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + } + + #[cfg(B)] + fn test(&self) { + unsafe { + let a = "test2\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + } +} + +fn main() -> i32 { + let a = Foo(123); + a.test(); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/cfg4.rs b/gcc/testsuite/rust/execute/torture/cfg4.rs new file mode 100644 index 00000000000..d1c2a22a0ff --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/cfg4.rs @@ -0,0 +1,38 @@ +// { dg-additional-options "-w -frust-cfg=A" } +// { dg-output "test1\ntest2\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(i32); +impl Foo { + #[cfg(A)] + fn test(&self) { + unsafe { + let a = "test1\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + } + + #[cfg(not(B))] + fn test2(&self) { + unsafe { + let a = "test2\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + } +} + +fn main() -> i32 { + let a = Foo(123); + a.test(); + a.test2(); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/cfg5.rs b/gcc/testsuite/rust/execute/torture/cfg5.rs new file mode 100644 index 00000000000..581a29bb89d --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/cfg5.rs @@ -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 +} diff --git a/gcc/testsuite/rust/execute/torture/coercion1.rs b/gcc/testsuite/rust/execute/torture/coercion1.rs new file mode 100644 index 00000000000..2cdb9bbca38 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/coercion1.rs @@ -0,0 +1,41 @@ +/* { dg-output "123\n123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(i32); +trait Bar { + fn baz(&self); +} + +impl Bar for Foo { + fn baz(&self) { + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, self.0); + } + } +} + +fn static_dispatch(t: &T) { + t.baz(); +} + +fn dynamic_dispatch(t: &dyn Bar) { + t.baz(); +} + +fn main() -> i32 { + let a; + a = Foo(123); + static_dispatch(&a); + + let b: &dyn Bar; + b = &a; + dynamic_dispatch(b); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/coercion2.rs b/gcc/testsuite/rust/execute/torture/coercion2.rs new file mode 100644 index 00000000000..12dd68ff5f7 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/coercion2.rs @@ -0,0 +1,39 @@ +/* { dg-output "123\n123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(i32); +trait Bar { + fn baz(&self); +} + +impl Bar for Foo { + fn baz(&self) { + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, self.0); + } + } +} + +fn static_dispatch(t: &T) { + t.baz(); +} + +fn dynamic_dispatch(t: &dyn Bar) { + t.baz(); +} + +fn main() -> i32 { + let a; + a = &Foo(123); + + static_dispatch(a); + dynamic_dispatch(a); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/const_fold1.rs b/gcc/testsuite/rust/execute/torture/const_fold1.rs new file mode 100644 index 00000000000..3cd6c0c77b5 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/const_fold1.rs @@ -0,0 +1,13 @@ +// { dg-additional-options "-w" } +const fn const_fn() -> usize { + 4 +} + +const FN_TEST: usize = const_fn(); + +const TEST: usize = 2 + FN_TEST; + +fn main() -> i32 { + let a: [_; 12] = [5; TEST * 2]; + a[6] - 5 +} diff --git a/gcc/testsuite/rust/execute/torture/const_fold2.rs b/gcc/testsuite/rust/execute/torture/const_fold2.rs new file mode 100644 index 00000000000..c525648fe0b --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/const_fold2.rs @@ -0,0 +1,16 @@ +// { dg-additional-options "-w" } +const A: i32 = 1; +const B: i32 = { A + 2 }; + +const fn test() -> i32 { + B +} + +const C: i32 = { + const a: i32 = 4; + test() + a +}; + +fn main() -> i32 { + C - 7 +} diff --git a/gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs b/gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs new file mode 100644 index 00000000000..2ae7a0869e3 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/copy_nonoverlapping1.rs @@ -0,0 +1,17 @@ +extern "rust-intrinsic" { + pub fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); +} + +fn main() -> i32 { + let i = 15; + let mut i_copy = 16; + + let i = &i as *const i32; + let i_copy = &mut i_copy as *mut i32; + + unsafe { + copy_nonoverlapping(i, i_copy, 1); + + *i_copy - *i + } +} \ No newline at end of file diff --git a/gcc/testsuite/rust/execute/torture/empty_main.rs b/gcc/testsuite/rust/execute/torture/empty_main.rs new file mode 100644 index 00000000000..6442e1e4e83 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/empty_main.rs @@ -0,0 +1,3 @@ +fn main() -> i32 { + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/execute.exp b/gcc/testsuite/rust/execute/torture/execute.exp new file mode 100644 index 00000000000..6dfb6d2b446 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/execute.exp @@ -0,0 +1,33 @@ +# Copyright (C) 2021-2022 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Execute tests, torture testing. + +# Load support procs. +load_lib rust-dg.exp + +# Initialize `dg'. +dg-init + +# Main loop. +set saved-dg-do-what-default ${dg-do-what-default} + +set dg-do-what-default "run" +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" "" +set dg-do-what-default ${saved-dg-do-what-default} + +# All done. +dg-finish diff --git a/gcc/testsuite/rust/execute/torture/exit_error.rs b/gcc/testsuite/rust/execute/torture/exit_error.rs new file mode 100644 index 00000000000..c3d0d9f2480 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/exit_error.rs @@ -0,0 +1,5 @@ +// { dg-xfail-run-if "" { *-*-* } } + +fn main() -> i32 { + 1 +} diff --git a/gcc/testsuite/rust/execute/torture/extern_mod4.rs b/gcc/testsuite/rust/execute/torture/extern_mod4.rs new file mode 100644 index 00000000000..99b6fb5c9ba --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/extern_mod4.rs @@ -0,0 +1,19 @@ +// { dg-additional-options "-w" } +// { dg-output "12" } +mod modules; + +extern "C" { + fn printf(s: *const i8, ...); +} + +fn main() -> i32 { + unsafe { + let fmt_s = "%d\n\0"; + let fmt_p = fmt_s as *const str; + let fmt_i8 = fmt_p as *const i8; + + printf(fmt_i8, modules::return_12()); + } + + return 0; +} diff --git a/gcc/testsuite/rust/execute/torture/func1.rs b/gcc/testsuite/rust/execute/torture/func1.rs new file mode 100644 index 00000000000..0a093d88587 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/func1.rs @@ -0,0 +1,5 @@ +fn main() -> i32 { + 1; + 2; + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/helloworld1.rs b/gcc/testsuite/rust/execute/torture/helloworld1.rs new file mode 100644 index 00000000000..d416efa33af --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/helloworld1.rs @@ -0,0 +1,15 @@ +/* { dg-output "Hello World" }*/ +extern "C" { + fn puts(s: *const i8); +} + +fn main() -> i32 { + unsafe { + let a = "Hello World"; + let b = a as *const str; + let c = b as *const i8; + + puts(c); + } + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/helloworld2.rs b/gcc/testsuite/rust/execute/torture/helloworld2.rs new file mode 100644 index 00000000000..cc05f3798fa --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/helloworld2.rs @@ -0,0 +1,15 @@ +/* { dg-output "Hello World 123\n" }*/ +extern "C" { + fn printf(s: *const i8, ...); +} + +fn main() -> i32 { + unsafe { + let a = "Hello World %i\n"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, 123); + } + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/include.txt b/gcc/testsuite/rust/execute/torture/include.txt new file mode 100644 index 00000000000..12c368778e1 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/include.txt @@ -0,0 +1 @@ +hello, include! diff --git a/gcc/testsuite/rust/execute/torture/index1.rs b/gcc/testsuite/rust/execute/torture/index1.rs new file mode 100644 index 00000000000..4682978bdd0 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/index1.rs @@ -0,0 +1,28 @@ +// { dg-additional-options "-w" } +#[lang = "index"] +trait Index { + type Output; + + fn index(&self, index: Idx) -> &Self::Output; +} + +struct Foo(i32, i32); +impl Index for Foo { + type Output = i32; + + fn index(&self, index: isize) -> &i32 { + if index == 0 { + &self.0 + } else { + &self.1 + } + } +} + +fn main() -> i32 { + let a = Foo(1, 2); + let b = a[0]; + let c = a[1]; + + c - b - 1 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-1120.rs b/gcc/testsuite/rust/execute/torture/issue-1120.rs new file mode 100644 index 00000000000..242c94b5cb6 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1120.rs @@ -0,0 +1,123 @@ +// { dg-additional-options "-w" } +extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + pub fn offset(dst: *const T, offset: isize) -> *const T; +} + +struct FatPtr { + data: *const T, + len: usize, +} + +pub union Repr { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr, +} + +pub enum Option { + None, + Some(T), +} + +#[lang = "Range"] +pub struct Range { + pub start: Idx, + pub end: Idx, +} + +#[lang = "const_slice_ptr"] +impl *const [T] { + pub const fn len(self) -> usize { + unsafe { Repr { rust: self }.raw.len } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +#[lang = "const_ptr"] +impl *const T { + pub const unsafe fn offset(self, count: isize) -> *const T { + unsafe { offset(self, count) } + } + + pub const unsafe fn add(self, count: usize) -> Self { + unsafe { self.offset(count as isize) } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { + unsafe { + Repr { + raw: FatPtr { data, len }, + } + .rust + } +} + +#[lang = "index"] +trait Index { + type Output; + + fn index(&self, index: Idx) -> &Self::Output; +} + +pub unsafe trait SliceIndex { + type Output; + + fn get(self, slice: &T) -> Option<&Self::Output>; + + unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output; + + fn index(self, slice: &T) -> &Self::Output; +} + +unsafe impl SliceIndex<[T]> for Range { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&[T]> { + if self.start > self.end + /* || self.end > slice.len() */ + { + Option::None + } else { + unsafe { Option::Some(&*self.get_unchecked(slice)) } + } + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + unsafe { + let a: *const T = slice.as_ptr(); + let b: *const T = a.add(self.start); + slice_from_raw_parts(b, self.end - self.start) + } + } + + fn index(self, slice: &[T]) -> &[T] { + unsafe { &*self.get_unchecked(slice) } + } +} + +impl Index for [T] +where + I: SliceIndex<[T]>, +{ + type Output = I::Output; + + fn index(&self, index: I) -> &I::Output { + index.index(self) + } +} + +fn main() -> i32 { + let a = [1, 2, 3, 4, 5]; + let b = &a[1..3]; + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-1133.rs b/gcc/testsuite/rust/execute/torture/issue-1133.rs new file mode 100644 index 00000000000..f2080a6e072 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1133.rs @@ -0,0 +1,146 @@ +// { dg-additional-options "-w" } +extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + pub fn offset(dst: *const T, offset: isize) -> *const T; +} + +struct FatPtr { + data: *const T, + len: usize, +} + +pub union Repr { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr, +} + +pub enum Option { + None, + Some(T), +} + +#[lang = "Range"] +pub struct Range { + pub start: Idx, + pub end: Idx, +} + +#[lang = "const_slice_ptr"] +impl *const [T] { + pub const fn len(self) -> usize { + unsafe { Repr { rust: self }.raw.len } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +#[lang = "const_ptr"] +impl *const T { + pub const unsafe fn offset(self, count: isize) -> *const T { + unsafe { offset(self, count) } + } + + pub const unsafe fn add(self, count: usize) -> Self { + unsafe { self.offset(count as isize) } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { + unsafe { + Repr { + raw: FatPtr { data, len }, + } + .rust + } +} + +#[lang = "index"] +trait Index { + type Output; + + fn index(&self, index: Idx) -> &Self::Output; +} + +pub unsafe trait SliceIndex { + type Output; + + fn get(self, slice: &T) -> Option<&Self::Output>; + + unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output; + + fn index(self, slice: &T) -> &Self::Output; +} + +unsafe impl SliceIndex<[T]> for usize { + type Output = T; + + fn get(self, slice: &[T]) -> Option<&T> { + unsafe { Option::Some(&*self.get_unchecked(slice)) } + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const T { + // SAFETY: the caller guarantees that `slice` is not dangling, so it + // cannot be longer than `isize::MAX`. They also guarantee that + // `self` is in bounds of `slice` so `self` cannot overflow an `isize`, + // so the call to `add` is safe. + unsafe { slice.as_ptr().add(self) } + } + + fn index(self, slice: &[T]) -> &T { + // N.B., use intrinsic indexing + // &(*slice)[self] + unsafe { &*self.get_unchecked(slice) } + } +} + +unsafe impl SliceIndex<[T]> for Range { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&[T]> { + if self.start > self.end + /* || self.end > slice.len() */ + { + Option::None + } else { + unsafe { Option::Some(&*self.get_unchecked(slice)) } + } + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + unsafe { + let a: *const T = slice.as_ptr(); + let b: *const T = a.add(self.start); + slice_from_raw_parts(b, self.end - self.start) + } + } + + fn index(self, slice: &[T]) -> &[T] { + unsafe { &*self.get_unchecked(slice) } + } +} + +impl Index for [T] +where + I: SliceIndex<[T]>, +{ + type Output = I::Output; + + fn index(&self, index: I) -> &I::Output { + index.index(self) + } +} + +fn main() -> i32 { + let a = [1, 2, 3, 4, 5]; + let b = &a[1..3]; + let c = b[1]; + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-1198.rs b/gcc/testsuite/rust/execute/torture/issue-1198.rs new file mode 100644 index 00000000000..fce44ad1994 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1198.rs @@ -0,0 +1,75 @@ +/* { dg-output "foo_deref\nimm_deref\n123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "deref"] +pub trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +impl Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "imm_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +impl Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "mut_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +struct Foo(T); +impl Deref for Foo { + type Target = T; + + fn deref(&self) -> &Self::Target { + unsafe { + let a = "foo_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + &self.0 + } +} + +fn main() -> i32 { + let foo: Foo = Foo(123); + let bar: &i32 = &foo; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, *bar); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-1231.rs b/gcc/testsuite/rust/execute/torture/issue-1231.rs new file mode 100644 index 00000000000..970e86f917a --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1231.rs @@ -0,0 +1,36 @@ +// { dg-additional-options "-w" } +// { dg-output "outer\ninner\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn machin() { + unsafe { + let a = "outer\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, 123); + } +} + +fn bidule() { + fn machin() { + unsafe { + let a = "inner\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, 123); + } + } + + self::machin(); + machin(); +} + +fn main() -> i32 { + bidule(); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-1232.rs b/gcc/testsuite/rust/execute/torture/issue-1232.rs new file mode 100644 index 00000000000..c56d5c18695 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1232.rs @@ -0,0 +1,159 @@ +// { dg-additional-options "-w" } +// { dg-output "slice_access=3\n" } +extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + fn offset(dst: *const T, offset: isize) -> *const T; +} + +extern "C" { + fn printf(s: *const i8, ...); +} + +struct FatPtr { + data: *const T, + len: usize, +} + +pub union Repr { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr, +} + +pub enum Option { + None, + Some(T), +} + +#[lang = "Range"] +pub struct Range { + pub start: Idx, + pub end: Idx, +} + +#[lang = "const_slice_ptr"] +impl *const [T] { + pub const fn len(self) -> usize { + unsafe { Repr { rust: self }.raw.len } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +#[lang = "const_ptr"] +impl *const T { + pub const unsafe fn offset(self, count: isize) -> *const T { + unsafe { offset(self, count) } + } + + pub const unsafe fn add(self, count: usize) -> Self { + unsafe { self.offset(count as isize) } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { + unsafe { + Repr { + raw: FatPtr { data, len }, + } + .rust + } +} + +#[lang = "index"] +trait Index { + type Output; + + fn index(&self, index: Idx) -> &Self::Output; +} + +pub unsafe trait SliceIndex { + type Output; + + fn get(self, slice: &T) -> Option<&Self::Output>; + + unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output; + + fn index(self, slice: &T) -> &Self::Output; +} + +unsafe impl SliceIndex<[T]> for usize { + type Output = T; + + fn get(self, slice: &[T]) -> Option<&T> { + unsafe { Option::Some(&*self.get_unchecked(slice)) } + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const T { + // SAFETY: the caller guarantees that `slice` is not dangling, so it + // cannot be longer than `isize::MAX`. They also guarantee that + // `self` is in bounds of `slice` so `self` cannot overflow an `isize`, + // so the call to `add` is safe. + unsafe { slice.as_ptr().add(self) } + } + + fn index(self, slice: &[T]) -> &T { + // N.B., use intrinsic indexing + // &(*slice)[self] + unsafe { &*self.get_unchecked(slice) } + } +} + +unsafe impl SliceIndex<[T]> for Range { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&[T]> { + if self.start > self.end + /* || self.end > slice.len() */ + { + Option::None + } else { + unsafe { Option::Some(&*self.get_unchecked(slice)) } + } + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + unsafe { + let a: *const T = slice.as_ptr(); + let b: *const T = a.add(self.start); + slice_from_raw_parts(b, self.end - self.start) + } + } + + fn index(self, slice: &[T]) -> &[T] { + unsafe { &*self.get_unchecked(slice) } + } +} + +impl Index for [T] +where + I: SliceIndex<[T]>, +{ + type Output = I::Output; + + fn index(&self, index: I) -> &I::Output { + index.index(self) + } +} + +fn main() -> i32 { + let array = [1, 2, 3, 4, 5]; + let slice = &array[1..3]; + let slice_access = slice[1]; + + unsafe { + let a = "slice_access=%i\n"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, slice_access); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-1249.rs b/gcc/testsuite/rust/execute/torture/issue-1249.rs new file mode 100644 index 00000000000..072204ea877 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1249.rs @@ -0,0 +1,39 @@ +// { dg-options "-w" } +// { dg-output "1\n2\n" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +trait T { + fn foo(&self); +} + +impl dyn T { + fn bar(&self) { + unsafe { + let a = "1\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf(c); + } + self.foo() + } +} + +struct S; +impl T for S { + fn foo(&self) { + unsafe { + let a = "2\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf(c); + } + } +} + +pub fn main() -> i32 { + ::bar(&S); + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-1436.rs b/gcc/testsuite/rust/execute/torture/issue-1436.rs new file mode 100644 index 00000000000..5c079a61f07 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1436.rs @@ -0,0 +1,172 @@ +// { dg-options "-w" } +// { dg-output "" } +mod intrinsics { + extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + pub fn offset(ptr: *const T, count: isize) -> *const T; + } +} + +mod mem { + extern "rust-intrinsic" { + fn size_of() -> usize; + } +} + +extern "C" { + fn printf(s: *const i8, ...); +} + +struct FatPtr { + data: *const T, + len: usize, +} + +pub union Repr { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr, +} + +pub enum Option { + None, + Some(T), +} + +#[lang = "Range"] +pub struct Range { + pub start: Idx, + pub end: Idx, +} + +#[lang = "const_slice_ptr"] +impl *const [T] { + pub const fn len(self) -> usize { + unsafe { Repr { rust: self }.raw.len } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +#[lang = "const_ptr"] +impl *const T { + pub const unsafe fn offset(self, count: isize) -> *const T { + unsafe { intrinsics::offset(self, count) } + } + + pub const unsafe fn add(self, count: usize) -> Self { + unsafe { self.offset(count as isize) } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { + unsafe { + Repr { + raw: FatPtr { data, len }, + } + .rust + } +} + +#[lang = "index"] +trait Index { + type Output; + + fn index(&self, index: Idx) -> &Self::Output; +} + +impl [T] { + pub const fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub const fn len(&self) -> usize { + unsafe { Repr { rust: self }.raw.len } + } +} + +pub unsafe trait SliceIndex { + type Output; + + fn get(self, slice: &T) -> Option<&Self::Output>; + + unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output; + + fn index(self, slice: &T) -> &Self::Output; +} + +unsafe impl SliceIndex<[T]> for usize { + type Output = T; + + fn get(self, slice: &[T]) -> Option<&T> { + unsafe { Option::Some(&*self.get_unchecked(slice)) } + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const T { + // SAFETY: the caller guarantees that `slice` is not dangling, so it + // cannot be longer than `isize::MAX`. They also guarantee that + // `self` is in bounds of `slice` so `self` cannot overflow an `isize`, + // so the call to `add` is safe. + unsafe { slice.as_ptr().add(self) } + } + + fn index(self, slice: &[T]) -> &T { + unsafe { &*self.get_unchecked(slice) } + } +} + +unsafe impl SliceIndex<[T]> for Range { + type Output = [T]; + + fn get(self, slice: &[T]) -> Option<&[T]> { + if self.start > self.end || self.end > slice.len() { + Option::None + } else { + unsafe { Option::Some(&*self.get_unchecked(slice)) } + } + } + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + unsafe { + let a: *const T = slice.as_ptr(); + let b: *const T = a.add(self.start); + slice_from_raw_parts(b, self.end - self.start) + } + } + + fn index(self, slice: &[T]) -> &[T] { + unsafe { &*self.get_unchecked(slice) } + } +} + +impl Index for [T] +where + I: SliceIndex<[T]>, +{ + type Output = I::Output; + + fn index(&self, index: I) -> &I::Output { + unsafe { + let a = "slice-index\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + index.index(self) + } +} + +fn main() -> i32 { + let a = [1, 2, 3, 4, 5]; + let b = a[1]; + + b - 2 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-1496.rs b/gcc/testsuite/rust/execute/torture/issue-1496.rs new file mode 100644 index 00000000000..9f08b2ae98a --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1496.rs @@ -0,0 +1,75 @@ +/* { dg-output "foo_deref\nimm_deref\n123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "deref"] +pub trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +impl Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "imm_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +impl Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "mut_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +struct Foo(T); +impl Deref for Foo { + type Target = T; + + fn deref(&self) -> &Self::Target { + unsafe { + let a = "foo_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + &self.0 + } +} + +fn main() -> i32 { + let foo = Foo(123); + let bar = &foo as &i32; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, *bar); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-647.rs b/gcc/testsuite/rust/execute/torture/issue-647.rs new file mode 100644 index 00000000000..3f427ccb785 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-647.rs @@ -0,0 +1,33 @@ +/* { dg-output "Hello World 123\n" }*/ +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(T); + +struct Bar { + a: Foo, + b: bool, + // { dg-warning "field is never read" "" { target *-*-* } .-1 } +} + +fn test(a: Bar) -> Foo { + a.a +} + +fn main() -> i32 { + let a: Bar = Bar:: { + a: Foo::(123), + b: true, + }; + let result: Foo = test(a); + + unsafe { + let a = "Hello World %i\n"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, result.0); + } + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-845.rs b/gcc/testsuite/rust/execute/torture/issue-845.rs new file mode 100644 index 00000000000..4c689e3b6c8 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-845.rs @@ -0,0 +1,47 @@ +// { dg-output "Foo::bar\n" } +// { dg-additional-options "-w" } +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo {} + +trait Bar { + fn bar(&self) { + unsafe { + let _a = "Bar::bar\n\0"; + let _b = _a as *const str; + let _c = _b as *const i8; + printf(_c); + } + } +} + +impl Foo { + fn bar(&self) { + unsafe { + let _a = "Foo::bar\n\0"; + let _b = _a as *const str; + let _c = _b as *const i8; + printf(_c); + } + } +} + +impl Bar for Foo { + fn bar(&self) { + unsafe { + let _a = "::bar\n\0"; + let _b = _a as *const str; + let _c = _b as *const i8; + printf(_c); + } + } +} + +pub fn main() -> i32 { + let mut f = Foo {}; + f.bar(); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-851.rs b/gcc/testsuite/rust/execute/torture/issue-851.rs new file mode 100644 index 00000000000..3881c7a2ada --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-851.rs @@ -0,0 +1,35 @@ +/* { dg-output "Result: 123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Foo { + A, + B(T), +} + +fn inspect(a: Foo) { + match a { + Foo::A => unsafe { + let a = "A\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + Foo::B(x) => unsafe { + let a = "Result: %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, x); + }, + } +} + +fn main() -> i32 { + let a = Foo::B(123); + inspect(a); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-858.rs b/gcc/testsuite/rust/execute/torture/issue-858.rs new file mode 100644 index 00000000000..5a43f3e1b1a --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-858.rs @@ -0,0 +1,32 @@ +/* { dg-output "Result: 123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Foo { + A, + B(T), +} + +fn main() -> i32 { + let result = Foo::B(123); + + match result { + Foo::A => unsafe { + let a = "A\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + Foo::B(x) => unsafe { + let a = "Result: %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, x); + }, + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-976.rs b/gcc/testsuite/rust/execute/torture/issue-976.rs new file mode 100644 index 00000000000..42cf596fb7d --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-976.rs @@ -0,0 +1,14 @@ +/* { dg-output "hi" } */ +fn main() -> i32 { + { + extern "C" { + fn puts(s: *const i8); + } + + unsafe { + puts("hi\0" as *const str as *const i8); + } + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/issue-995.rs b/gcc/testsuite/rust/execute/torture/issue-995.rs new file mode 100644 index 00000000000..42570e33f74 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-995.rs @@ -0,0 +1,9 @@ +struct Pattern(i32); + +fn pattern_as_arg(Pattern(value): Pattern) -> i32 { + value +} + +fn main() -> i32 { + pattern_as_arg(Pattern(15)) - 15 +} diff --git a/gcc/testsuite/rust/execute/torture/macros1.rs b/gcc/testsuite/rust/execute/torture/macros1.rs new file mode 100644 index 00000000000..652d2d8fe5b --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros1.rs @@ -0,0 +1,13 @@ +macro_rules! add { + ($a:expr,$b:expr) => { + $a + $b + }; +} + +fn test() -> i32 { + add!(1 + 2, 3) +} + +fn main() -> i32 { + test() - 6 +} diff --git a/gcc/testsuite/rust/execute/torture/macros10.rs b/gcc/testsuite/rust/execute/torture/macros10.rs new file mode 100644 index 00000000000..155a440ee04 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros10.rs @@ -0,0 +1,22 @@ +// { dg-output "18\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn print_int(value: i32) { + let s = "%d\n\0" as *const str as *const i8; + unsafe { + printf(s, value); + } +} + +macro_rules! add_exprs { + ($($e:expr)*) => (0 $(+ $e)*) +} + +fn main() -> i32 { + // 1 + 2 + 15 => 18 + print_int(add_exprs!(1 2 15)); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros11.rs b/gcc/testsuite/rust/execute/torture/macros11.rs new file mode 100644 index 00000000000..5bde97d3dd4 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros11.rs @@ -0,0 +1,25 @@ +// { dg-output "2" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn print_int(value: i32) { + let s = "%d\n\0"; + let s_p = s as *const str; + let c_p = s_p as *const i8; + unsafe { + printf(c_p, value); + } +} + +macro_rules! add_exprs { + ($($e:expr)?) => (0 $(+ $e)?) +} + +fn main() -> i32 { + // 2 + let a = add_exprs!(2); + print_int(a); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros12.rs b/gcc/testsuite/rust/execute/torture/macros12.rs new file mode 100644 index 00000000000..d310dff9ba8 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros12.rs @@ -0,0 +1,22 @@ +// { dg-output "0\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn print_int(value: i32) { + let s = "%d\n\0" as *const str as *const i8; + unsafe { + printf(s, value); + } +} + +macro_rules! add_exprs { + ($($e:expr)?) => (0 $(+ $e)?) +} + +fn main() -> i32 { + // 0 + print_int(add_exprs!()); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros13.rs b/gcc/testsuite/rust/execute/torture/macros13.rs new file mode 100644 index 00000000000..afb20264625 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros13.rs @@ -0,0 +1,22 @@ +// { dg-output "18\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn print_int(value: i32) { + let s = "%d\n\0" as *const str as *const i8; + unsafe { + printf(s, value); + } +} + +macro_rules! add_exprs { + ($($e:expr)+) => (0 $(+ $e)+) +} + +fn main() -> i32 { + // 1 + 2 + 15 => 18 + print_int(add_exprs!(1 2 15)); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros14.rs b/gcc/testsuite/rust/execute/torture/macros14.rs new file mode 100644 index 00000000000..00656546d4c --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros14.rs @@ -0,0 +1,22 @@ +// { dg-output "15\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn print_int(value: i32) { + let s = "%d\n\0" as *const str as *const i8; + unsafe { + printf(s, value); + } +} + +macro_rules! add_exprs { + ($($e:expr)*) => (15 $(+ $e)*) +} + +fn main() -> i32 { + // 15 + print_int(add_exprs!()); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros16.rs b/gcc/testsuite/rust/execute/torture/macros16.rs new file mode 100644 index 00000000000..47ab2411c0d --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros16.rs @@ -0,0 +1,14 @@ +macro_rules! add { + ($e:literal) => { + 0 + $e + }; + ($e:literal $($es:literal)*) => { + $e + add!($($es)*) + }; +} + +fn main() -> i32 { + let a = add!(1 2 3 10); // 16 + + a - 16 +} diff --git a/gcc/testsuite/rust/execute/torture/macros17.rs b/gcc/testsuite/rust/execute/torture/macros17.rs new file mode 100644 index 00000000000..390352ec47f --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros17.rs @@ -0,0 +1,17 @@ +macro_rules! two { + (2) => { + 3 + }; +} + +macro_rules! one { + (1) => {{ + two!(2) + }}; +} + +fn main() -> i32 { + let a = one!(1); + + a - 3 +} diff --git a/gcc/testsuite/rust/execute/torture/macros18.rs b/gcc/testsuite/rust/execute/torture/macros18.rs new file mode 100644 index 00000000000..61df17e9da5 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros18.rs @@ -0,0 +1,14 @@ +macro_rules! add { + ($e:literal) => { + 0 + $e + }; + ($e:literal $($es:literal)*) => { + $e + add!($($es)*) + }; +} + +fn main() -> i32 { + let a = add!(3 4); // 7 + + a - 7 +} diff --git a/gcc/testsuite/rust/execute/torture/macros19.rs b/gcc/testsuite/rust/execute/torture/macros19.rs new file mode 100644 index 00000000000..4732545410e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros19.rs @@ -0,0 +1,14 @@ +macro_rules! add { + ($e:expr, $($es:expr),*) => { + $e + add!($($es),*) + }; + ($e:expr) => { + $e + }; +} + +fn main() -> i32 { + let a = add!(15, 2, 9); // 26 + + a - 26 +} diff --git a/gcc/testsuite/rust/execute/torture/macros2.rs b/gcc/testsuite/rust/execute/torture/macros2.rs new file mode 100644 index 00000000000..ba5098710ea --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros2.rs @@ -0,0 +1,40 @@ +// { dg-output "arg\narg\narg\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn f() { + unsafe { + let r_s = "arg\n\0"; + let s_p = r_s as *const str; + let c_p = s_p as *const i8; + + printf(c_p); + } +} + +macro_rules! kw0 { + (keyword) => { + f(); + }; +} + +macro_rules! kw1 { + (fn) => { + f(); + }; +} + +macro_rules! kw2 { + (kw0 kw1 kw3) => { + f(); + }; +} + +fn main() -> i32 { + kw0!(keyword); + kw1!(fn); + kw2!(kw0 kw1 kw3); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros20.rs b/gcc/testsuite/rust/execute/torture/macros20.rs new file mode 100644 index 00000000000..97317a0879e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros20.rs @@ -0,0 +1,14 @@ +macro_rules! add { + ($e:expr , $($es:expr) , *) => { + $e + add!($($es) , *) + }; + ($e:expr) => { + $e + }; +} + +fn main() -> i32 { + let a = add!(15, 2, 9); // 26 + + a - 26 +} diff --git a/gcc/testsuite/rust/execute/torture/macros21.rs b/gcc/testsuite/rust/execute/torture/macros21.rs new file mode 100644 index 00000000000..2508be1a6fd --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros21.rs @@ -0,0 +1,15 @@ +macro_rules! add_parens { + ($($rep:ident ( ) )*) => { + { 0 $(+ $rep ( ))* } + }; +} + +fn f() -> i32 { + 1 +} + +fn main() -> i32 { + let a = add_parens!(f() f() f()); + + a - 3 +} diff --git a/gcc/testsuite/rust/execute/torture/macros22.rs b/gcc/testsuite/rust/execute/torture/macros22.rs new file mode 100644 index 00000000000..3f291ace98e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros22.rs @@ -0,0 +1,27 @@ +// { dg-output "1\n2\nNaN\n3\n" } + +macro_rules! print_num { + ($l:literal) => {{ + unsafe { + printf("%d\n\0" as *const str as *const i8, $l); + } + }}; +} + +extern "C" { + fn printf(s: *const i8, ...); +} + +// Check to make sure that expanding macros does not break the flow of calls +fn main() -> i32 { + print_num!(1); + print_num!(2); + + unsafe { + printf("NaN\n\0" as *const str as *const i8); + } + + print_num!(3); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros23.rs b/gcc/testsuite/rust/execute/torture/macros23.rs new file mode 100644 index 00000000000..846352d0487 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros23.rs @@ -0,0 +1,19 @@ +trait Valuable { + const VALUE: i32; +} + +struct Something; + +macro_rules! implement { + () => { + const VALUE: i32 = 18; + }; +} + +impl Valuable for Something { + implement!(); +} + +fn main() -> i32 { + Something::VALUE - 18 +} diff --git a/gcc/testsuite/rust/execute/torture/macros24.rs b/gcc/testsuite/rust/execute/torture/macros24.rs new file mode 100644 index 00000000000..f838a83af66 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros24.rs @@ -0,0 +1,9 @@ +macro_rules! repeat { + ( $( $i:literal ),* ; $( $j:literal ),* ) => (( $( ($i,$j) ),* )) +} + +fn main() -> i32 { + let t = repeat!(1, 1; 2, 2); + + t.0 .0 + t.0 .1 + t.1 .0 + t.1 .1 - 6 +} diff --git a/gcc/testsuite/rust/execute/torture/macros25.rs b/gcc/testsuite/rust/execute/torture/macros25.rs new file mode 100644 index 00000000000..c2658721bdf --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros25.rs @@ -0,0 +1,13 @@ +macro_rules! t { + ($t:tt) => { + $t + }; +} + +fn frob() -> i32 { + t!(15) + t!((14)) +} + +fn main() -> i32 { + frob() - 29 +} diff --git a/gcc/testsuite/rust/execute/torture/macros26.rs b/gcc/testsuite/rust/execute/torture/macros26.rs new file mode 100644 index 00000000000..30f0beef0d9 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros26.rs @@ -0,0 +1,12 @@ +macro_rules! count_tt { + ($t:tt) => { 1 }; + ($t:tt $($ts:tt)*) => { 1 + count_tt!($($ts)*) }; +} + +fn main() -> i32 { + let count = count_tt!(1 2 let a = 15) + count_tt!(1 2 (let a = 15)); + // ^ ^ ^^^ ^ ^ ^^ ^ ^ ^^^^^^^^^^^^ + // 6 token-trees 3 token-trees + + count - 9 +} diff --git a/gcc/testsuite/rust/execute/torture/macros27.rs b/gcc/testsuite/rust/execute/torture/macros27.rs new file mode 100644 index 00000000000..d515bb278a0 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros27.rs @@ -0,0 +1,24 @@ +// { dg-additional-options "-frust-cfg=A" } + +macro_rules! attr { + (#[$attr:meta] $s:stmt) => { + #[$attr] + $s; + }; +} + +fn main() -> i32 { + let mut a = 0; + + attr! { + #[cfg(A)] + a = 3 + }; + + attr! { + #[cfg(B)] + a = 40 + }; + + a - 3 +} diff --git a/gcc/testsuite/rust/execute/torture/macros28.rs b/gcc/testsuite/rust/execute/torture/macros28.rs new file mode 100644 index 00000000000..b011f924149 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros28.rs @@ -0,0 +1,13 @@ +macro_rules! t { + () => { + i32 + }; +} + +fn id(arg: T) -> T { + arg +} + +fn main() -> i32 { + id::(15) - 15 +} diff --git a/gcc/testsuite/rust/execute/torture/macros29.rs b/gcc/testsuite/rust/execute/torture/macros29.rs new file mode 100644 index 00000000000..306979b9b5b --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros29.rs @@ -0,0 +1,24 @@ +// { dg-output "1\n" } +#[rustc_builtin_macro] +macro_rules! concat { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: u32) { + unsafe { + printf("%u\n\0" as *const str as *const i8, s); + } +} + +fn main() -> i32 { + let res = concat!("test2") == "test3"; + if !res { + print(1); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros3.rs b/gcc/testsuite/rust/execute/torture/macros3.rs new file mode 100644 index 00000000000..00f6d253f50 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros3.rs @@ -0,0 +1,61 @@ +// { dg-output "invok\ninvok\ninvok\ninvok\ninvok\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn f() { + unsafe { + let r_s = "invok\n\0"; + let s_p = r_s as *const str; + let c_p = s_p as *const i8; + + printf(c_p); + } +} + +macro_rules! invocation0 { + (valid) => { + f(); + }; + () => {}; +} + +macro_rules! invocation1 { + (valid) => {}; + () => { + f(); + }; +} + +macro_rules! invocation2 { + (valid) => { + f(); + }; + (invalid) => {}; +} + +macro_rules! invocation3 { + (this is a valid invocation) => { + f(); + }; + (not this one) => {}; +} + +macro_rules! invocation4 { + (fn f() {}) => { + f(); + }; + (not a keyword) => {}; +} + +fn main() -> i32 { + invocation0!(valid); + invocation1!(); + invocation2!(valid); + invocation3!(this is a valid invocation); + invocation4!( + fn f() {} + ); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros30.rs b/gcc/testsuite/rust/execute/torture/macros30.rs new file mode 100644 index 00000000000..ab36f5e78af --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros30.rs @@ -0,0 +1,25 @@ +// { dg-output "1\n" } +#[rustc_builtin_macro] +macro_rules! concat { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: u32) { + unsafe { + printf("%u\n\0" as *const str as *const i8, s); + } +} + +fn main() -> i32 { + let mut x = concat!("x"); + x = concat!("y"); + if x == "y" { + print(1); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros31.rs b/gcc/testsuite/rust/execute/torture/macros31.rs new file mode 100644 index 00000000000..483f897a92b --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros31.rs @@ -0,0 +1,32 @@ +// { dg-additional-options "-w -frust-cfg=A" } +// { dg-output "A\nB\n" } +#[rustc_builtin_macro] +macro_rules! cfg { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: &str) { + unsafe { + printf( + "%s\n" as *const str as *const i8, + s as *const str as *const i8, + ); + } +} + +fn main() -> i32 { + let cfg = cfg!(A) || cfg!(B); + if cfg { + print("A"); + } + let cfg = cfg!(A) && cfg!(B); + if !cfg { + print("B"); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros4.rs b/gcc/testsuite/rust/execute/torture/macros4.rs new file mode 100644 index 00000000000..3303bfa58aa --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros4.rs @@ -0,0 +1,15 @@ +macro_rules! add { + ($a:expr,$b:expr) => { + $a + $b + }; + ($a:expr) => { + $a + }; +} + +fn main() -> i32 { + let mut x = add!(1); + x += add!(2, 3); + + x - 6 +} diff --git a/gcc/testsuite/rust/execute/torture/macros5.rs b/gcc/testsuite/rust/execute/torture/macros5.rs new file mode 100644 index 00000000000..822665494a4 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros5.rs @@ -0,0 +1,13 @@ +macro_rules! add { + ($a:expr,$b:expr) => {{ + $a + $b + }}; +} + +fn test() -> i32 { + add!(1, 2) +} + +fn main() -> i32 { + test() - 3 +} diff --git a/gcc/testsuite/rust/execute/torture/macros6.rs b/gcc/testsuite/rust/execute/torture/macros6.rs new file mode 100644 index 00000000000..652a765d5a8 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros6.rs @@ -0,0 +1,12 @@ +macro_rules! Test { + ($a:ident, $b:ty) => { + struct $a($b); + }; +} + +Test!(Foo, i32); + +fn main() -> i32 { + let a = Foo(123); + a.0 - 123 +} diff --git a/gcc/testsuite/rust/execute/torture/macros7.rs b/gcc/testsuite/rust/execute/torture/macros7.rs new file mode 100644 index 00000000000..ed1f922f581 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros7.rs @@ -0,0 +1,28 @@ +// { dg-output "any\nany\nany\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn f() { + let r_s = "any\n\0"; + let s_p = r_s as *const str; + let c_p = s_p as *const i8; + + unsafe { + printf(c_p); + } +} + +macro_rules! any { + ($($a:expr)*) => { + f(); + }; +} + +fn main() -> i32 { + any!(); + any!(a + b); + any!(a + b 14 "gcc"); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros8.rs b/gcc/testsuite/rust/execute/torture/macros8.rs new file mode 100644 index 00000000000..a12aca4910e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros8.rs @@ -0,0 +1,27 @@ +// { dg-output "zo1\nzo1\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn f() { + let r_s = "zo1\n\0"; + let s_p = r_s as *const str; + let c_p = s_p as *const i8; + + unsafe { + printf(c_p); + } +} + +macro_rules! zero_or_one { + ($($a:expr)?) => { + f(); + }; +} + +fn main() -> i32 { + zero_or_one!(); + zero_or_one!(f()); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros9.rs b/gcc/testsuite/rust/execute/torture/macros9.rs new file mode 100644 index 00000000000..0e3fd24e8a9 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros9.rs @@ -0,0 +1,28 @@ +// { dg-output "oom\noom\noom\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn f() { + let r_s = "oom\n\0"; + let s_p = r_s as *const str; + let c_p = s_p as *const i8; + + unsafe { + printf(c_p); + } +} + +macro_rules! one_or_more { + ($($a:expr)+) => { + f(); + }; +} + +fn main() -> i32 { + one_or_more!(f()); + one_or_more!(f() f()); + one_or_more!(f() f() 15 + 12); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match1.rs b/gcc/testsuite/rust/execute/torture/match1.rs new file mode 100644 index 00000000000..e5af512f15d --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match1.rs @@ -0,0 +1,58 @@ +// { dg-output "Foo::A\nFoo::B\nFoo::C x\nFoo::D 20 80\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Foo { + A, + B, + C(char), + D { x: i32, y: i32 }, +} + +fn inspect(f: Foo) { + match f { + Foo::A => unsafe { + let a = "Foo::A\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + Foo::B => unsafe { + let a = "Foo::B\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + Foo::C(x) => unsafe { + let a = "Foo::C %c\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, x); + }, + Foo::D { x, y } => unsafe { + let a = "Foo::D %i %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, x, y); + }, + } +} + +fn main() -> i32 { + let a = Foo::A; + let b = Foo::B; + let c = Foo::C('x'); + let d = Foo::D { x: 20, y: 80 }; + + inspect(a); + inspect(b); + inspect(c); + inspect(d); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match2.rs b/gcc/testsuite/rust/execute/torture/match2.rs new file mode 100644 index 00000000000..02cedf29b3c --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match2.rs @@ -0,0 +1,41 @@ +// { dg-output "123\n80\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Foo { + C(i32), + D { x: i32, y: i32 }, +} + +fn inspect(f: Foo) -> i32 { + match f { + Foo::C(x) => x, + Foo::D { x, y } => y, + } +} + +fn main() -> i32 { + let a = Foo::C(123); + let b = Foo::D { x: 20, y: 80 }; + + let result = inspect(a); + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, result); + } + + let result = inspect(b); + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, result); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match3.rs b/gcc/testsuite/rust/execute/torture/match3.rs new file mode 100644 index 00000000000..8cded3044df --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match3.rs @@ -0,0 +1,51 @@ +// { dg-output "Foo::A\nwildcard\nwildcard\nFoo::D 20 80\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Foo { + A, + B, + C(char), + D { x: i32, y: i32 }, +} + +fn inspect(f: Foo) { + match f { + Foo::A => unsafe { + let a = "Foo::A\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + Foo::D { x, y } => unsafe { + let a = "Foo::D %i %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, x, y); + }, + _ => unsafe { + let a = "wildcard\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + } +} + +fn main() -> i32 { + let a = Foo::A; + let b = Foo::B; + let c = Foo::C('x'); + let d = Foo::D { x: 20, y: 80 }; + + inspect(a); + inspect(b); + inspect(c); + inspect(d); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match_bool1.rs b/gcc/testsuite/rust/execute/torture/match_bool1.rs new file mode 100644 index 00000000000..101dbb58571 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_bool1.rs @@ -0,0 +1,49 @@ +// { dg-output "182 is more than 100\n55 is less than 100\n" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +fn foo(x: bool) -> i32 { + match x { + true => { + return 182; + } + false => { + return 55; + } + } +} + +fn bar(y: i32) { + match y < 100 { + true => { + let a = "%i is less than 100\n\0"; + let b = a as *const str; + let c = b as *const i8; + + unsafe { + printf(c, y); + } + } + _ => { + let a = "%i is more than 100\n\0"; + let b = a as *const str; + let c = b as *const i8; + + unsafe { + printf(c, y); + } + } + } +} + +fn main() -> i32 { + let a = foo(true); + let b = foo(false); + + bar(a); + bar(b); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match_byte1.rs b/gcc/testsuite/rust/execute/torture/match_byte1.rs new file mode 100644 index 00000000000..3546cfb9d8b --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_byte1.rs @@ -0,0 +1,56 @@ +// { dg-output "a\nseven\nquote\nelse" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +fn foo(x: u8) { + match x { + b'a' => { + let a = "a\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + b'\x07' => { + let a = "seven\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + b'\'' => { + let a = "quote\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + _ => { + let a = "else\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + } +} + +fn main() -> i32 { + let x: u8 = 7; + + foo(b'a'); + foo(x); + foo(b'\''); + foo(b'\\'); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match_char1.rs b/gcc/testsuite/rust/execute/torture/match_char1.rs new file mode 100644 index 00000000000..fa65876a907 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_char1.rs @@ -0,0 +1,56 @@ +// { dg-output "amazing\nwildcard\ncompiler\nproductivity\n" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +fn foo(x: char) { + match x { + 'a' => { + let a = "amazing\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + 'c' => { + let a = "compiler\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + 'p' => { + let a = "productivity\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + _ => { + let a = "wildcard\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + } +} + +fn main() -> i32 { + let p = 'p'; + + foo('a'); + foo('b'); + foo('c'); + foo(p); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match_int1.rs b/gcc/testsuite/rust/execute/torture/match_int1.rs new file mode 100644 index 00000000000..209429added --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_int1.rs @@ -0,0 +1,109 @@ +// { dg-output "other!\nother!\nother!\nfifteen!\nfifteen!\nother!\nother!\nfifteen!\n" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +fn foo_i32(x: i32) { + match x { + 15 => { + let a = "fifteen!\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + _ => { + let a = "other!\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + } +} + +fn foo_isize(x: isize) { + match x { + 15 => { + let a = "fifteen!\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + _ => { + let a = "other!\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + } +} + +fn foo_u32(x: u32) { + match x { + 15 => { + let a = "fifteen!\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + _ => { + let a = "other!\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + } +} + +fn foo_usize(x: usize) { + match x { + 15 => { + let a = "fifteen!\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + _ => { + let a = "other!\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + } +} + +fn main() -> i32 { + let x = -2; + foo_i32(x); + foo_i32(334); + foo_isize(-4768); + foo_isize(15); + + let y = 127; + foo_u32(15); + foo_u32(y); + foo_usize(2394); + foo_usize(15); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match_loop1.rs b/gcc/testsuite/rust/execute/torture/match_loop1.rs new file mode 100644 index 00000000000..bb6aee946f6 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_loop1.rs @@ -0,0 +1,56 @@ +// { dg-output "E::One\nE::Two\nbreak!\n" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +enum E { + One, + Two, + Other, +} + +fn foo() { + let mut x = E::One; + + loop { + match x { + E::One => { + let a = "E::One\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + + x = E::Two; + } + E::Two => { + let a = "E::Two\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + + x = E::Other; + } + _ => { + let a = "break!\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + + break; + } + } + } +} + +fn main() -> i32 { + foo(); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match_range1.rs b/gcc/testsuite/rust/execute/torture/match_range1.rs new file mode 100644 index 00000000000..82e9e34a989 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_range1.rs @@ -0,0 +1,37 @@ +// { dg-output "zero to END_RANGE\nzero to END_RANGE\nelse\n" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +const END_RANGE: i32 = 15; + +fn foo(x: i32) { + match x { + 0..=END_RANGE => { + let a = "zero to END_RANGE\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + + _ => { + let a = "else\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + } +} + +fn main() -> i32 { + foo(11); + foo(15); + foo(21); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match_range2.rs b/gcc/testsuite/rust/execute/torture/match_range2.rs new file mode 100644 index 00000000000..8153f9e1c7e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_range2.rs @@ -0,0 +1,45 @@ +// { dg-output "lowercase\nuppercase\nother\n" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +const BIG_A: char = 'A'; +const BIG_Z: char = 'Z'; + +fn bar(x: char) { + match x { + 'a'..='z' => { + let a = "lowercase\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + BIG_A..=BIG_Z => { + let a = "uppercase\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + _ => { + let a = "other\n\0"; + let b = a as *const str; + let c = b as *const i8; + unsafe { + printf(c); + } + } + } +} + +fn main() -> i32 { + bar('b'); + bar('X'); + bar('!'); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match_tuple1.rs b/gcc/testsuite/rust/execute/torture/match_tuple1.rs new file mode 100644 index 00000000000..cb61cc0847c --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_tuple1.rs @@ -0,0 +1,45 @@ +// { dg-output "x:15\ny:20\n" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Foo { + A, + B, +} + +fn inspect(f: Foo, g: u8) -> i32 { + match (f, g) { + (Foo::A, 1) => { + return 5; + } + + (Foo::A, 2) => { + return 10; + } + + (Foo::B, 2) => { + return 15; + } + + _ => { + return 20; + } + } + return 25; +} + +fn main() -> i32 { + let x = inspect(Foo::B, 2); + let y = inspect(Foo::B, 1); + + unsafe { + printf("x:%d\n" as *const str as *const i8, x); + } + unsafe { + printf("y:%d\n" as *const str as *const i8, y); + } + + y - x - 5 +} diff --git a/gcc/testsuite/rust/execute/torture/method1.rs b/gcc/testsuite/rust/execute/torture/method1.rs new file mode 100644 index 00000000000..6af6133939b --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/method1.rs @@ -0,0 +1,27 @@ +/* { dg-output "124\n458" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(i32); +impl Foo { + fn bar(&self, i: i32) { + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, self.0 + i); + } + } +} + +fn main() -> i32 { + let a = Foo(123); + a.bar(1); + + let b = &Foo(456); + b.bar(2); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/method2.rs b/gcc/testsuite/rust/execute/torture/method2.rs new file mode 100644 index 00000000000..f532b4488c6 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/method2.rs @@ -0,0 +1,76 @@ +// { dg-additional-options "-w" } +// { dg-output "foo_deref\nimm_deref\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "deref"] +pub trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +impl Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "imm_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +impl Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "mut_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +struct Bar(i32); +impl Bar { + fn foobar(self) -> i32 { + self.0 + } +} + +struct Foo(T); +impl Deref for Foo { + type Target = T; + + fn deref(&self) -> &Self::Target { + unsafe { + let a = "foo_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + &self.0 + } +} + +pub fn main() -> i32 { + let bar = Bar(123); + let foo: Foo<&Bar> = Foo(&bar); + let foobar: i32 = foo.foobar(); + + foobar - 123 +} diff --git a/gcc/testsuite/rust/execute/torture/method3.rs b/gcc/testsuite/rust/execute/torture/method3.rs new file mode 100644 index 00000000000..0e9e8ff42a0 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/method3.rs @@ -0,0 +1,78 @@ +// { dg-additional-options "-w" } +// { dg-output "mut_deref\nfoobar: 123\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "deref"] +pub trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +#[lang = "deref_mut"] +pub trait DerefMut: Deref { + fn deref_mut(&mut self) -> &mut Self::Target; +} + +impl Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + +impl Deref for &mut T { + type Target = T; + fn deref(&self) -> &T { + *self + } +} + +pub struct Bar(i32); +impl Bar { + pub fn foobar(&mut self) -> i32 { + self.0 + } +} + +pub struct Foo(T); +impl Deref for Foo { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { + let a = "mut_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + &mut self.0 + } +} + +pub fn main() -> i32 { + let bar = Bar(123); + let mut foo: Foo = Foo(bar); + let foobar = foo.foobar(); + + unsafe { + let a = "foobar: %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, foobar); + } + + foobar - 123 +} diff --git a/gcc/testsuite/rust/execute/torture/method4.rs b/gcc/testsuite/rust/execute/torture/method4.rs new file mode 100644 index 00000000000..5c6fdfe02c3 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/method4.rs @@ -0,0 +1,78 @@ +// { dg-additional-options "-w" } +// { dg-output "mut_deref\nfoobar: 123\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "deref"] +pub trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +#[lang = "deref_mut"] +pub trait DerefMut: Deref { + fn deref_mut(&mut self) -> &mut Self::Target; +} + +impl Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + *self + } +} + +impl Deref for &mut T { + type Target = T; + fn deref(&self) -> &T { + *self + } +} + +pub struct Bar(i32); +impl Bar { + pub fn foobar(&mut self) -> i32 { + self.0 + } +} + +pub struct Foo(T); +impl Deref for Foo { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { + let a = "mut_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + &mut self.0 + } +} + +pub fn main() -> i32 { + let mut bar = Bar(123); + let mut foo: Foo<&mut Bar> = Foo(&mut bar); + let foobar = foo.foobar(); + + unsafe { + let a = "foobar: %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, foobar); + } + + foobar - 123 +} diff --git a/gcc/testsuite/rust/execute/torture/mod1.rs b/gcc/testsuite/rust/execute/torture/mod1.rs new file mode 100644 index 00000000000..700393850af --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/mod1.rs @@ -0,0 +1,21 @@ +mod A { + pub mod B { + pub mod C { + pub struct Foo { + pub f: i32, + } + impl Foo { + pub fn new() -> Self { + Foo { f: 23i32 } + } + } + } + } +} + +fn main() -> i32 { + let a = A::B::C::Foo::new(); + let b = A::B::C::Foo { f: -23i32 }; + + a.f + b.f +} diff --git a/gcc/testsuite/rust/execute/torture/modules/mod.rs b/gcc/testsuite/rust/execute/torture/modules/mod.rs new file mode 100644 index 00000000000..9020aaf4bb8 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/modules/mod.rs @@ -0,0 +1,3 @@ +fn return_12() -> i32 { + 12 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_1.rs b/gcc/testsuite/rust/execute/torture/operator_overload_1.rs new file mode 100644 index 00000000000..5a28c5f4e93 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_1.rs @@ -0,0 +1,36 @@ +/* { dg-output "3\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "add"] +pub trait Add { + type Output; + + fn add(self, rhs: Rhs) -> Self::Output; +} + +impl Add for i32 { + type Output = i32; + + fn add(self, other: i32) -> i32 { + let res = self + other; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, res); + } + + res + } +} + +fn main() -> i32 { + let a; + a = 1 + 2; + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_10.rs b/gcc/testsuite/rust/execute/torture/operator_overload_10.rs new file mode 100644 index 00000000000..f5d45db5338 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_10.rs @@ -0,0 +1,75 @@ +/* { dg-output "foo_deref\n123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "deref"] +pub trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +impl Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "imm_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +impl Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "mut_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +struct Foo(T); +impl Deref for Foo { + type Target = T; + + fn deref(&self) -> &Self::Target { + unsafe { + let a = "foo_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + &self.0 + } +} + +fn main() -> i32 { + let foo: Foo = Foo(123); + let bar: i32 = *foo; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, bar); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_11.rs b/gcc/testsuite/rust/execute/torture/operator_overload_11.rs new file mode 100644 index 00000000000..1919941c486 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_11.rs @@ -0,0 +1,37 @@ +// { dg-output "1\n" } +// { dg-additional-options "-w" } +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "bitand"] +pub trait BitAnd { + type Output; + + fn bitand(self, rhs: Rhs) -> Self::Output; +} + +impl BitAnd for i32 { + type Output = i32; + + fn bitand(self, other: i32) -> i32 { + let res = self & other; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, res); + } + + res + } +} + +fn main() -> i32 { + let a; + a = 1 & 1; + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_12.rs b/gcc/testsuite/rust/execute/torture/operator_overload_12.rs new file mode 100644 index 00000000000..7433330fa31 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_12.rs @@ -0,0 +1,31 @@ +// { dg-output "1\n" } +// { dg-additional-options "-w" } +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "bitand_assign"] +pub trait BitAndAssign { + fn bitand_assign(&mut self, rhs: Rhs); +} + +impl BitAndAssign for i32 { + fn bitand_assign(&mut self, other: i32) { + *self &= other; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, *self); + } + } +} + +fn main() -> i32 { + let mut a = 1; + a &= 1; + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_2.rs b/gcc/testsuite/rust/execute/torture/operator_overload_2.rs new file mode 100644 index 00000000000..a577718451d --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_2.rs @@ -0,0 +1,38 @@ +/* { dg-output "3\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "add"] +pub trait Add { + type Output; + + fn add(self, rhs: Rhs) -> Self::Output; +} + +struct Foo(i32); + +impl Add for Foo { + type Output = Foo; + + fn add(self, other: Foo) -> Foo { + let res = Foo(self.0 + other.0); + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, res.0); + } + + res + } +} + +fn main() -> i32 { + let a; + a = Foo(1) + Foo(2); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_3.rs b/gcc/testsuite/rust/execute/torture/operator_overload_3.rs new file mode 100644 index 00000000000..57f58076c3e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_3.rs @@ -0,0 +1,55 @@ +/* { dg-output "3\n3\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "add"] +pub trait Add { + type Output; + + fn add(self, rhs: Rhs) -> Self::Output; +} + +impl Add for i32 { + type Output = i32; + + fn add(self, other: i32) -> i32 { + let res = self + other; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, res); + } + + res + } +} + +struct Foo(i32); +impl Add for Foo { + type Output = Foo; + + fn add(self, other: Foo) -> Foo { + let res = Foo(self.0 + other.0); + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, res.0); + } + + res + } +} + +fn main() -> i32 { + let a; + a = Foo(1) + Foo(2); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_4.rs b/gcc/testsuite/rust/execute/torture/operator_overload_4.rs new file mode 100644 index 00000000000..ce9887b2ead --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_4.rs @@ -0,0 +1,33 @@ +/* { dg-output "neg\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "neg"] +pub trait Neg { + type Output; + + fn neg(self) -> Self::Output; +} + +impl Neg for i32 { + type Output = i32; + + fn neg(self) -> i32 { + unsafe { + let a = "neg\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + -self + } +} + +fn main() -> i32 { + let a: i32 = 1; + let _b = -a; + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_5.rs b/gcc/testsuite/rust/execute/torture/operator_overload_5.rs new file mode 100644 index 00000000000..a525f743680 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_5.rs @@ -0,0 +1,33 @@ +/* { dg-output "not\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "not"] +pub trait Not { + type Output; + + fn not(self) -> Self::Output; +} + +impl Not for i32 { + type Output = i32; + + fn not(self) -> i32 { + unsafe { + let a = "not\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + !self + } +} + +fn main() -> i32 { + let a: i32 = 1; + let _b = !a; + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_6.rs b/gcc/testsuite/rust/execute/torture/operator_overload_6.rs new file mode 100644 index 00000000000..fbd2a8fa9d3 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_6.rs @@ -0,0 +1,37 @@ +/* { dg-output "add_assign\n3\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "add_assign"] +pub trait AddAssign { + fn add_assign(&mut self, rhs: Rhs); +} + +impl AddAssign for i32 { + fn add_assign(&mut self, other: i32) { + unsafe { + let a = "add_assign\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + *self += other + } +} + +fn main() -> i32 { + let mut res = 1; + res += 2; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, res); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_7.rs b/gcc/testsuite/rust/execute/torture/operator_overload_7.rs new file mode 100644 index 00000000000..886a7010efc --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_7.rs @@ -0,0 +1,42 @@ +/* { dg-output "imm_deref\n123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "deref"] +pub trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +impl Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "imm_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +fn main() -> i32 { + let foo: &i32 = &123; + let res: i32 = *foo; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, res); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_8.rs b/gcc/testsuite/rust/execute/torture/operator_overload_8.rs new file mode 100644 index 00000000000..862e29a4bc6 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_8.rs @@ -0,0 +1,58 @@ +/* { dg-output "imm_deref\n123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "deref"] +pub trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +impl Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "imm_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +impl Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "mut_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +fn main() -> i32 { + let foo: &i32 = &123; + let res: i32 = *foo; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, res); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_9.rs b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs new file mode 100644 index 00000000000..fd972e28ab3 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/operator_overload_9.rs @@ -0,0 +1,58 @@ +/* { dg-output "mut_deref\n123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "deref"] +pub trait Deref { + type Target; + + fn deref(&self) -> &Self::Target; +} + +impl Deref for &T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "imm_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +impl Deref for &mut T { + type Target = T; + + fn deref(&self) -> &T { + unsafe { + let a = "mut_deref\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + + *self + } +} + +fn main() -> i32 { + let foo = &mut 123; + let res: i32 = *foo; + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, res); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/slice-magic.rs b/gcc/testsuite/rust/execute/torture/slice-magic.rs new file mode 100644 index 00000000000..d1132989ddb --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/slice-magic.rs @@ -0,0 +1,106 @@ +// { dg-additional-options "-w" } +extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + pub fn offset(dst: *const T, offset: isize) -> *const T; +} + +struct FatPtr { + data: *const T, + len: usize, +} + +union Repr { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr, +} + +#[lang = "Range"] +pub struct Range { + pub start: Idx, + pub end: Idx, +} + +#[lang = "const_slice_ptr"] +impl *const [A] { + pub const fn len(self) -> usize { + unsafe { Repr { rust: self }.raw.len } + } + + pub const fn as_ptr(self) -> *const A { + self as *const A + } +} + +#[lang = "const_ptr"] +impl *const B { + pub const unsafe fn offset(self, count: isize) -> *const B { + unsafe { offset(self, count) } + } + + pub const unsafe fn add(self, count: usize) -> Self { + unsafe { self.offset(count as isize) } + } + + pub const fn as_ptr(self) -> *const B { + self as *const B + } +} + +const fn slice_from_raw_parts(data: *const C, len: usize) -> *const [C] { + unsafe { + Repr { + raw: FatPtr { data, len }, + } + .rust + } +} + +#[lang = "index"] +trait Index { + type Output; + + fn index(&self, index: Idx) -> &Self::Output; +} + +pub unsafe trait SliceIndex { + type Output; + + unsafe fn get_unchecked(self, slice: *const X) -> *const Self::Output; + + fn index(self, slice: &X) -> &Self::Output; +} + +unsafe impl SliceIndex<[Y]> for Range { + type Output = [Y]; + + unsafe fn get_unchecked(self, slice: *const [Y]) -> *const [Y] { + unsafe { + let a: *const Y = slice.as_ptr(); + let b: *const Y = a.add(self.start); + slice_from_raw_parts(b, self.end - self.start) + } + } + + fn index(self, slice: &[Y]) -> &[Y] { + unsafe { &*self.get_unchecked(slice) } + } +} + +impl Index for [T] +where + I: SliceIndex<[T]>, +{ + type Output = I::Output; + + fn index(&self, index: I) -> &I::Output { + index.index(self) + } +} + +fn main() -> i32 { + let a = [1, 2, 3, 4, 5]; + let b = &a[1..3]; + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/slice-magic2.rs b/gcc/testsuite/rust/execute/torture/slice-magic2.rs new file mode 100644 index 00000000000..64a566185fa --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/slice-magic2.rs @@ -0,0 +1,106 @@ +// { dg-additional-options "-w" } +extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] + pub fn offset(dst: *const T, offset: isize) -> *const T; +} + +struct FatPtr { + data: *const T, + len: usize, +} + +union Repr { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr, +} + +#[lang = "Range"] +pub struct Range { + pub start: Idx, + pub end: Idx, +} + +#[lang = "const_slice_ptr"] +impl *const [T] { + pub const fn len(self) -> usize { + unsafe { Repr { rust: self }.raw.len } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +#[lang = "const_ptr"] +impl *const T { + pub const unsafe fn offset(self, count: isize) -> *const T { + unsafe { offset(self, count) } + } + + pub const unsafe fn add(self, count: usize) -> Self { + unsafe { self.offset(count as isize) } + } + + pub const fn as_ptr(self) -> *const T { + self as *const T + } +} + +const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { + unsafe { + Repr { + raw: FatPtr { data, len }, + } + .rust + } +} + +#[lang = "index"] +trait Index { + type Output; + + fn index(&self, index: Idx) -> &Self::Output; +} + +pub unsafe trait SliceIndex { + type Output; + + unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output; + + fn index(self, slice: &T) -> &Self::Output; +} + +unsafe impl SliceIndex<[T]> for Range { + type Output = [T]; + + unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { + unsafe { + let a: *const T = slice.as_ptr(); + let b: *const T = a.add(self.start); + slice_from_raw_parts(b, self.end - self.start) + } + } + + fn index(self, slice: &[T]) -> &[T] { + unsafe { &*self.get_unchecked(slice) } + } +} + +impl Index for [T] +where + I: SliceIndex<[T]>, +{ + type Output = I::Output; + + fn index(&self, index: I) -> &I::Output { + index.index(self) + } +} + +fn main() -> i32 { + let a = [1, 2, 3, 4, 5]; + let b = &a[1..3]; + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/slice1.rs b/gcc/testsuite/rust/execute/torture/slice1.rs new file mode 100644 index 00000000000..a0488b3912c --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/slice1.rs @@ -0,0 +1,27 @@ +// { dg-additional-options "-w" } +struct FatPtr { + data: *const T, + len: usize, +} + +union Repr { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr, +} + +const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { + unsafe { + let a = FatPtr { data, len }; + let b = Repr { raw: a }; + b.rust + } +} + +fn main() -> i32 { + let a = 123; + let b: *const i32 = &a; + let c = slice_from_raw_parts(b, 1); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/str-layout1.rs b/gcc/testsuite/rust/execute/torture/str-layout1.rs new file mode 100644 index 00000000000..80bdc2a9c9f --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/str-layout1.rs @@ -0,0 +1,57 @@ +// { dg-additional-options "-w" } +// { dg-output "t1sz=5 t2sz=10" } +mod mem { + extern "rust-intrinsic" { + #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")] + fn transmute(_: T) -> U; + } +} + +extern "C" { + fn printf(s: *const i8, ...); +} + +struct FatPtr { + data: *const T, + len: usize, +} + +pub union Repr { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr, +} + +impl [T] { + pub const fn len(&self) -> usize { + unsafe { Repr { rust: self }.raw.len } + } +} + +impl str { + pub const fn len(&self) -> usize { + self.as_bytes().len() + } + + pub const fn as_bytes(&self) -> &[u8] { + unsafe { mem::transmute(self) } + } +} + +fn main() -> i32 { + let t1: &str = "TEST1"; + let t2: &str = &"TEST_12345"; + + let t1sz = t1.len(); + let t2sz = t2.len(); + + unsafe { + let a = "t1sz=%i t2sz=%i\n"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, t1sz as i32, t2sz as i32); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/str-zero.rs b/gcc/testsuite/rust/execute/torture/str-zero.rs new file mode 100644 index 00000000000..e7fba0d1372 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/str-zero.rs @@ -0,0 +1,26 @@ +/* { dg-output "bar foo baz foobar\n" } */ +extern "C" +{ + fn printf(s: *const i8, ...); + fn memchr(s: *const i8, c: u8, n: usize) -> *const i8; +} + +pub fn main () -> i32 +{ + let f = "%s %s %s %s\n\0"; + let s = "bar\0\ + foo\ + \x00\ + baz\u{0000}\ + foobar\0"; + let cf = f as *const str as *const i8; + let cs = s as *const str as *const i8; + unsafe + { + let cs2 = memchr (cs, b'f', 5); + let cs3 = memchr (cs2, b'b', 5); + let cs4 = memchr (cs3, b'f', 5); + printf (cf, cs, cs2, cs3, cs4); + } + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait1.rs b/gcc/testsuite/rust/execute/torture/trait1.rs new file mode 100644 index 00000000000..dc3cc471c33 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait1.rs @@ -0,0 +1,52 @@ +/* { dg-output "S::f\nT1::f\nT2::f\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +struct S; + +impl S { + fn f() { + unsafe { + let a = "S::f\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + } +} + +trait T1 { + fn f() { + unsafe { + let a = "T1::f\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + } +} +impl T1 for S {} + +trait T2 { + fn f() { + unsafe { + let a = "T2::f\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + } + } +} +impl T2 for S {} + +fn main() -> i32 { + S::f(); + ::f(); + ::f(); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait10.rs b/gcc/testsuite/rust/execute/torture/trait10.rs new file mode 100644 index 00000000000..e581e324bbf --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait10.rs @@ -0,0 +1,41 @@ +/* { dg-output "123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(i32); +trait Bar { + fn baz(&self); +} + +impl Bar for Foo { + fn baz(&self) { + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, self.0); + } + } +} + +struct S; +impl S { + fn dynamic_dispatch(self, t: &dyn Bar) { + // { dg-warning "unused name" "" { target *-*-* } .-1 } + t.baz(); + } +} + +pub fn main() -> i32 { + let a; + a = &Foo(123); + + let b; + b = S; + + b.dynamic_dispatch(a); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait11.rs b/gcc/testsuite/rust/execute/torture/trait11.rs new file mode 100644 index 00000000000..283c9ecd0ed --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait11.rs @@ -0,0 +1,38 @@ +/* { dg-output "3\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +struct S; +impl<'a, T> FnLike<&'a T, &'a T> for S { + fn call(&self, arg: &'a T) -> &'a T { + // { dg-warning "unused name .self." "" { target *-*-* } .-1 } + arg + } +} + +fn indirect(f: F) +where + F: for<'a> FnLike<&'a isize, &'a isize>, +{ + let x = 3; + let y = f.call(&x); + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, *y); + } +} + +fn main() -> i32 { + indirect(S); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait12.rs b/gcc/testsuite/rust/execute/torture/trait12.rs new file mode 100644 index 00000000000..68b0a4014ad --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait12.rs @@ -0,0 +1,38 @@ +/* { dg-output "3\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +type FnObject<'b> = dyn for<'a> FnLike<&'a isize, &'a isize> + 'b; + +struct Identity; + +impl<'a, T> FnLike<&'a T, &'a T> for Identity { + fn call(&self, arg: &'a T) -> &'a T { + // { dg-warning "unused name .self." "" { target *-*-* } .-1 } + arg + } +} + +fn call_repeatedly(f: &FnObject) { + let x = 3; + let y = f.call(&x); + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, *y); + } +} + +fn main() -> i32 { + call_repeatedly(&Identity); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait13.rs b/gcc/testsuite/rust/execute/torture/trait13.rs new file mode 100644 index 00000000000..3071da27a6a --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait13.rs @@ -0,0 +1,48 @@ +/* { dg-output "123\n456\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(i32); +trait Bar { + fn baz(&self); + + fn qux(&self) { + // { dg-warning "unused name" "" { target *-*-* } .-1 } + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, 456); + } + } +} + +impl Bar for Foo { + fn baz(&self) { + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, self.0); + } + } +} + +fn dynamic_dispatch(t: &dyn Bar) { + t.baz(); + t.qux(); +} + +fn main() -> i32 { + let a; + a = Foo(123); + + let b: &dyn Bar; + b = &a; + dynamic_dispatch(b); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait2.rs b/gcc/testsuite/rust/execute/torture/trait2.rs new file mode 100644 index 00000000000..c96615fa891 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait2.rs @@ -0,0 +1,37 @@ +/* { dg-output "Bar::A = 456\n::A = 456\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +trait Foo { + const A: i32 = 123; +} + +struct Bar; +impl Foo for Bar { + const A: i32 = 456; +} + +fn main() -> i32 { + let a; + a = Bar::A; + + unsafe { + let _a = "Bar::A = %i\n\0"; + let _b = _a as *const str; + let _c = _b as *const i8; + printf(_c, a); + } + + let b; + b = ::A; + + unsafe { + let _a = "::A = %i\n\0"; + let _b = _a as *const str; + let _c = _b as *const i8; + printf(_c, b); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait3.rs b/gcc/testsuite/rust/execute/torture/trait3.rs new file mode 100644 index 00000000000..accfa9d0a36 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait3.rs @@ -0,0 +1,43 @@ +/* { dg-output "123, 777" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +trait A { + fn a() -> i32 { + 123 + } +} + +trait B: A { + fn b() -> i32 { + ::a() + 456 + } +} + +struct T; +// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 } + +impl A for T { + fn a() -> i32 { + 321 + } +} + +struct S; +impl A for S {} +impl B for S {} + +fn main() -> i32 { + let aa = S::a(); + let bb = S::b(); + + unsafe { + let a = "%i, %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, aa, bb); + } + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait4.rs b/gcc/testsuite/rust/execute/torture/trait4.rs new file mode 100644 index 00000000000..8c0d257cd7e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait4.rs @@ -0,0 +1,34 @@ +/* { dg-output "123\n" }*/ +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(i32); +trait Bar { + fn baz(&self); +} + +impl Bar for Foo { + fn baz(&self) { + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, self.0); + } + } +} + +fn type_bound(t: &T) { + t.baz(); +} + +fn main() -> i32 { + let a; + + a = &Foo(123); + type_bound(a); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait5.rs b/gcc/testsuite/rust/execute/torture/trait5.rs new file mode 100644 index 00000000000..49f11a6085a --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait5.rs @@ -0,0 +1,39 @@ +/* { dg-output "123\n123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +struct Foo(i32); +trait Bar { + fn baz(&self); +} + +impl Bar for Foo { + fn baz(&self) { + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, self.0); + } + } +} + +fn static_dispatch(t: &T) { + t.baz(); +} + +fn dynamic_dispatch(t: &dyn Bar) { + t.baz(); +} + +fn main() -> i32 { + let a = &Foo(123); + static_dispatch(a); + + let b: &dyn Bar = a; + dynamic_dispatch(b); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait6.rs b/gcc/testsuite/rust/execute/torture/trait6.rs new file mode 100644 index 00000000000..c83d6666c87 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait6.rs @@ -0,0 +1,39 @@ +/* { dg-output "123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +pub trait Foo { + type A; + + fn bar(self) -> Self::A; +} + +struct S(i32); +impl Foo for S { + type A = i32; + + fn bar(self) -> Self::A { + self.0 + } +} + +fn test_bar(x: T) -> T::A { + x.bar() +} + +fn main() -> i32 { + let a; + a = S(123); + + let bar: i32 = test_bar::(a); + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, bar); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait7.rs b/gcc/testsuite/rust/execute/torture/trait7.rs new file mode 100644 index 00000000000..064f88d5de9 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait7.rs @@ -0,0 +1,39 @@ +/* { dg-output "123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +pub trait Foo { + type A; + + fn bar(self) -> Self::A; +} + +struct S(i32); +impl Foo for S { + type A = i32; + + fn bar(self) -> Self::A { + self.0 + } +} + +fn test_bar(x: T) -> T::A { + x.bar() +} + +fn main() -> i32 { + let a; + a = S(123); + + let bar: i32 = test_bar(a); + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, bar); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait8.rs b/gcc/testsuite/rust/execute/torture/trait8.rs new file mode 100644 index 00000000000..14392ff0cca --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait8.rs @@ -0,0 +1,39 @@ +/* { dg-output "123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +pub trait Foo { + type A; + + fn bar(&self) -> Self::A; +} + +struct S(i32); +impl Foo for S { + type A = i32; + + fn bar(&self) -> Self::A { + self.0 + } +} + +fn test_bar(x: T) -> T::A { + x.bar() +} + +fn main() -> i32 { + let a; + a = S(123); + + let bar: i32 = test_bar(a); + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, bar); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/trait9.rs b/gcc/testsuite/rust/execute/torture/trait9.rs new file mode 100644 index 00000000000..c0e6d36f183 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/trait9.rs @@ -0,0 +1,35 @@ +/* { dg-output "3\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +struct S; +impl FnLike<&T, &T> for S { + fn call(&self, arg: &T) -> &T { + // { dg-warning "unused name .self." "" { target *-*-* } .-1 } + arg + } +} + +fn indirect>(f: F) { + let x = 3; + let y = f.call(&x); + + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, *y); + } +} + +fn main() -> i32 { + indirect(S); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/transmute1.rs b/gcc/testsuite/rust/execute/torture/transmute1.rs new file mode 100644 index 00000000000..b9ec38ca618 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/transmute1.rs @@ -0,0 +1,23 @@ +// { dg-additional-options "-w" } + +extern "rust-intrinsic" { + fn transmute(value: T) -> U; +} + +struct WrapI { + inner: i32, +} + +struct WrapF { + inner: f32, +} + +fn main() -> i32 { + let f = 15.4f32; + let f_wrap = WrapF { inner: f }; + + let fst = unsafe { transmute::(f) }; + let snd = unsafe { transmute::(f_wrap) }; + + fst - snd.inner +} diff --git a/gcc/testsuite/rust/execute/torture/wrapping_op1.rs b/gcc/testsuite/rust/execute/torture/wrapping_op1.rs new file mode 100644 index 00000000000..64b37085ab7 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/wrapping_op1.rs @@ -0,0 +1,14 @@ +extern "rust-intrinsic" { + pub fn wrapping_add(l: T, r: T) -> T; +} + +fn five() -> u8 { + 5 +} + +fn main() -> u8 { + let l = 255; + let r = five(); + + unsafe { wrapping_add(l, r) - 4 } +} diff --git a/gcc/testsuite/rust/execute/torture/wrapping_op2.rs b/gcc/testsuite/rust/execute/torture/wrapping_op2.rs new file mode 100644 index 00000000000..f9990157894 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/wrapping_op2.rs @@ -0,0 +1,20 @@ +extern "rust-intrinsic" { + pub fn wrapping_add(l: T, r: T) -> T; + pub fn wrapping_sub(l: T, r: T) -> T; + pub fn wrapping_mul(l: T, r: T) -> T; +} + +fn five() -> u8 { + 5 +} + +fn main() -> u8 { + let l = 255; + let r = five(); + + let ret0 = unsafe { wrapping_add(l, r) - 4 }; // 4 + let ret1 = unsafe { wrapping_sub(r, l) - 6 }; // 6 + let ret2 = unsafe { wrapping_mul(r, l) - 251 }; // 251 + + ret0 + ret1 + ret2 +} diff --git a/gcc/testsuite/rust/execute/xfail/macro1.rs b/gcc/testsuite/rust/execute/xfail/macro1.rs new file mode 100644 index 00000000000..eab5a0285cf --- /dev/null +++ b/gcc/testsuite/rust/execute/xfail/macro1.rs @@ -0,0 +1,32 @@ +// { dg-output "macro\nmacro\nmacro\nmacro\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn f() { + let r_s = "macro\n\0"; + let s_p = r_s as *const str; + let c_p = s_p as *const i8; + + printf(c_p); +} + +macro_rules! empty0 { + () => ( f() ); +} + +macro_rules! empty1 { + {} => { f() }; +} + +macro_rules! empty2 { + [] => [ f() ]; +} + +// using multiple parens/brackets/curlies variants allows us to make sure we +// parse everything properly +fn main() { + empty0!(); + empty1!{}; + empty2![]; +} -- 2.25.1