Patchwork [C] Warn if inline attributes conflict (PR c/18079)

login
register
mail settings
Submitter Marek Polacek
Date March 20, 2014, 11:07 a.m.
Message ID <20140320110736.GL6523@redhat.com>
Download mbox | patch
Permalink /patch/332079/
State New
Headers show

Comments

Marek Polacek - March 20, 2014, 11:07 a.m.
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?

2014-03-20  Marek Polacek  <polacek@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.


	Marek
Richard Guenther - March 20, 2014, 11:10 a.m.
On Thu, Mar 20, 2014 at 12:07 PM, Marek Polacek <polacek@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 ....".

Richard.

> 2014-03-20  Marek Polacek  <polacek@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..14c838a 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 conflicts with attribute %s",
> +                  name, "always_inline");
> +         *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 conflicts with attribute %s",
> +                  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 gcc/testsuite/gcc.dg/pr18079.c gcc/testsuite/gcc.dg/pr18079.c
> index e69de29..adb5cdf 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 conflicts with attribute noinline" } */
> +  return r & 4;
> +}
> +
> +__attribute__ ((noinline, always_inline))
> +int
> +fn2 (int r)
> +{ /* { dg-warning "attribute conflicts with attribute noinline" } */
> +  return r & 4;
> +}
> +
> +__attribute__ ((always_inline))
> +__attribute__ ((noinline))
> +inline int
> +fn3 (int r)
> +{ /* { dg-warning "attribute conflicts with attribute always_inline" } */
> +  return r & 8;
> +}
> +
> +__attribute__ ((always_inline, noinline))
> +inline int
> +fn4 (int r)
> +{ /* { dg-warning "attribute conflicts with attribute always_inline" } */
> +  return r & 8;
> +}
>
>         Marek

Patch

diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
index abd96fb..14c838a 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 conflicts with attribute %s",
+		   name, "always_inline");
+	  *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 conflicts with attribute %s",
+		   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 gcc/testsuite/gcc.dg/pr18079.c gcc/testsuite/gcc.dg/pr18079.c
index e69de29..adb5cdf 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 conflicts with attribute noinline" } */
+  return r & 4;
+}
+
+__attribute__ ((noinline, always_inline))
+int
+fn2 (int r)
+{ /* { dg-warning "attribute conflicts with attribute noinline" } */
+  return r & 4;
+}
+
+__attribute__ ((always_inline))
+__attribute__ ((noinline))
+inline int
+fn3 (int r)
+{ /* { dg-warning "attribute conflicts with attribute always_inline" } */
+  return r & 8;
+}
+
+__attribute__ ((always_inline, noinline))
+inline int
+fn4 (int r)
+{ /* { dg-warning "attribute conflicts with attribute always_inline" } */
+  return r & 8;
+}