We set default for some target options in TARGET_OPTION_OPTIMIZATION_TABLE, but these can be overridden by specifying the corresponding explicit -mXXX / -mno-XXX options. When a function bears the attribue __attribute__ ((optimize("02"))) the target options are set to the default for that optimization level, which can be different from what was selected for the file as a whole. As handle_optimize_attribute is right now, it will thus clobber the target options, and with enable_checking it will then abort.
The attached patch makes it save and restore the target options. Bootstrapped and regression tested on x86_64-pc-linux-gnu.
c-family/ * handle_optimize_attribute: Save & restore target options too. diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index f54388e9939..82d85ef8e01 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -5333,10 +5333,13 @@ handle_optimize_attribute (tree *node, tree name, tree args, else { struct cl_optimization cur_opts; + struct cl_target_option cur_target_opts; tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node); /* Save current options. */ cl_optimization_save (&cur_opts, &global_options, &global_options_set); + cl_target_option_save (&cur_target_opts, &global_options, + &global_options_set); /* If we previously had some optimization options, use them as the default. */ @@ -5359,6 +5362,8 @@ handle_optimize_attribute (tree *node, tree name, tree args, /* Restore current options. */ cl_optimization_restore (&global_options, &global_options_set, &cur_opts); + cl_target_option_restore (&global_options, &global_options_set, + &cur_target_opts); if (saved_global_options != NULL) { cl_optimization_compare (saved_global_options, &global_options);