From a336c110cbefda2a1febddc56e0fd8289bb08c94 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 10 Dec 2019 19:41:08 +0100 Subject: [PATCH] Add gcc_assert that &global_options are not dirty modified. gcc/ChangeLog: 2020-03-17 Martin Liska PR tree-optimization/92860 * opth-gen.awk: Generate new function gcc_options_check. Include known exceptions. gcc/c-family/ChangeLog: 2020-03-17 Martin Liska PR tree-optimization/92860 * c-attribs.c (handle_optimize_attribute): Save global options before parsing of an optimization attribute. * c-pragma.c (opt_stack): Add saved_global_options field. (handle_pragma_push_options): Save current global_options. (handle_pragma_pop_options): Check current options. --- gcc/c-family/c-attribs.c | 12 ++++++++++++ gcc/c-family/c-pragma.c | 11 +++++++++++ gcc/opth-gen.awk | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 9abf81d0248..4ac44128407 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -4448,6 +4448,13 @@ handle_optimize_attribute (tree *node, tree name, tree args, /* If we previously had some optimization options, use them as the default. */ + gcc_options *saved_global_options = NULL; + if (flag_checking) + { + saved_global_options = (gcc_options *) xmalloc (sizeof (gcc_options)); + *saved_global_options = global_options; + } + if (old_opts) cl_optimization_restore (&global_options, TREE_OPTIMIZATION (old_opts)); @@ -4459,6 +4466,11 @@ handle_optimize_attribute (tree *node, tree name, tree args, /* Restore current options. */ cl_optimization_restore (&global_options, &cur_opts); + if (saved_global_options != NULL) + { + gcc_assert (gcc_options_check (saved_global_options, &global_options)); + free (saved_global_options); + } } return NULL_TREE; diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index 7c35741745b..94a1c486fc1 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -1003,6 +1003,7 @@ struct GTY(()) opt_stack { tree target_strings; tree optimize_binary; tree optimize_strings; + gcc_options *saved_global_options; }; static GTY(()) struct opt_stack * options_stack; @@ -1028,6 +1029,11 @@ handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy)) options_stack = p; /* Save optimization and target flags in binary format. */ + if (flag_checking) + { + p->saved_global_options = (gcc_options *) xmalloc (sizeof (gcc_options)); + *p->saved_global_options = global_options; + } p->optimize_binary = build_optimization_node (&global_options); p->target_binary = build_target_option_node (&global_options); @@ -1079,6 +1085,11 @@ handle_pragma_pop_options (cpp_reader *ARG_UNUSED(dummy)) p->optimize_binary); optimization_current_node = p->optimize_binary; } + if (flag_checking) + { + gcc_assert (gcc_options_check (p->saved_global_options, &global_options)); + free (p->saved_global_options); + } current_target_pragma = p->target_strings; current_optimize_pragma = p->optimize_strings; diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk index 856a69168a5..586213da3d3 100644 --- a/gcc/opth-gen.awk +++ b/gcc/opth-gen.awk @@ -119,6 +119,41 @@ print "#endif" print "#endif" print "" +print "#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)" +print "#ifndef GENERATOR_FILE" +print "static inline bool gcc_options_check (gcc_options *ptr1, gcc_options *ptr2)" +print "{" +print " bool result = true;" + +# all these options are mentioned in PR92860 +checked_options["flag_merge_constants"]++ +checked_options["param_max_fields_for_field_sensitive"]++ +checked_options["flag_omit_frame_pointer"]++ +checked_options["unroll_only_small_loops"]++ + +for (i = 0; i < n_opts; i++) { + name = var_name(flags[i]); + if (name == "") + continue; + + if (name in checked_options) + continue; + checked_options[name]++ + + print " if (ptr1->x_" name " != ptr2->x_" name ")" + print " {" + print " if (result)" + print " fprintf (stderr, \"Error: global_options are modified in local context:\\n\");" + print " fprintf (stderr, \" " name " (%ld/%ld)\\n\", (long int)ptr1->x_" name ", (long int)ptr2->x_" name ");" + print " result = false;" + print " }" +} + +print " return result;" +print "}" +print "#endif" +print "#endif" + # All of the optimization switches gathered together so they can be saved and restored. # This will allow attribute((cold)) to turn on space optimization. -- 2.25.1