MSP430: Setup exclusion tables for function and data attributes
authorJozef Lawrynowicz <jozefl@gcc.gnu.org>
Tue, 3 Sep 2019 20:48:55 +0000 (20:48 +0000)
committerJozef Lawrynowicz <jozefl@gcc.gnu.org>
Tue, 3 Sep 2019 20:48:55 +0000 (20:48 +0000)
gcc/ChangeLog:

2019-09-03  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

* config/msp430/msp430.c (msp430_attr): Remove warnings about
conflicting msp430-specific attributes.
(msp430_section_attr): Likewise.
Add warnings about conflicts with generic "noinit" and "section"
attributes.
Fix grammar in -mlarge error message.
(msp430_data_attr): Rename to msp430_persist_attr.
Add warnings about conflicts with generic "noinit" and "section"
attributes.
Add warning for when variable is not initialized.
Chain conditionals which prevent the attribute being added.
(ATTR_EXCL): New helper.
(attr_reent_exclusions): New exclusion table.
(attr_naked_exclusions): Likewise.
(attr_crit_exclusions): Likewise.
(attr_lower_exclusions): Likewise.
(attr_upper_exclusions): Likewise.
(attr_either_exclusions): Likewise.
(attr_persist_exclusions): Likewise.
(msp430_attribute_table): Update with exclusion rules.
(msp430_output_aligned_decl_common): Don't output common symbol if decl
has a section.

gcc/testsuite/ChangeLog:

2019-09-03  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

* gcc.target/msp430/data-attributes-2.c: New test.
* gcc.target/msp430/function-attributes-4.c: Update dg-warning
strings.
* gcc.target/msp430/region-attribute-misuse.c: Likewise.

From-SVN: r275356

gcc/ChangeLog
gcc/config/msp430/msp430.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/msp430/data-attributes-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/msp430/function-attributes-4.c
gcc/testsuite/gcc.target/msp430/region-attribute-misuse.c

index e65e3046571f01708b86e2105ce5ba826a8114b5..e78a2b39569c5cb728cb2cda89106d745be48de7 100644 (file)
@@ -1,3 +1,28 @@
+2019-09-03  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
+
+       * config/msp430/msp430.c (msp430_attr): Remove warnings about
+       conflicting msp430-specific attributes.
+       (msp430_section_attr): Likewise.
+       Add warnings about conflicts with generic "noinit" and "section"
+       attributes.
+       Fix grammar in -mlarge error message.
+       (msp430_data_attr): Rename to msp430_persist_attr.
+       Add warnings about conflicts with generic "noinit" and "section"
+       attributes.
+       Add warning for when variable is not initialized.
+       Chain conditionals which prevent the attribute being added.
+       (ATTR_EXCL): New helper.
+       (attr_reent_exclusions): New exclusion table.
+       (attr_naked_exclusions): Likewise.
+       (attr_crit_exclusions): Likewise.
+       (attr_lower_exclusions): Likewise.
+       (attr_upper_exclusions): Likewise.
+       (attr_either_exclusions): Likewise.
+       (attr_persist_exclusions): Likewise.
+       (msp430_attribute_table): Update with exclusion rules.
+       (msp430_output_aligned_decl_common): Don't output common symbol if decl
+       has a section.
+
 2019-09-03  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
 
        * config/msp430/msp430.c (TARGET_HANDLE_GENERIC_ATTRIBUTE): Define.
index 1e6107589f53e7d1773353b7ccb58ffb98f617b9..8880522194bca4ed6accbe2da85c84092c9c469a 100644 (file)
@@ -1345,35 +1345,19 @@ msp430_attr (tree * node,
        }
       if (is_critical_func (* node))
        {
+         /* We always ignore the critical attribute when interrupt and
+            critical are used together.  */
          warning (OPT_Wattributes,
                   "critical attribute has no effect on interrupt functions");
          DECL_ATTRIBUTES (*node) = remove_attribute (ATTR_CRIT,
                                                      DECL_ATTRIBUTES (* node));
        }
     }
-  else if (TREE_NAME_EQ (name, ATTR_REENT))
-    {
-      if (is_naked_func (* node))
-       message = "naked functions cannot be reentrant";
-      else if (is_critical_func (* node))
-       message = "critical functions cannot be reentrant";
-    }
   else if (TREE_NAME_EQ (name, ATTR_CRIT))
     {
-      if (is_naked_func (* node))
-       message = "naked functions cannot be critical";
-      else if (is_reentrant_func (* node))
-       message = "reentrant functions cannot be critical";
-      else if (is_interrupt_func ( *node))
+      if (is_interrupt_func ( *node))
        message = "critical attribute has no effect on interrupt functions";
     }
