On Thu, Mar 20, 2014 at 12:10:35PM +0100, Richard Biener wrote: > On Thu, Mar 20, 2014 at 12:07 PM, Marek Polacek <pola...@redhat.com> wrote: > > We should warn if someone wants to use both always_inline and noinline > > attributes. > > > > Regtested/bootstrapped on x86_64-linux. This is hardly 4.9 material, > > so ok for 5.0? > > Shouldn't the warning state that the attribute will be ignored? That is, > the common warning is > > warning (OPT_Wattributes, "%qE attribute ignored", name); > > which could be amended with " due to conflict with ....".
Dunno. I did what we do wrt conflicting cold/hot attributes. But here's a patch with what you suggest (with some Extra Quotes). 2014-03-20 Marek Polacek <pola...@redhat.com> PR c/18079 c-family/ * c-common.c (handle_noinline_attribute): Warn if the attribute conflicts with always_inline attribute. (handle_always_inline_attribute): Warn if the attribute conflicts with noinline attribute. testsuite/ * gcc.dg/pr18079.c: New test. diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c index abd96fb..5258e52 100644 --- gcc/c-family/c-common.c +++ gcc/c-family/c-common.c @@ -6666,7 +6666,16 @@ handle_noinline_attribute (tree *node, tree name, int ARG_UNUSED (flags), bool *no_add_attrs) { if (TREE_CODE (*node) == FUNCTION_DECL) - DECL_UNINLINABLE (*node) = 1; + { + if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node))) + { + warning (OPT_Wattributes, "%qE attribute ignored due to conflict " + "with %<always_inline%> attribute", name); + *no_add_attrs = true; + } + else + DECL_UNINLINABLE (*node) = 1; + } else { warning (OPT_Wattributes, "%qE attribute ignored", name); @@ -6704,9 +6713,16 @@ handle_always_inline_attribute (tree *node, tree name, { if (TREE_CODE (*node) == FUNCTION_DECL) { - /* Set the attribute and mark it for disregarding inline - limits. */ - DECL_DISREGARD_INLINE_LIMITS (*node) = 1; + if (lookup_attribute ("noinline", DECL_ATTRIBUTES (*node))) + { + warning (OPT_Wattributes, "%qE attribute ignored due to conflict " + "with %<noinline%> attribute", name); + *no_add_attrs = true; + } + else + /* Set the attribute and mark it for disregarding inline + limits. */ + DECL_DISREGARD_INLINE_LIMITS (*node) = 1; } else { diff --git gcc/testsuite/gcc.dg/pr18079.c gcc/testsuite/gcc.dg/pr18079.c index e69de29..b84cdeb 100644 --- gcc/testsuite/gcc.dg/pr18079.c +++ gcc/testsuite/gcc.dg/pr18079.c @@ -0,0 +1,33 @@ +/* PR c/18079 */ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ + +__attribute__ ((noinline)) +__attribute__ ((always_inline)) +int +fn1 (int r) +{ /* { dg-warning "attribute ignored due to conflict" } */ + return r & 4; +} + +__attribute__ ((noinline, always_inline)) +int +fn2 (int r) +{ /* { dg-warning "attribute ignored due to conflict" } */ + return r & 4; +} + +__attribute__ ((always_inline)) +__attribute__ ((noinline)) +inline int +fn3 (int r) +{ /* { dg-warning "attribute ignored due to conflict" } */ + return r & 8; +} + +__attribute__ ((always_inline, noinline)) +inline int +fn4 (int r) +{ /* { dg-warning "attribute ignored due to conflict" } */ + return r & 8; +} Marek