From 45484dcfb14634ff30b409c58ecc754e9fd88b5c Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 25 Apr 2014 11:04:40 +0000 Subject: [PATCH] re PR c/18079 (Contradicting function attributes (always_inline vs noinline)) PR c/18079 c/ * c-decl.c (diagnose_mismatched_decls): Warn for mismatched always_inline/noinline and hot/cold attributes. 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. * gcc.dg/pr18079-2.c: New test. From-SVN: r209796 --- gcc/c-family/ChangeLog | 8 +++++++ gcc/c-family/c-common.c | 32 ++++++++++++++++++------- gcc/c/ChangeLog | 6 +++++ gcc/c/c-decl.c | 40 ++++++++++++++++++++++++-------- gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/gcc.dg/pr18079-2.c | 16 +++++++++++++ gcc/testsuite/gcc.dg/pr18079.c | 33 ++++++++++++++++++++++++++ 7 files changed, 123 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr18079-2.c create mode 100644 gcc/testsuite/gcc.dg/pr18079.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 9d5ecc49be83..fb0d102eac33 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2014-04-25 Marek Polacek + + PR c/18079 + * 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. + 2014-04-25 Marek Polacek PR c/60156 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 97d16c16dd76..0ad955d9ccaf 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -6568,8 +6568,8 @@ handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args), { if (lookup_attribute ("cold", DECL_ATTRIBUTES (*node)) != NULL) { - warning (OPT_Wattributes, "%qE attribute conflicts with attribute %s", - name, "cold"); + warning (OPT_Wattributes, "%qE attribute ignored due to conflict " + "with attribute %qs", name, "cold"); *no_add_attrs = true; } /* Most of the rest of the hot processing is done later with @@ -6596,8 +6596,8 @@ handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args), { if (lookup_attribute ("hot", DECL_ATTRIBUTES (*node)) != NULL) { - warning (OPT_Wattributes, "%qE attribute conflicts with attribute %s", - name, "hot"); + warning (OPT_Wattributes, "%qE attribute ignored due to conflict " + "with attribute %qs", name, "hot"); *no_add_attrs = true; } /* Most of the rest of the cold processing is done later with @@ -6670,7 +6670,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 attribute %qs", name, "always_inline"); + *no_add_attrs = true; + } + else + DECL_UNINLINABLE (*node) = 1; + } else { warning (OPT_Wattributes, "%qE attribute ignored", name); @@ -6708,9 +6717,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 %qs attribute", name, "noinline"); + *no_add_attrs = true; + } + else + /* Set the attribute and mark it for disregarding inline + limits. */ + DECL_DISREGARD_INLINE_LIMITS (*node) = 1; } else { diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7369065d20ef..80841af40ee8 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2014-04-25 Marek Polacek + + PR c/18079 + * c-decl.c (diagnose_mismatched_decls): Warn for mismatched + always_inline/noinline and hot/cold attributes. + 2014-04-25 Marek Polacek PR c/60114 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index df84980e3090..e30876cbd1b8 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2099,18 +2099,38 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, /* Diagnose inline __attribute__ ((noinline)) which is silly. */ if (DECL_DECLARED_INLINE_P (newdecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) - { - warned |= warning (OPT_Wattributes, - "inline declaration of %qD follows " - "declaration with attribute noinline", newdecl); - } + warned |= warning (OPT_Wattributes, + "inline declaration of %qD follows " + "declaration with attribute noinline", newdecl); else if (DECL_DECLARED_INLINE_P (olddecl) && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) - { - warned |= warning (OPT_Wattributes, - "declaration of %q+D with attribute " - "noinline follows inline declaration ", newdecl); - } + warned |= warning (OPT_Wattributes, + "declaration of %q+D with attribute " + "noinline follows inline declaration ", newdecl); + else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)) + && lookup_attribute ("always_inline", DECL_ATTRIBUTES (olddecl))) + warned |= warning (OPT_Wattributes, + "declaration of %q+D with attribute " + "%qs follows declaration with attribute %qs", + newdecl, "noinline", "always_inline"); + else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (newdecl)) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) + warned |= warning (OPT_Wattributes, + "declaration of %q+D with attribute " + "%qs follows declaration with attribute %qs", + newdecl, "always_inline", "noinline"); + else if (lookup_attribute ("cold", DECL_ATTRIBUTES (newdecl)) + && lookup_attribute ("hot", DECL_ATTRIBUTES (olddecl))) + warned |= warning (OPT_Wattributes, + "declaration of %q+D with attribute %qs follows " + "declaration with attribute %qs", newdecl, "cold", + "hot"); + else if (lookup_attribute ("hot", DECL_ATTRIBUTES (newdecl)) + && lookup_attribute ("cold", DECL_ATTRIBUTES (olddecl))) + warned |= warning (OPT_Wattributes, + "declaration of %q+D with attribute %qs follows " + "declaration with attribute %qs", newdecl, "hot", + "cold"); } else /* PARM_DECL, VAR_DECL */ { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d711b3b762b7..6747b754b4c4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-04-25 Marek Polacek + + PR c/18079 + * gcc.dg/pr18079.c: New test. + * gcc.dg/pr18079-2.c: New test. + 2014-04-25 Uros Bizjak * c-c++-common/gomp/pr60823-2.c: Require effective target diff --git a/gcc/testsuite/gcc.dg/pr18079-2.c b/gcc/testsuite/gcc.dg/pr18079-2.c new file mode 100644 index 000000000000..5091dd41b2fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr18079-2.c @@ -0,0 +1,16 @@ +/* PR c/18079 */ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ + +__attribute__ ((always_inline)) void fndecl1 (void); +__attribute__ ((noinline)) void fndecl1 (void); /* { dg-warning "attribute noinline follows declaration with attribute always_inline" } */ + +__attribute__ ((noinline)) void fndecl2 (void); +__attribute__ ((always_inline)) void fndecl2 (void); /* { dg-warning "attribute always_inline follows declaration with attribute noinline" } */ + + +__attribute__ ((hot)) void fndecl3 (void); +__attribute__ ((cold)) void fndecl3 (void); /* { dg-warning "attribute cold follows declaration with attribute hot" } */ + +__attribute__ ((cold)) void fndecl4 (void); +__attribute__ ((hot)) void fndecl4 (void); /* { dg-warning "attribute hot follows declaration with attribute cold" } */ diff --git a/gcc/testsuite/gcc.dg/pr18079.c b/gcc/testsuite/gcc.dg/pr18079.c new file mode 100644 index 000000000000..b84cdebde3f4 --- /dev/null +++ b/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; +} -- 2.47.3