-  else if (TREE_NAME_EQ (name, ATTR_NAKED))
-    {
-      if (is_critical_func (* node))
-       message = "critical functions cannot be naked";
-      else if (is_reentrant_func (* node))
-       message = "reentrant functions cannot be naked";
-    }
 
   if (message)
     {
@@ -1396,32 +1380,15 @@ msp430_section_attr (tree * node,
 
   const char * message = NULL;
 
-  if (TREE_NAME_EQ (name, ATTR_UPPER))
-    {
-      if (has_attr (ATTR_LOWER, * node))
-       message = "already marked with 'lower' attribute";
-      else if (has_attr (ATTR_EITHER, * node))
-       message = "already marked with 'either' attribute";
-      else if (! msp430x)
-       message = "upper attribute needs a 430X cpu";
-    }
-  else if (TREE_NAME_EQ (name, ATTR_LOWER))
-    {
-      if (has_attr (ATTR_UPPER, * node))
-       message = "already marked with 'upper' attribute";
-      else if (has_attr (ATTR_EITHER, * node))
-       message = "already marked with 'either' attribute";
-    }
-  else
-    {
-      gcc_assert (TREE_NAME_EQ (name, ATTR_EITHER));
-
-      if (has_attr (ATTR_LOWER, * node))
-       message = "already marked with 'lower' attribute";
-      else if (has_attr (ATTR_UPPER, * node))
-       message = "already marked with 'upper' attribute";
-    }
-
+  /* The "noinit" and "section" attributes are handled generically, so we
+     cannot set up additional target-specific attribute exclusions using the
+     existing mechanism.  */
+  if (has_attr (ATTR_NOINIT, *node))
+    message = G_("ignoring attribute %qE because it conflicts with "
+                "attribute %<noinit%>");
+  else if (has_attr ("section", *node))
+    message = G_("ignoring attribute %qE because it conflicts with "
+                "attribute %<section%>");
   /* It does not make sense to use upper/lower/either attributes without
      -mlarge.
      Without -mlarge, "lower" is the default and only region, so is redundant.
@@ -1429,9 +1396,9 @@ msp430_section_attr (tree * node,
      upper region, which for data could result in relocation overflows, and for
      code could result in stack mismanagement and incorrect call/return
      instructions.  */
-  if (!TARGET_LARGE)
-    message = G_("%qE attribute ignored. large memory model (%<-mlarge%>) "
-                "is required");
+  else if (!TARGET_LARGE)
+    message = G_("%qE attribute ignored.  Large memory model (%<-mlarge%>) "
+                "is required.");
 
   if (message)
     {
@@ -1443,7 +1410,7 @@ msp430_section_attr (tree * node,
 }
 
 static tree
-msp430_data_attr (tree * node,
+msp430_persist_attr (tree *node,
                  tree   name,
                  tree   args,
                  int    flags ATTRIBUTE_UNUSED,
@@ -1453,34 +1420,36 @@ msp430_data_attr (tree * node,
 
   gcc_assert (DECL_P (* node));
   gcc_assert (args == NULL);
+  gcc_assert (TREE_NAME_EQ (name, ATTR_PERSIST));
 
-  if (TREE_CODE (* node) != VAR_DECL)
-    message = G_("%qE attribute only applies to variables");
-
+  /* Check for the section attribute separately from DECL_SECTION_NAME so
+     we can provide a clearer warning.  */
+  if (has_attr ("section", *node))
+    message = G_("ignoring attribute %qE because it conflicts with "
+                "attribute %<section%>");
   /* Check that it's possible for the variable to have a section.  */
-  if ((TREE_STATIC (* node) || DECL_EXTERNAL (* node) || in_lto_p)
-      && DECL_SECTION_NAME (* node))
+  else if ((TREE_STATIC (*node) || DECL_EXTERNAL (*node) || in_lto_p)
+          && (DECL_SECTION_NAME (*node)))
     message = G_("%qE attribute cannot be applied to variables with specific "
                 "sections");
-
-  if (!message && TREE_NAME_EQ (name, ATTR_PERSIST) && !TREE_STATIC (* node)
-      && !TREE_PUBLIC (* node) && !DECL_EXTERNAL (* node))
+  else if (has_attr (ATTR_NOINIT, *node))
+    message = G_("ignoring attribute %qE because it conflicts with "
+                "attribute %<noinit%>");
+  else if (TREE_CODE (*node) != VAR_DECL)
+    message = G_("%qE attribute only applies to variables");
+  else if (!TREE_STATIC (*node) && !TREE_PUBLIC (*node)
+          && !DECL_EXTERNAL (*node))
     message = G_("%qE attribute has no effect on automatic variables");
-
-  /* It's not clear if there is anything that can be set here to prevent the
-     front end placing the variable before the back end can handle it, in a
-     similar way to how DECL_COMMON is used below.
-     So just place the variable in the .persistent section now.  */
-  if ((TREE_STATIC (* node) || DECL_EXTERNAL (* node) || in_lto_p)
-      && TREE_NAME_EQ (name, ATTR_PERSIST))
+  else if (DECL_COMMON (*node) || DECL_INITIAL (*node) == NULL)
+    message = G_("variables marked with %qE attribute must be initialized");
+  else
+    /* It's not clear if there is anything that can be set here to prevent the
+       front end placing the variable before the back end can handle it, in a
+       similar way to how DECL_COMMON is cleared for .noinit variables in
+       handle_noinit_attribute (gcc/c-family/c-attribs.c).
+       So just place the variable in the .persistent section now.  */
     set_decl_section_name (* node, ".persistent");
 
-  /* If this var is thought to be common, then change this.  Common variables
-     are assigned to sections before the backend has a chance to process
-     them.  */
-  if (DECL_COMMON (* node))
-    DECL_COMMON (* node) = 0;
-
   if (message)
     {
       warning (OPT_Wattributes, message, name);
@@ -1490,6 +1459,67 @@ msp430_data_attr (tree * node,
   return NULL_TREE;
 }
 
+/* Helper to define attribute exclusions.  */
+#define ATTR_EXCL(name, function, type, variable)      \
+  { name, function, type, variable }
+
+/* "reentrant", "critical" and "naked" functions must conflict because
+   they all modify the prologue or epilogue of functions in mutually exclusive
+   ways.  */
+static const struct attribute_spec::exclusions attr_reent_exclusions[] =
+{
+  ATTR_EXCL (ATTR_NAKED, true, true, true),
+  ATTR_EXCL (ATTR_CRIT, true, true, true),
+  ATTR_EXCL (NULL, false, false, false)
+};
+
+static const struct attribute_spec::exclusions attr_naked_exclusions[] =
+{
+  ATTR_EXCL (ATTR_REENT, true, true, true),
+  ATTR_EXCL (ATTR_CRIT, true, true, true),
+  ATTR_EXCL (NULL, false, false, false)
+};
+
+static const struct attribute_spec::exclusions attr_crit_exclusions[] =
+{
+  ATTR_EXCL (ATTR_REENT, true, true, true),
+  ATTR_EXCL (ATTR_NAKED, true, true, true),
+  ATTR_EXCL (NULL, false, false, false)
+};
+
+/* Attributes which put the given object in a specific section must conflict
+   with one another.  */
+static const struct attribute_spec::exclusions attr_lower_exclusions[] =
+{
+  ATTR_EXCL (ATTR_UPPER, true, true, true),
+  ATTR_EXCL (ATTR_EITHER, true, true, true),
+  ATTR_EXCL (ATTR_PERSIST, true, true, true),
+  ATTR_EXCL (NULL, false, false, false)
+};
+
+static const struct attribute_spec::exclusions attr_upper_exclusions[] =
+{
+  ATTR_EXCL (ATTR_LOWER, true, true, true),
+  ATTR_EXCL (ATTR_EITHER, true, true, true),
+  ATTR_EXCL (ATTR_PERSIST, true, true, true),
+  ATTR_EXCL (NULL, false, false, false)
+};
+
+static const struct attribute_spec::exclusions attr_either_exclusions[] =
+{
+  ATTR_EXCL (ATTR_LOWER, true, true, true),
+  ATTR_EXCL (ATTR_UPPER, true, true, true),
+  ATTR_EXCL (ATTR_PERSIST, true, true, true),
+  ATTR_EXCL (NULL, false, false, false)
+};
+
+static const struct attribute_spec::exclusions attr_persist_exclusions[] =
+{
+  ATTR_EXCL (ATTR_LOWER, true, true, true),
+  ATTR_EXCL (ATTR_UPPER, true, true, true),
+  ATTR_EXCL (ATTR_EITHER, true, true, true),
+  ATTR_EXCL (NULL, false, false, false)
+};
 
 #undef  TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE         msp430_attribute_table
@@ -1500,20 +1530,23 @@ const struct attribute_spec msp430_attribute_table[] =
     /* { name, min_num_args, max_num_args, decl_req, type_req, fn_type_req,
         affects_type_identity, handler, exclude } */
     { ATTR_INTR,       0, 1, true,  false, false, false, msp430_attr, NULL },
-    { ATTR_NAKED,       0, 0, true,  false, false, false, msp430_attr, NULL },
-    { ATTR_REENT,       0, 0, true,  false, false, false, msp430_attr, NULL },
-    { ATTR_CRIT,       0, 0, true,  false, false, false, msp430_attr, NULL },
+    { ATTR_NAKED,       0, 0, true,  false, false, false, msp430_attr,
+      attr_naked_exclusions },
+    { ATTR_REENT,       0, 0, true,  false, false, false, msp430_attr,
+      attr_reent_exclusions },
+    { ATTR_CRIT,       0, 0, true,  false, false, false, msp430_attr,
+      attr_crit_exclusions },
     { ATTR_WAKEUP,      0, 0, true,  false, false, false, msp430_attr, NULL },
 
     { ATTR_LOWER,       0, 0, true,  false, false, false, msp430_section_attr,
-      NULL },
+      attr_lower_exclusions },
     { ATTR_UPPER,       0, 0, true,  false, false, false, msp430_section_attr,
-      NULL },
+      attr_upper_exclusions },
     { ATTR_EITHER,      0, 0, true,  false, false, false, msp430_section_attr,
-      NULL },
+      attr_either_exclusions },
 
-    { ATTR_PERSIST,     0, 0, true,  false, false, false, msp430_data_attr,
-      NULL },
+    { ATTR_PERSIST,     0, 0, true,  false, false, false, msp430_persist_attr,
+      attr_persist_exclusions },
 
     { NULL,            0, 0, false, false, false, false, NULL,  NULL }
   };
@@ -1922,7 +1955,15 @@ msp430_output_aligned_decl_common (FILE *                  stream,
                                   unsigned HOST_WIDE_INT size,
                                   unsigned int           align)
 {
-  if (msp430_data_region == MSP430_REGION_ANY)
+  /* Only emit a common symbol if the variable does not have a specific section
+     assigned.  */
+  if (msp430_data_region == MSP430_REGION_ANY
+      && !(decl != NULL_TREE && DECL_SECTION_NAME (decl))
+      && !has_attr (ATTR_EITHER, decl)
+      && !has_attr (ATTR_LOWER, decl)
+      && !has_attr (ATTR_UPPER, decl)
+      && !has_attr (ATTR_PERSIST, decl)
+      && !has_attr (ATTR_NOINIT, decl))
     {
       fprintf (stream, COMMON_ASM_OP);
       assemble_name (stream, name);
index 4cf3e9b1ec411b1e9f800fbb50d49ce9acd5faf0..7c9a9c92fd650927d350ea0456c5ff4b3ca399a9 100644 (file)
@@ -1,6 +1,13 @@
+2019-09-03  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
+
+       * gcc.target/msp430/data-attributes-2.c: New test.
+       * gcc.target/msp430/function-attributes-4.c: Update dg-warning
+       strings.
+       * gcc.target/msp430/region-attribute-misuse.c: Likewise.
+
 2019-09-03  Kamlesh Kumar  <kamleshbhalui@gmail.com>
 
-        PR tree-optimization/91504
+       PR tree-optimization/91504
        gcc.dg/tree-ssa/pr91504.c: New test.
 
 2019-09-03  Jakub Jelinek  <jakub@redhat.com>
diff --git a/gcc/testsuite/gcc.target/msp430/data-attributes-2.c b/gcc/testsuite/gcc.target/msp430/data-attributes-2.c
new file mode 100644 (file)
index 0000000..d049194
--- /dev/null
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mcpu=msp430" } } */
+/* { dg-options "-mlarge" } */
+
+/* The msp430-specific variable attributes "lower", "upper", either", "noinit"
+   and "persistent", all conflict with one another.
+   These attributes also conflict with the "section" attribute, since they
+   specify sections to put the variables into.  */
+int __attribute__((persistent)) p = 10;
+int __attribute__((persistent,lower)) pl = 20; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'persistent'" } */
+int __attribute__((persistent,upper)) pu = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'persistent'" } */
+int __attribute__((persistent,either)) pe = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'persistent'" } */
+/* This one results in an error because the handler for persistent sets the
+   section to .persistent there and then.  */
+int __attribute__((persistent,section(".data.foo"))) ps = 20; /* { dg-error "section of 'ps' conflicts with previous declaration" } */
+int __attribute__((persistent,noinit)) pn = 2; /* { dg-warning "'noinit' attribute cannot be applied to variables with specific sections" } */
+
+int __attribute__((noinit)) n;
+int __attribute__((noinit,lower)) nl; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'noinit'" } */
+int __attribute__((noinit,upper)) nu; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'noinit'" } */
+int __attribute__((noinit,either)) ne; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'noinit'" } */
+int __attribute__((noinit,persistent)) np; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'noinit'" } */
+int __attribute__((noinit,section(".data.foo"))) ns; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'noinit'" } */
+
+int __attribute__((lower)) l = 20;
+int __attribute__((lower,upper)) lu = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'lower'" } */
+int __attribute__((lower,either)) le = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'lower'" } */
+int __attribute__((lower,persistent)) lp = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'lower'" } */
+int __attribute__((lower,noinit)) ln; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'lower'" } */
+int __attribute__((lower,section(".data.foo"))) ls = 30; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'lower'" } */
+
+int __attribute__((upper)) u = 20;
+int __attribute__((upper,lower)) ul = 20; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'upper'" } */
+int __attribute__((upper,either)) ue = 20; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'upper'" } */
+int __attribute__((upper,persistent)) up = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'upper'" } */
+int __attribute__((upper,noinit)) un; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'upper'" } */
+int __attribute__((upper,section(".data.foo"))) us = 30; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'upper'" } */
+
+int __attribute__((either)) e = 20;
+int __attribute__((either,lower)) el = 20; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'either'" } */
+int __attribute__((either,upper)) ee = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'either'" } */
+int __attribute__((either,persistent)) ep = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'either'" } */
+int __attribute__((either,noinit)) en; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'either'" } */
+int __attribute__((either,section(".data.foo"))) es = 30; /* { dg-warning "ignoring attribute 'section' because it conflicts with attribute 'either'" } */
+
+int __attribute__((section(".data.foo"))) s = 20;
+int __attribute__((section(".data.foo"),noinit)) sn; /* { dg-warning "ignoring attribute 'noinit' because it conflicts with attribute 'section'" } */
+int __attribute__((section(".data.foo"),persistent)) sp = 20; /* { dg-warning "ignoring attribute 'persistent' because it conflicts with attribute 'section'" } */
+int __attribute__((section(".data.foo"),lower)) sl = 2; /* { dg-warning "ignoring attribute 'lower' because it conflicts with attribute 'section'" } */
+int __attribute__((section(".data.foo"),upper)) su = 20; /* { dg-warning "ignoring attribute 'upper' because it conflicts with attribute 'section'" } */
+int __attribute__((section(".data.foo"),either)) se = 2; /* { dg-warning "ignoring attribute 'either' because it conflicts with attribute 'section'" } */
index 07d13c95ff16b39320eb72b2e7f83cab9bf7efa4..86224cc1436f2abaa556511fbc8dcb5b4c9a577a 100644 (file)
@@ -1,6 +1,9 @@
 /* { dg-do compile } */
 /* Check that the foo interrupt vectors aren't actually removed.  */
 /* { dg-final { scan-assembler-times "__interrupt_vector_foo" 2 } } */
+/* Check that the out-of-range interrupt vectors aren't actually removed.  */
+/* { dg-final { scan-assembler "__interrupt_vector_65" } } */
+/* { dg-final { scan-assembler "__interrupt_vector_100" } } */
 
 /* Check that warnings are emitted when attributes are used incorrectly and
    that attributes are interpreted correctly whether leading and trailing
 
 void __attribute__((__naked__,__reentrant__))
 fn1(void)
-{ /* { dg-warning "naked functions cannot be reentrant" } */
+{ /* { dg-warning "ignoring attribute 'reentrant' because it conflicts with attribute 'naked'" } */
 }
 
 void __attribute__((naked,reentrant))
 fn2(void)
-{ /* { dg-warning "naked functions cannot be reentrant" } */
+{ /* { dg-warning "ignoring attribute 'reentrant' because it conflicts with attribute 'naked'" } */
 }
 
 void __attribute__((__reentrant__,__naked__))
 fn3(void)
-{ /* { dg-warning "reentrant functions cannot be naked" } */
+{ /* { dg-warning "ignoring attribute 'naked' because it conflicts with attribute 'reentrant'" } */
 }
 
 void __attribute__((reentrant,naked))
 fn4(void)
-{ /* { dg-warning "reentrant functions cannot be naked" } */
+{ /* { dg-warning "ignoring attribute 'naked' because it conflicts with attribute 'reentrant'" } */
 }
 
 void __attribute__((__critical__,__reentrant__))
 fn5(void)
-{ /* { dg-warning "critical functions cannot be reentrant" } */
+{ /* { dg-warning "ignoring attribute 'reentrant' because it conflicts with attribute 'critical'" } */
 }
 
 void __attribute__((critical,reentrant))
 fn6(void)
-{ /* { dg-warning "critical functions cannot be reentrant" } */
+{ /* { dg-warning "ignoring attribute 'reentrant' because it conflicts with attribute 'critical'" } */
 }
 
 void __attribute__((__reentrant__,__critical__))
 fn7(void)
-{ /* { dg-warning "reentrant functions cannot be critical" } */
+{ /* { dg-warning "ignoring attribute 'critical' because it conflicts with attribute 'reentrant'" } */
 }
 
 void __attribute__((reentrant,critical))
 fn8(void)
-{ /* { dg-warning "reentrant functions cannot be critical" } */
+{ /* { dg-warning "ignoring attribute 'critical' because it conflicts with attribute 'reentrant'" } */
 }
 
 void __attribute__((__critical__,__naked__))
 fn9(void)
-{ /* { dg-warning "critical functions cannot be naked" } */
+{ /* { dg-warning "ignoring attribute 'naked' because it conflicts with attribute 'critical'" } */
 }
 
 void __attribute__((critical,naked))
 fn10(void)
-{ /* { dg-warning "critical functions cannot be naked" } */
+{ /* { dg-warning "ignoring attribute 'naked' because it conflicts with attribute 'critical'" } */
 }
 
 void __attribute__((__naked__,__critical__))
 fn11(void)
-{ /* { dg-warning "naked functions cannot be critical" } */
+{ /* { dg-warning "ignoring attribute 'critical' because it conflicts with attribute 'naked'" } */
 }
 
 void __attribute__((naked,critical))
 fn12(void)
-{ /* { dg-warning "naked functions cannot be critical" } */
+{ /* { dg-warning "ignoring attribute 'critical' because it conflicts with attribute 'naked'" } */
 }
 
 int __attribute__((interrupt))
index fe4617b917c2bb6d5ff80666775914e534439b60..a108e2741236b3c402097881528329dd5cc073c7 100644 (file)
@@ -5,9 +5,9 @@
 /* { dg-final { scan-assembler ".section.*lower.data" } } */
 /* { dg-final { scan-assembler ".section.*either.data" } } */
 
-int __attribute__((upper)) upper_bss; /* { dg-warning "'upper' attribute ignored. large memory model .'-mlarge'. is required" } */
-int __attribute__((lower)) lower_bss; /* { dg-warning "'lower' attribute ignored. large memory model .'-mlarge'. is required" } */
-int __attribute__((either)) either_bss; /* { dg-warning "'either' attribute ignored. large memory model .'-mlarge'. is required" } */
+int __attribute__((upper)) upper_bss; /* { dg-warning "'upper' attribute ignored.  Large memory model .'-mlarge'. is required" } */
+int __attribute__((lower)) lower_bss; /* { dg-warning "'lower' attribute ignored.  Large memory model .'-mlarge'. is required" } */
+int __attribute__((either)) either_bss; /* { dg-warning "'either' attribute ignored.  Large memory model .'-mlarge'. is required" } */
 
 /* Verify that even without -mlarge, objects can still be placed in
    upper/lower/either regions manually.  */