diff --git a/gcc/attribs.cc b/gcc/attribs.cc index 497dcff84df..b219f878042 100644 --- a/gcc/attribs.cc +++ b/gcc/attribs.cc @@ -636,15 +636,20 @@ decl_attributes (tree *node, tree attributes, int flags, && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)) { DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node; - tree cur_tree - = build_target_option_node (&global_options, &global_options_set); - tree old_tree = DECL_FUNCTION_SPECIFIC_TARGET (*node); - if (!old_tree) - old_tree = target_option_default_node; - /* The changes on optimization options can cause the changes in - target options, update it accordingly if it's changed. */ - if (old_tree != cur_tree) - DECL_FUNCTION_SPECIFIC_TARGET (*node) = cur_tree; + /* Don't set DECL_FUNCTION_SPECIFIC_TARGET for targets that don't + support #pragma GCC target or target attribute. */ + if (target_option_default_node) + { + tree cur_tree + = build_target_option_node (&global_options, &global_options_set); + tree old_tree = DECL_FUNCTION_SPECIFIC_TARGET (*node); + if (!old_tree) + old_tree = target_option_default_node; + /* The changes on optimization options can cause the changes in + target options, update it accordingly if it's changed. */ + if (old_tree != cur_tree) + DECL_FUNCTION_SPECIFIC_TARGET (*node) = cur_tree; + } } /* If this is a function and the user used #pragma GCC target, add the diff --git a/gcc/testsuite/gcc.c-torture/compile/pr105234.c b/gcc/testsuite/gcc.c-torture/compile/pr105234.c new file mode 100644 index 00000000000..3fdfed8b562 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr105234.c @@ -0,0 +1,14 @@ +/* PR target/105234 */ +/* { dg-do compile } */ + +static inline __attribute__((always_inline)) int foo (int x) { return x + 1; } +#pragma GCC push_options +static inline __attribute__((always_inline)) int bar (int x) { return x + 2; } +#pragma GCC pop_options +static inline __attribute__((always_inline)) int baz (int x) { return x + 3; } + +int +qux (void) +{ + return foo (bar (baz (42))); +}