Enabling in Glibc the recent enhancement to detect attribute
mismatches in alias declarations (PR 81824) revealed a use
case where aliases are being declared for targets declared
with the always_inline attribute.  Copying the always_inline
attribute to the declaration of the alias would then trigger

  error: always_inline function might not be inlinable [-Werror=attributes]

due to the alias not being inlinable in some contexts where
(presumably) the target would be.  To avoid the warning for
this use case the attached patch excludes all attributes
that affect inlining from being copied by attribute copy.

While testing this I also more thoroughly exercised attribute
tls_target (which also came up during the Glibc deployment),
and improved the diagnostics for the attribute to make their
root cause easier to understand (printing "attribute ignored"
alone isn't very informative without also explaining why).

Martin

PS While testing this I also opened bug 88010 where inlining
attributes on aliases seem to be silently ignored in favor of
those on their targets.  I'm wondering what the expected (or
preferred) behavior is.
gcc/c-family/ChangeLog:

	* c-attribs.c (handle_copy_attribute): Exclude inlining attributes.
	(handle_tls_model_attribute): Improve diagnostics.
	(has_attribute): Fix a typo.

gcc/testsuite/ChangeLog:

	* gcc.dg/attr-copy-5.c: New test.
	* gcc.dg/tls/diag-6.c: Adjust expected diagnostics.


Index: gcc/c-family/c-attribs.c
===================================================================
--- gcc/c-family/c-attribs.c	(revision 266033)
+++ gcc/c-family/c-attribs.c	(working copy)
@@ -2239,13 +2239,15 @@ handle_copy_attribute (tree *node, tree name, tree
       /* Copy decl attributes from REF to DECL.  */
       for (tree at = attrs; at; at = TREE_CHAIN (at))
 	{
-	  /* Avoid copying attributes that affect a symbol linkage or
-	     visibility since those in all likelihood only apply to
-	     the target.
+	  /* Avoid copying attributes that affect a symbol linkage,
+	     inlining, or visibility since those in all likelihood
+	     only apply to the target.
 	     FIXME: make it possible to specify which attributes to
 	     copy or not to copy in the copy attribute itself.  */
 	  tree atname = get_attribute_name (at);
 	  if (is_attribute_p ("alias", atname)
+	      || is_attribute_p ("always_inline", atname)
+	      || is_attribute_p ("gnu_inline", atname)
 	      || is_attribute_p ("ifunc", atname)
 	      || is_attribute_p ("visibility", atname)
 	      || is_attribute_p ("weak", atname)
@@ -2458,17 +2460,26 @@ handle_tls_model_attribute (tree *node, tree name,
   tree decl = *node;
   enum tls_model kind;
 
-  if (!VAR_P (decl) || !DECL_THREAD_LOCAL_P (decl))
+  if (!VAR_P (decl))
     {
-      warning (OPT_Wattributes, "%qE attribute ignored", name);
+      warning (OPT_Wattributes, "%qE attribute ignored because %qD "
+	       "is not a variable",
+	       name, decl);
       return NULL_TREE;
     }
 
+  if (!DECL_THREAD_LOCAL_P (decl))
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored because %qD does "
+	       "not have thread storage duration", name, decl);
+      return NULL_TREE;
+    }
+
   kind = DECL_TLS_MODEL (decl);
   id = TREE_VALUE (args);
   if (TREE_CODE (id) != STRING_CST)
     {
-      error ("tls_model argument not a string");
+      error ("%qE argument not a string", name);
       return NULL_TREE;
     }
 
@@ -2481,7 +2492,9 @@ handle_tls_model_attribute (tree *node, tree name,
   else if (!strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
     kind = TLS_MODEL_GLOBAL_DYNAMIC;
   else
-    error ("tls_model argument must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\"");
+    error ("%qE argument must be one of %qs, %qs, %qs, or %qs",
+	   name,
+	   "local-exec", "initial-exec", "local-dynamic", "global-dynamic");
 
   set_decl_tls_model (decl, kind);
   return NULL_TREE;
Index: gcc/testsuite/gcc.dg/attr-copy-5.c
===================================================================
--- gcc/testsuite/gcc.dg/attr-copy-5.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/attr-copy-5.c	(working copy)
@@ -0,0 +1,57 @@
+/* PR middle-end/81824 - Warn for missing attributes with function aliases
+   Verify that attributes always_inline, gnu_inline, and noinline aren't
+   copied.  Also verify that copying attribute tls_model to a non-thread
+   variable triggers a warning.
+   { dg-do compile }
+   { dg-options "-Wall" }
+   { dg-require-effective-target tls } */
+
+#define ATTR(...)   __attribute__ ((__VA_ARGS__))
+
+ATTR (always_inline, gnu_inline, noreturn) inline int
+finline_noret (void)
+{
+  __builtin_abort ();
+  /* Expect no -Wreturn-type.  */
+}
+
+int call_finline_noret (void)
+{
+  finline_noret ();
+  /* Expect no -Wreturn-type.  */
+}
+
+
+ATTR (copy (finline_noret)) int
+fnoret (void);
+
+int call_fnoret (void)
+{
+  fnoret ();
+  /* Expect no -Wreturn-type.  */
+}
+
+
+/* Verify that attribute always_inline on an alias target doesn't
+   get copied and interfere with attribute noinline on the alias
+   (trigger a warning due to a conflict).  */
+
+ATTR (always_inline) static inline int
+finline (void) { return 0; }
+
+ATTR (alias ("finline"), noinline) int
+fnoinline (void);
+
+ATTR (copy (finline)) int
+fnoinline (void);
+
+
+ATTR (tls_model ("global-dynamic")) __thread int
+  tls_target;
+
+ATTR (alias ("tls_target"), copy (tls_target)) extern __thread int
+  thread_alias;
+
+
+ATTR (alias ("tls_target"), copy (tls_target)) extern int
+  alias;            /* { dg-warning ".tls_model. attribute ignored because .alias. does not have thread storage duration" } */
Index: gcc/testsuite/gcc.dg/tls/diag-6.c
===================================================================
--- gcc/testsuite/gcc.dg/tls/diag-6.c	(revision 266033)
+++ gcc/testsuite/gcc.dg/tls/diag-6.c	(working copy)
@@ -4,5 +4,5 @@
 int v __attribute__((tls_model("initial-exec"))); /* { dg-warning "attribute ignored" } */
 typedef int X __attribute__((tls_model("initial-exec"))); /* { dg-warning "attribute ignored" } */
 void f(int x __attribute__((tls_model("initial-exec")))); /* { dg-warning "attribute ignored" } */
-__thread int a __attribute__((tls_model(1))); /* { dg-error "tls_model argument not a string" } */
-__thread int b __attribute__((tls_model("unknown"))); /* { dg-error "tls_model argument must be one of" } */
+__thread int a __attribute__((tls_model(1))); /* { dg-error ".tls_model. argument not a string" } */
+__thread int b __attribute__((tls_model("unknown"))); /* { dg-error ".tls_model. argument must be one of" } */

Reply via email to