(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
attr-copy-2.c
       1  /* PR middle-end/81824 - Warn for missing attributes with function aliases
       2     Exercise attribute copy for functions.
       3     { dg-do compile }
       4     { dg-require-alias "" }
       5     { dg-options "-O2 -Wall -Wno-array-bounds" } */
       6  
       7  #define Assert(expr)   typedef char AssertExpr[2 * !!(expr) - 1]
       8  
       9  #define ATTR(list)   __attribute__ (list)
      10  
      11  /* Verify that referencing a symbol with no attributes is accepted
      12     with no diagnostics.  */
      13  
      14  void ref0 (void);
      15  
      16  ATTR ((copy (ref0))) void
      17  f0 (void);
      18  
      19  /* Verify that referencing a symbol using the address-of and dereferencing
      20     operators is also accepted with no diagnostics.  */
      21  
      22  ATTR ((copy (&ref0))) void f1 (void);
      23  ATTR ((copy (*ref0))) void f2 (void);
      24  
      25  /* Verify that referencing a symbol of a different kind than that
      26     of the one the attribute is applied to is diagnosed.  */
      27  
      28  int v0;                       /* { dg-message "symbol .v0. referenced by .f3. declared here" } */
      29  
      30  ATTR ((copy (v0))) void
      31  f3 (void);                    /* { dg-warning ".copy. attribute ignored on a declaration of a different kind than referenced symbol" } */
      32  
      33  void f4 (void);              /* { dg-message "symbol .f4. referenced by .v1. declared here" } */
      34  
      35  ATTR ((copy (f4))) int
      36  v1;                           /* { dg-warning ".copy. attribute ignored on a declaration of a different kind than referenced symbol" } */
      37  
      38  
      39  ATTR ((copy (v0 + 1)))
      40  void f5 (void);               /* { dg-warning ".copy. attribute ignored on a declaration of a different kind than referenced symbol" } */
      41  
      42  void f6 (void);
      43  
      44  ATTR ((copy (f6 - 1)))
      45  int v1;                       /* { dg-warning ".copy. attribute ignored on a declaration of a different kind than referenced symbol" } */
      46  
      47  
      48  
      49  /* Verify that circular references of the copy function attribute
      50     are handled gracefully (i.e., not by getting into an infinite
      51     recursion) by issuing a diagnostic.  */
      52  
      53  void xref1 (void);            /* { dg-message "previous declaration here" } */
      54  ATTR ((copy (xref1))) void
      55  xref1 (void);                 /* { dg-warning ".copy. attribute ignored on a redeclaration of the referenced symbol" } */
      56  ATTR ((copy (xref1))) void
      57  xref1 (void);                 /* { dg-warning ".copy. attribute ignored on a redeclaration of the referenced symbol" } */
      58  ATTR ((copy (xref1), copy (xref1))) void
      59  xref1 (void);                 /* { dg-warning ".copy. attribute ignored on a redeclaration of the referenced symbol" } */
      60  
      61  
      62  /* Use attribute noreturn to verify that circular references propagate
      63     atttibutes as expected, and unlike in the self-referential instances
      64     above, without a warning.  Also use the address-of operator to make
      65     sure it doesn't change anything.  */
      66  
      67  ATTR ((noreturn))      void xref2 (void);
      68  ATTR ((copy (xref2)))  void xref3 (void);
      69  ATTR ((copy (&xref3))) void xref4 (void);
      70  ATTR ((copy (xref4)))  void xref5 (void);
      71  ATTR ((copy (&xref5))) void xref6 (void);
      72  ATTR ((copy (xref6)))  void xref7 (void);
      73  ATTR ((copy (&xref7))) void xref8 (void);
      74  ATTR ((copy (xref8)))  void xref9 (void);
      75  ATTR ((copy (&xref9))) void xref2 (void);
      76  
      77  int call_ref2 (void) { xref2 (); }
      78  int call_ref3 (void) { xref3 (); }
      79  int call_ref4 (void) { xref4 (); }
      80  int call_ref5 (void) { xref5 (); }
      81  int call_ref6 (void) { xref6 (); }
      82  int call_ref7 (void) { xref7 (); }
      83  int call_ref8 (void) { xref8 (); }
      84  int call_ref9 (void) { xref9 (); }
      85  
      86  
      87  /* Verify that copying attributes from multiple symbols into one works
      88     as expected.  */
      89  
      90  ATTR ((malloc)) void*
      91  xref10 (void);
      92  
      93  ATTR ((alloc_size (1)))
      94  void* xref11 (int);
      95  
      96  ATTR ((copy (xref10), copy (xref11)))
      97  void* xref12 (int);
      98  
      99  void* call_xref12 (void)
     100  {
     101    void *p = xref12 (3);
     102    __builtin___strcpy_chk (p, "123", __builtin_object_size (p, 0));   /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     103    return p;
     104  }
     105  
     106  
     107  /* Verify that attribute exclusions apply.  */
     108  
     109  ATTR ((const)) int
     110  fconst (void);
     111  
     112  ATTR ((pure)) int
     113  fpure (void);                 /* { dg-message "previous declaration here" } */
     114  
     115  ATTR ((copy (fconst), copy (fpure))) int
     116  fconst_pure (void);           /* { dg-warning "ignoring attribute .pure. because it conflicts with attribute .const." } */
     117  
     118  
     119  /* Also verify that the note in the exclusion warning points to
     120     the declaration from which the conflicting attribute is copied.
     121     The wording in the note could be improved but it's the same as
     122     in ordinary exclusions so making it different between the two
     123     would take some API changes.  */
     124  
     125  ATTR ((const)) int
     126  gconst (void);                /* { dg-message "previous declaration here" } */
     127  
     128  ATTR ((pure, copy (gconst))) int
     129  gpure_const (void);           /* { dg-warning "ignoring attribute .const. because it conflicts with attribute .pure." } */
     130  
     131  
     132  /* Verify that attribute deprecated isn't copied (but referencing
     133     the deprecated declaration still triggers a warning).  */
     134  
     135  ATTR ((deprecated)) void
     136  fdeprecated (void);           /* { dg-message "declared here" } */
     137  
     138  /* Unlike in most other instance the warning below is on the line
     139     with the copy attribute that references the deprecated function.  */
     140  ATTR ((copy (fdeprecated)))   /* { dg-warning "\\\[-Wdeprecated-declarations]" } */
     141  int fcurrent (void);
     142  
     143  ATTR ((copy (fcurrent))) int
     144  fcurrent2 (void);
     145  
     146  int call_fcurrent (void) { return fcurrent () + fcurrent2 (); }
     147  
     148  
     149  /* Verify that attributes are copied on a declaration using __typeof__
     150     and that -Wmissing-attributes is not issued.  */
     151  
     152  ATTR ((cold)) int
     153  target_cold (void)
     154  { return 0; }
     155  
     156  __typeof__ (target_cold) ATTR ((copy (target_cold), alias ("target_cold")))
     157  alias_cold;                   /* { dg-bogus "\\\[-Wmissing-attributes]." } */
     158  
     159  
     160  /* Verify that attribute alias is not copied.  This also indirectly
     161     verifies that attribute copy itself isn't copied.  */
     162  
     163  ATTR ((noreturn)) void fnoret (void) { __builtin_abort (); }
     164  ATTR ((alias ("fnoret"), copy (fnoret))) void fnoret_alias (void);
     165  ATTR ((copy (fnoret_alias))) void fnoret2 (void) { __builtin_exit (1); }
     166  
     167  /* Expect no warning below.  */
     168  int call_noret (void) { fnoret2 (); }
     169  
     170  
     171  /* Verify that attribute nonnull (which is part of a function type,
     172     even when it's specified on a function declaration) is copied to
     173     the alias from its target.  Expect no warning about the alias
     174     specifying less restrictive attributes than its target, but do
     175     verify that passing a null to the alias triggers -Wnonnull.  */
     176  
     177  ATTR ((nonnull))
     178  void* ftarget_nonnull (void *p) { return p; }
     179  
     180  ATTR ((alias ("ftarget_nonnull"), copy (ftarget_nonnull)))
     181  void* falias_nonnull (void*);
     182  
     183  void call_falias_nonnull (void)
     184  {
     185    falias_nonnull (0);         /* { dg-warning "-Wnonnull" } */
     186  }
     187  
     188  /* Same as above but for malloc.  Also verify that the attribute
     189     on the alias is used by -Wstringop-overflow.  */
     190  
     191  ATTR ((malloc))
     192  void* ftarget_malloc (void) { return __builtin_malloc (1); }
     193  
     194  ATTR ((alias ("ftarget_malloc"), copy (ftarget_malloc)))
     195  void* falias_malloc (void);
     196  
     197  void* call_falias_malloc (void)
     198  {
     199    char *p = falias_malloc ();
     200    __builtin___strcpy_chk (p, "123", __builtin_object_size (p, 0));   /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
     201    return p;
     202  }
     203  
     204  /* Same as above but for nothrow.  */
     205  
     206  ATTR ((nothrow))
     207  void ftarget_nothrow (void) { }
     208  
     209  ATTR ((alias ("ftarget_nothrow"), copy (ftarget_nothrow)))
     210  void falias_nothrow (void);