@@ -214,3 +214,73 @@ make_pru_tiabi_check (gcc::context *ctxt)
{
return new pass_pru_tiabi_check (ctxt);
}
+
+namespace {
+
+/* Scan the tree to ensure that the compiled code by GCC
+ conforms to the non-standard minimal runtime. */
+const pass_data pass_data_pru_minrt_check =
+{
+ GIMPLE_PASS, /* type */
+ "*pru_minrt_check", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+/* Implementation class for the minrt compliance-check pass. */
+class pass_pru_minrt_check : public gimple_opt_pass
+{
+public:
+ pass_pru_minrt_check (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_pru_minrt_check, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual unsigned int execute (function *);
+
+ virtual bool gate (function *)
+ {
+ return TARGET_MINRT;
+ }
+
+}; // class pass_pru_minrt_check
+
+/* Pass implementation. */
+unsigned
+pass_pru_minrt_check::execute (function *fun)
+{
+ const_tree fntype = TREE_TYPE (fun->decl);
+
+ if (id_equal (DECL_NAME (fun->decl), "main"))
+ {
+ /* Argument list always ends with VOID_TYPE, so subtract one
+ to get the number of function arguments. */
+ const unsigned num_args = list_length (TYPE_ARG_TYPES (fntype)) - 1;
+
+ if (num_args != 0)
+ error_at (DECL_SOURCE_LOCATION (fun->decl), "function %<main%> "
+ "must have no arguments when using the "
+ "%<-minrt%> option");
+
+ /* The required CFG analysis to detect when a functions would never
+ return is available only with -O1 and higher. */
+ if (optimize >= 1 && !TREE_THIS_VOLATILE (fun->decl))
+ error_at (DECL_SOURCE_LOCATION (fun->decl), "function %<main%> "
+ "must never return when using the "
+ "%<-minrt%> option");
+ }
+ return 0;
+}
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pru_minrt_check (gcc::context *ctxt)
+{
+ return new pass_pru_minrt_check (ctxt);
+}
@@ -22,3 +22,8 @@
If GCC cannot output a conforming code, then an error is raised. */
INSERT_PASS_AFTER (pass_warn_unused_result, 1, pru_tiabi_check);
+
+/* If -minrt option is used, then this pass would validate
+ that the compiled code by GCC is compatible with the minimal
+ C runtime. */
+INSERT_PASS_AFTER (pass_warn_function_noreturn, 1, pru_minrt_check);
@@ -73,6 +73,7 @@ extern int pru_get_ctable_base_offset (unsigned HOST_WIDE_INT caddr);
extern int pru_symref2ioregno (rtx op);
extern rtl_opt_pass *make_pru_tiabi_check (gcc::context *);
+extern rtl_opt_pass *make_pru_minrt_check (gcc::context *);
#endif /* RTX_CODE */
new file mode 100644
@@ -0,0 +1,10 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+
+int main(void)
+{
+ for (;;)
+ ;
+}
new file mode 100644
@@ -0,0 +1,10 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+int main(int argc, char *argv[])
+/* { dg-error "function 'main' must have no arguments when using the '-minrt' option" "" { target pru-*-* } .-1 } */
+{
+ for (;;)
+ ;
+}
new file mode 100644
@@ -0,0 +1,9 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+int main(void)
+/* { dg-error "function 'main' must never return when using the '-minrt' option" "" { target pru-*-* } .-1 } */
+{
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,34 @@
+# Copyright (C) 2024 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
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't a pru target.
+if ![istarget pru*-*-*] then {
+ return
+}
+
+# Load support procs.
+load_lib g++-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] "" ""
+
+# All done.
+dg-finish
new file mode 100644
@@ -0,0 +1,10 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+
+int main(void)
+{
+ for (;;)
+ ;
+}
new file mode 100644
@@ -0,0 +1,10 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+int main(int argc, char *argv[])
+/* { dg-error "function 'main' must have no arguments when using the '-minrt' option" "" { target pru-*-* } .-1 } */
+{
+ for (;;)
+ ;
+}
new file mode 100644
@@ -0,0 +1,9 @@
+/* Test minrt checks */
+
+/* { dg-options "-O1 -minrt" } */
+
+int main(void)
+/* { dg-error "function 'main' must never return when using the '-minrt' option" "" { target pru-*-* } .-1 } */
+{
+ return 0;
+}
Add a new pru-specific pass to validate that the assumptions for the minimal C runtime are not violated by the user program. gcc/ChangeLog: * config/pru/pru-passes.cc (class pass_pru_minrt_check): New pass. (pass_pru_minrt_check::execute): New method. (make_pru_minrt_check): New function. * config/pru/pru-passes.def (INSERT_PASS_AFTER): Register the minrt check pass. * config/pru/pru-protos.h (make_pru_minrt_check): Add declaration. gcc/testsuite/ChangeLog: * g++.target/pru/minrt-1.cc: New test. * g++.target/pru/minrt-2.cc: New test. * g++.target/pru/minrt-3.cc: New test. * g++.target/pru/pru.exp: New test. * gcc.target/pru/minrt-1.c: New test. * gcc.target/pru/minrt-2.c: New test. * gcc.target/pru/minrt-3.c: New test. Signed-off-by: Dimitar Dimitrov <dimitar@dinux.eu> --- gcc/config/pru/pru-passes.cc | 70 +++++++++++++++++++++++++ gcc/config/pru/pru-passes.def | 5 ++ gcc/config/pru/pru-protos.h | 1 + gcc/testsuite/g++.target/pru/minrt-1.cc | 10 ++++ gcc/testsuite/g++.target/pru/minrt-2.cc | 10 ++++ gcc/testsuite/g++.target/pru/minrt-3.cc | 9 ++++ gcc/testsuite/g++.target/pru/pru.exp | 34 ++++++++++++ gcc/testsuite/gcc.target/pru/minrt-1.c | 10 ++++ gcc/testsuite/gcc.target/pru/minrt-2.c | 10 ++++ gcc/testsuite/gcc.target/pru/minrt-3.c | 9 ++++ 10 files changed, 168 insertions(+) create mode 100644 gcc/testsuite/g++.target/pru/minrt-1.cc create mode 100644 gcc/testsuite/g++.target/pru/minrt-2.cc create mode 100644 gcc/testsuite/g++.target/pru/minrt-3.cc create mode 100644 gcc/testsuite/g++.target/pru/pru.exp create mode 100644 gcc/testsuite/gcc.target/pru/minrt-1.c create mode 100644 gcc/testsuite/gcc.target/pru/minrt-2.c create mode 100644 gcc/testsuite/gcc.target/pru/minrt-3.c