analyzer: fix feasibility false +ve on jumps through function ptrs [PR107582]
[platform/upstream/gcc.git] / gcc / attribs.h
1 /* Declarations and definitions dealing with attribute handling.
2    Copyright (C) 2013-2022 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #ifndef GCC_ATTRIBS_H
21 #define GCC_ATTRIBS_H
22
23 extern const struct attribute_spec *lookup_attribute_spec (const_tree);
24 extern void free_attr_data ();
25 extern void init_attributes (void);
26
27 /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
28    which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
29    it should be modified in place; if a TYPE, a copy should be created
30    unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS.  FLAGS gives further
31    information, in the form of a bitwise OR of flags in enum attribute_flags
32    from tree.h.  Depending on these flags, some attributes may be
33    returned to be applied at a later stage (for example, to apply
34    a decl attribute to the declaration rather than to its type).  */
35 extern tree decl_attributes (tree *, tree, int, tree = NULL_TREE);
36
37 extern bool cxx11_attribute_p (const_tree);
38 extern tree get_attribute_name (const_tree);
39 extern tree get_attribute_namespace (const_tree);
40 extern void apply_tm_attr (tree, tree);
41 extern tree make_attribute (const char *, const char *, tree);
42 extern bool attribute_ignored_p (tree);
43 extern bool attribute_ignored_p (const attribute_spec *const);
44
45 extern struct scoped_attributes* register_scoped_attributes (const struct attribute_spec *,
46                                                              const char *,
47                                                              bool = false);
48
49 extern char *sorted_attr_string (tree);
50 extern bool common_function_versions (tree, tree);
51 extern tree make_dispatcher_decl (const tree);
52 extern bool is_function_default_version (const tree);
53 extern void handle_ignored_attributes_option (vec<char *> *);
54
55 /* Return a type like TTYPE except that its TYPE_ATTRIBUTES
56    is ATTRIBUTE.
57
58    Such modified types already made are recorded so that duplicates
59    are not made.  */
60
61 extern tree build_type_attribute_variant (tree, tree);
62 extern tree build_decl_attribute_variant (tree, tree);
63 extern tree build_type_attribute_qual_variant (tree, tree, int);
64
65 extern bool simple_cst_list_equal (const_tree, const_tree);
66 extern bool attribute_value_equal (const_tree, const_tree);
67
68 /* Return 0 if the attributes for two types are incompatible, 1 if they
69    are compatible, and 2 if they are nearly compatible (which causes a
70    warning to be generated).  */
71 extern int comp_type_attributes (const_tree, const_tree);
72
73 extern tree affects_type_identity_attributes (tree, bool = true);
74 extern tree restrict_type_identity_attributes_to (tree, tree);
75
76 /* Default versions of target-overridable functions.  */
77 extern tree merge_decl_attributes (tree, tree);
78 extern tree merge_type_attributes (tree, tree);
79
80 /* Remove any instances of attribute ATTR_NAME in LIST and return the
81    modified list.  */
82
83 extern tree remove_attribute (const char *, tree);
84
85 /* Similarly but also with specific attribute namespace.  */
86
87 extern tree remove_attribute (const char *, const char *, tree);
88
89 /* Given two attributes lists, return a list of their union.  */
90
91 extern tree merge_attributes (tree, tree);
92
93 /* Duplicate all attributes with name NAME in ATTR list to *ATTRS if
94    they are missing there.  */
95
96 extern void duplicate_one_attribute (tree *, tree, const char *);
97
98 /* Duplicate all attributes from user DECL to the corresponding
99    builtin that should be propagated.  */
100
101 extern void copy_attributes_to_builtin (tree);
102
103 /* Given two Windows decl attributes lists, possibly including
104    dllimport, return a list of their union .  */
105 extern tree merge_dllimport_decl_attributes (tree, tree);
106
107 /* Handle a "dllimport" or "dllexport" attribute.  */
108 extern tree handle_dll_attribute (tree *, tree, tree, int, bool *);
109
110 extern int attribute_list_equal (const_tree, const_tree);
111 extern int attribute_list_contained (const_tree, const_tree);
112
113 /* The backbone of lookup_attribute().  ATTR_LEN is the string length
114    of ATTR_NAME, and LIST is not NULL_TREE.
115
116    The function is called from lookup_attribute in order to optimize
117    for size.  */
118 extern tree private_lookup_attribute (const char *attr_name, size_t attr_len,
119                                       tree list);
120 extern tree private_lookup_attribute (const char *attr_ns,
121                                       const char *attr_name,
122                                       size_t attr_ns_len, size_t attr_len,
123                                       tree list);
124
125 extern unsigned decls_mismatched_attributes (tree, tree, tree,
126                                              const char* const[],
127                                              pretty_printer*);
128
129 extern void maybe_diag_alias_attributes (tree, tree);
130
131 /* For a given string S of length L, strip leading and trailing '_' characters
132    so that we have a canonical form of attribute names.  NB: This function may
133    change S and L.  */
134
135 template <typename T>
136 inline bool
137 canonicalize_attr_name (const char *&s, T &l)
138 {
139   if (l > 4 && s[0] == '_' && s[1] == '_' && s[l - 1] == '_' && s[l - 2] == '_')
140     {
141       s += 2;
142       l -= 4;
143       return true;
144     }
145   return false;
146 }
147
148 /* For a given IDENTIFIER_NODE, strip leading and trailing '_' characters
149    so that we have a canonical form of attribute names.  */
150
151 static inline tree
152 canonicalize_attr_name (tree attr_name)
153 {
154   size_t l = IDENTIFIER_LENGTH (attr_name);
155   const char *s = IDENTIFIER_POINTER (attr_name);
156
157   if (canonicalize_attr_name (s, l))
158     return get_identifier_with_length (s, l);
159
160   return attr_name;
161 }
162
163 /* Compare attribute identifiers ATTR1 and ATTR2 with length ATTR1_LEN and
164    ATTR2_LEN.  */
165
166 static inline bool
167 cmp_attribs (const char *attr1, size_t attr1_len,
168              const char *attr2, size_t attr2_len)
169 {
170   return attr1_len == attr2_len && strncmp (attr1, attr2, attr1_len) == 0;
171 }
172
173 /* Compare attribute identifiers ATTR1 and ATTR2.  */
174
175 static inline bool
176 cmp_attribs (const char *attr1, const char *attr2)
177 {
178   return cmp_attribs (attr1, strlen (attr1), attr2, strlen (attr2));
179 }
180
181 /* Given an identifier node IDENT and a string ATTR_NAME, return true
182    if the identifier node is a valid attribute name for the string.  */
183
184 static inline bool
185 is_attribute_p (const char *attr_name, const_tree ident)
186 {
187   return cmp_attribs (attr_name, strlen (attr_name),
188                       IDENTIFIER_POINTER (ident), IDENTIFIER_LENGTH (ident));
189 }
190
191 /* Given an attribute ATTR and a string ATTR_NS, return true
192    if the attribute namespace is valid for the string.  ATTR_NS "" stands
193    for standard attribute (NULL get_attribute_namespace) or "gnu"
194    namespace.  */
195
196 static inline bool
197 is_attribute_namespace_p (const char *attr_ns, const_tree attr)
198 {
199   tree ident = get_attribute_namespace (attr);
200   if (attr_ns == NULL)
201     return ident == NULL_TREE;
202   if (attr_ns[0])
203     return ident && is_attribute_p (attr_ns, ident);
204   return ident == NULL_TREE || is_attribute_p ("gnu", ident);
205 }
206
207 /* Given an attribute name ATTR_NAME and a list of attributes LIST,
208    return a pointer to the attribute's list element if the attribute
209    is part of the list, or NULL_TREE if not found.  If the attribute
210    appears more than once, this only returns the first occurrence; the
211    TREE_CHAIN of the return value should be passed back in if further
212    occurrences are wanted.  ATTR_NAME must be in the form 'text' (not
213    '__text__').  */
214
215 static inline tree
216 lookup_attribute (const char *attr_name, tree list)
217 {
218   if (CHECKING_P && attr_name[0] != '_')
219     {
220       size_t attr_len = strlen (attr_name);
221       gcc_checking_assert (!canonicalize_attr_name (attr_name, attr_len));
222     }
223   /* In most cases, list is NULL_TREE.  */
224   if (list == NULL_TREE)
225     return NULL_TREE;
226   else
227     {
228       size_t attr_len = strlen (attr_name);
229       /* Do the strlen() before calling the out-of-line implementation.
230          In most cases attr_name is a string constant, and the compiler
231          will optimize the strlen() away.  */
232       return private_lookup_attribute (attr_name, attr_len, list);
233     }
234 }
235
236 /* Similar to lookup_attribute, but also match the attribute namespace.
237    ATTR_NS "" stands for either standard attribute or "gnu" namespace.  */
238
239 static inline tree
240 lookup_attribute (const char *attr_ns, const char *attr_name, tree list)
241 {
242   if (CHECKING_P && attr_name[0] != '_')
243     {
244       size_t attr_len = strlen (attr_name);
245       gcc_checking_assert (!canonicalize_attr_name (attr_name, attr_len));
246     }
247   if (CHECKING_P && attr_ns && attr_ns[0] != '_')
248     {
249       size_t attr_ns_len = strlen (attr_ns);
250       gcc_checking_assert (!canonicalize_attr_name (attr_ns, attr_ns_len));
251     }
252   /* In most cases, list is NULL_TREE.  */
253   if (list == NULL_TREE)
254     return NULL_TREE;
255   else
256     {
257       size_t attr_ns_len = attr_ns ? strlen (attr_ns) : 0;
258       size_t attr_len = strlen (attr_name);
259       /* Do the strlen() before calling the out-of-line implementation.
260          In most cases attr_name is a string constant, and the compiler
261          will optimize the strlen() away.  */
262       return private_lookup_attribute (attr_ns, attr_name,
263                                        attr_ns_len, attr_len, list);
264     }
265 }
266
267 /* Given an attribute name ATTR_NAME and a list of attributes LIST,
268    return a pointer to the attribute's list first element if the attribute
269    starts with ATTR_NAME.  ATTR_NAME must be in the form 'text' (not
270    '__text__').  */
271
272 static inline tree
273 lookup_attribute_by_prefix (const char *attr_name, tree list)
274 {
275   gcc_checking_assert (attr_name[0] != '_');
276   /* In most cases, list is NULL_TREE.  */
277   if (list == NULL_TREE)
278     return NULL_TREE;
279   else
280     {
281       size_t attr_len = strlen (attr_name);
282       while (list)
283         {
284           tree name = get_attribute_name (list);
285           size_t ident_len = IDENTIFIER_LENGTH (name);
286
287           if (attr_len > ident_len)
288             {
289               list = TREE_CHAIN (list);
290               continue;
291             }
292
293           const char *p = IDENTIFIER_POINTER (name);
294           gcc_checking_assert (attr_len == 0 || p[0] != '_'
295                                || (ident_len > 1 && p[1] != '_'));
296           if (strncmp (attr_name, p, attr_len) == 0)
297             break;
298
299           list = TREE_CHAIN (list);
300         }
301
302       return list;
303     }
304 }
305
306 /* Description of a function argument declared with attribute access.
307    Used as an "iterator" over all such arguments in a function declaration
308    or call.  */
309
310 struct attr_access
311 {
312   /* The beginning and end of the internal string representation.  */
313   const char *str, *end;
314   /* The attribute pointer argument.  */
315   tree ptr;
316   /* For a declaration, a TREE_CHAIN of VLA bound expressions stored
317      in TREE_VALUE and their positions in the argument list (stored
318      in TREE_PURPOSE).  Each expression may be a PARM_DECL or some
319      other DECL (for ordinary variables), or an EXPR for other
320      expressions (e.g., funcion calls).  */
321   tree size;
322
323   /* The zero-based position of each of the formal function arguments.
324      For the optional SIZARG, UINT_MAX when not specified.  For VLAs
325      with multiple variable bounds, SIZARG is the position corresponding
326      to the most significant bound in the argument list.  Positions of
327      subsequent bounds are in the TREE_PURPOSE field of the SIZE chain.  */
328   unsigned ptrarg;
329   unsigned sizarg;
330   /* For internal specifications only, the constant minimum size of
331      the array, zero if not specified, and HWI_M1U for the unspecified
332      VLA [*] notation.  Meaningless for external (explicit) access
333      specifications.  */
334   unsigned HOST_WIDE_INT minsize;
335
336   /* The access mode.  */
337   access_mode mode;
338
339   /* Set for an attribute added internally rather than by an explicit
340      declaration. */
341   bool internal_p;
342   /* Set for the T[static MINSIZE] array notation for nonzero MINSIZE
343      less than HWI_M1U.  */
344   bool static_p;
345
346   /* Return the number of specified VLA bounds.  */
347   unsigned vla_bounds (unsigned *) const;
348
349   /* Return internal representation as STRING_CST.  */
350   tree to_internal_string () const;
351
352   /* Return the human-readable representation of the external attribute
353      specification (as it might appear in the source code) as STRING_CST.  */
354   tree to_external_string () const;
355
356   /* Return argument of array type formatted as a readable string.  */
357   std::string array_as_string (tree) const;
358
359   /* Return the access mode corresponding to the character code.  */
360   static access_mode from_mode_char (char);
361
362   /* Reset front end-specific attribute access data from attributes.  */
363   static void free_lang_data (tree);
364
365   /* The character codes corresponding to all the access modes.  */
366   static constexpr char mode_chars[5] = { '-', 'r', 'w', 'x', '^' };
367
368   /* The strings corresponding to just the external access modes.  */
369   static constexpr char mode_names[4][11] =
370     {
371      "none", "read_only", "write_only", "read_write"
372     };
373 };
374
375 inline access_mode
376 attr_access::from_mode_char (char c)
377 {
378   switch (c)
379     {
380     case mode_chars[access_none]: return access_none;
381     case mode_chars[access_read_only]: return access_read_only;
382     case mode_chars[access_write_only]: return access_write_only;
383     case mode_chars[access_read_write]: return access_read_write;
384     case mode_chars[access_deferred]: return access_deferred;
385     }
386   gcc_unreachable ();
387 }
388
389 /* Used to define rdwr_map below.  */
390 struct rdwr_access_hash: int_hash<int, -1> { };
391
392 /* A mapping between argument number corresponding to attribute access
393    mode (read_only, write_only, or read_write) and operands.  */
394 struct attr_access;
395 typedef hash_map<rdwr_access_hash, attr_access> rdwr_map;
396
397 extern void init_attr_rdwr_indices (rdwr_map *, tree);
398 extern attr_access *get_parm_access (rdwr_map &, tree,
399                                      tree = current_function_decl);
400
401 #endif // GCC_ATTRIBS_H