1 /* UndefinedBehaviorSanitizer, undefined behavior detector.
2 Copyright (C) 2013 Free Software Foundation, Inc.
3 Contributed by Marek Polacek <polacek@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 #include "pointer-set.h"
33 #include "c-family/c-common.h"
35 /* Map from a tree to a VAR_DECL tree. */
37 struct GTY(()) tree_type_map
{
38 struct tree_map_base type
;
42 #define tree_type_map_eq tree_map_base_eq
43 #define tree_type_map_hash tree_map_base_hash
44 #define tree_type_map_marked_p tree_map_base_marked_p
46 static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map
)))
47 htab_t decl_tree_for_type
;
49 /* Lookup a VAR_DECL for TYPE, and return it if we find one. */
52 decl_for_type_lookup (tree type
)
54 /* If the hash table is not initialized yet, create it now. */
55 if (decl_tree_for_type
== NULL
)
57 decl_tree_for_type
= htab_create_ggc (10, tree_type_map_hash
,
59 /* That also means we don't have to bother with the lookup. */
63 struct tree_type_map
*h
, in
;
66 h
= (struct tree_type_map
*)
67 htab_find_with_hash (decl_tree_for_type
, &in
, TYPE_UID (type
));
68 return h
? h
->decl
: NULL_TREE
;
71 /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
74 decl_for_type_insert (tree type
, tree decl
)
76 struct tree_type_map
*h
;
79 h
= ggc_alloc_tree_type_map ();
82 slot
= htab_find_slot_with_hash (decl_tree_for_type
, h
, TYPE_UID (type
),
84 *(struct tree_type_map
**) slot
= h
;
87 /* Helper routine, which encodes a value in the pointer_sized_int_node.
88 Arguments with precision <= POINTER_SIZE are passed directly,
89 the rest is passed by reference. T is a value we are to encode. */
92 ubsan_encode_value (tree t
)
94 tree type
= TREE_TYPE (t
);
95 switch (TREE_CODE (type
))
98 if (TYPE_PRECISION (type
) <= POINTER_SIZE
)
99 return fold_build1 (NOP_EXPR
, pointer_sized_int_node
, t
);
101 return build_fold_addr_expr (t
);
104 unsigned int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (type
));
105 if (bitsize
<= POINTER_SIZE
)
107 tree itype
= build_nonstandard_integer_type (bitsize
, true);
108 t
= fold_build1 (VIEW_CONVERT_EXPR
, itype
, t
);
109 return fold_convert (pointer_sized_int_node
, t
);
113 if (!TREE_ADDRESSABLE (t
))
115 /* The reason for this is that we don't want to pessimize
116 code by making vars unnecessarily addressable. */
117 tree var
= create_tmp_var (TREE_TYPE (t
), NULL
);
118 tree tem
= build2 (MODIFY_EXPR
, void_type_node
, var
, t
);
119 t
= build_fold_addr_expr (var
);
120 return build2 (COMPOUND_EXPR
, TREE_TYPE (t
), tem
, t
);
123 return build_fold_addr_expr (t
);
132 struct __ubsan_type_descriptor
134 unsigned short __typekind;
135 unsigned short __typeinfo;
141 ubsan_type_descriptor_type (void)
143 static const char *field_names
[3]
144 = { "__typekind", "__typeinfo", "__typename" };
146 tree itype
= build_range_type (sizetype
, size_zero_node
, NULL_TREE
);
147 tree flex_arr_type
= build_array_type (char_type_node
, itype
);
149 ret
= make_node (RECORD_TYPE
);
150 for (int i
= 0; i
< 3; i
++)
152 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
153 get_identifier (field_names
[i
]),
154 (i
== 2) ? flex_arr_type
155 : short_unsigned_type_node
);
156 DECL_CONTEXT (fields
[i
]) = ret
;
158 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
160 TYPE_FIELDS (ret
) = fields
[0];
161 TYPE_NAME (ret
) = get_identifier ("__ubsan_type_descriptor");
167 struct __ubsan_source_location
169 const char *__filename;
171 unsigned int __column;
176 ubsan_source_location_type (void)
178 static const char *field_names
[3]
179 = { "__filename", "__line", "__column" };
181 tree const_char_type
= build_qualified_type (char_type_node
,
184 ret
= make_node (RECORD_TYPE
);
185 for (int i
= 0; i
< 3; i
++)
187 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
,
188 get_identifier (field_names
[i
]),
189 (i
== 0) ? build_pointer_type (const_char_type
)
190 : unsigned_type_node
);
191 DECL_CONTEXT (fields
[i
]) = ret
;
193 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
195 TYPE_FIELDS (ret
) = fields
[0];
196 TYPE_NAME (ret
) = get_identifier ("__ubsan_source_location");
201 /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
202 type with its fields filled from a location_t LOC. */
205 ubsan_source_location (location_t loc
)
207 expanded_location xloc
;
208 tree type
= ubsan_source_location_type ();
210 xloc
= expand_location (loc
);
212 /* Fill in the values from LOC. */
213 size_t len
= strlen (xloc
.file
);
214 tree str
= build_string (len
+ 1, xloc
.file
);
215 TREE_TYPE (str
) = build_array_type (char_type_node
,
216 build_index_type (size_int (len
)));
217 TREE_READONLY (str
) = 1;
218 TREE_STATIC (str
) = 1;
219 str
= build_fold_addr_expr_loc (loc
, str
);
220 tree ctor
= build_constructor_va (type
, 3, NULL_TREE
, str
, NULL_TREE
,
221 build_int_cst (unsigned_type_node
,
222 xloc
.line
), NULL_TREE
,
223 build_int_cst (unsigned_type_node
,
225 TREE_CONSTANT (ctor
) = 1;
226 TREE_STATIC (ctor
) = 1;
231 /* This routine returns a magic number for TYPE. */
233 static unsigned short
234 get_ubsan_type_info_for_type (tree type
)
236 gcc_assert (TYPE_SIZE (type
) && host_integerp (TYPE_SIZE (type
), 1));
237 int prec
= exact_log2 (tree_low_cst (TYPE_SIZE (type
), 1));
238 gcc_assert (prec
!= -1);
239 return (prec
<< 1) | !TYPE_UNSIGNED (type
);
242 /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
243 descriptor. It first looks into the pointer map; if not found,
244 create the VAR_DECL, put it into the pointer map and return the
245 ADDR_EXPR of it. TYPE describes a particular type. */
248 ubsan_type_descriptor (tree type
)
250 /* See through any typedefs. */
251 type
= TYPE_MAIN_VARIANT (type
);
253 tree decl
= decl_for_type_lookup (type
);
254 if (decl
!= NULL_TREE
)
257 tree dtype
= ubsan_type_descriptor_type ();
259 unsigned short tkind
, tinfo
;
261 /* At least for INTEGER_TYPE/REAL_TYPE/COMPLEX_TYPE, this should work.
262 For e.g. type_unsigned_for (type) or bit-fields, the TYPE_NAME
264 if (TYPE_NAME (type
) != NULL
)
266 if (TREE_CODE (TYPE_NAME (type
)) == IDENTIFIER_NODE
)
267 tname
= IDENTIFIER_POINTER (TYPE_NAME (type
));
269 tname
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
)));
274 if (TREE_CODE (type
) == INTEGER_TYPE
)
276 /* For INTEGER_TYPE, this is 0x0000. */
278 tinfo
= get_ubsan_type_info_for_type (type
);
280 else if (TREE_CODE (type
) == REAL_TYPE
)
281 /* We don't have float support yet. */
286 /* Create a new VAR_DECL of type descriptor. */
288 static unsigned int type_var_id_num
;
289 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_type", type_var_id_num
++);
290 decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
292 TREE_STATIC (decl
) = 1;
293 TREE_PUBLIC (decl
) = 0;
294 DECL_ARTIFICIAL (decl
) = 1;
295 DECL_IGNORED_P (decl
) = 1;
296 DECL_EXTERNAL (decl
) = 0;
298 size_t len
= strlen (tname
);
299 tree str
= build_string (len
+ 1, tname
);
300 TREE_TYPE (str
) = build_array_type (char_type_node
,
301 build_index_type (size_int (len
)));
302 TREE_READONLY (str
) = 1;
303 TREE_STATIC (str
) = 1;
304 tree ctor
= build_constructor_va (dtype
, 3, NULL_TREE
,
305 build_int_cst (short_unsigned_type_node
,
307 build_int_cst (short_unsigned_type_node
,
308 tinfo
), NULL_TREE
, str
);
309 TREE_CONSTANT (ctor
) = 1;
310 TREE_STATIC (ctor
) = 1;
311 DECL_INITIAL (decl
) = ctor
;
312 rest_of_decl_compilation (decl
, 1, 0);
314 /* Save the address of the VAR_DECL into the pointer map. */
315 decl
= build_fold_addr_expr (decl
);
316 decl_for_type_insert (type
, decl
);
321 /* Create a structure for the ubsan library. NAME is a name of the new
322 structure. The arguments in ... are of __ubsan_type_descriptor type
323 and there are at most two of them. */
326 ubsan_create_data (const char *name
, location_t loc
, ...)
331 vec
<tree
, va_gc
> *saved_args
= NULL
;
334 /* Firstly, create a pointer to type descriptor type. */
335 tree td_type
= ubsan_type_descriptor_type ();
336 TYPE_READONLY (td_type
) = 1;
337 td_type
= build_pointer_type (td_type
);
339 /* Create the structure type. */
340 ret
= make_node (RECORD_TYPE
);
341 if (loc
!= UNKNOWN_LOCATION
)
343 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
344 ubsan_source_location_type ());
345 DECL_CONTEXT (fields
[i
]) = ret
;
349 va_start (args
, loc
);
350 for (t
= va_arg (args
, tree
); t
!= NULL_TREE
;
351 i
++, t
= va_arg (args
, tree
))
353 gcc_checking_assert (i
< 3);
354 /* Save the tree argument for later use. */
355 vec_safe_push (saved_args
, t
);
356 fields
[i
] = build_decl (UNKNOWN_LOCATION
, FIELD_DECL
, NULL_TREE
,
358 DECL_CONTEXT (fields
[i
]) = ret
;
360 DECL_CHAIN (fields
[i
- 1]) = fields
[i
];
362 TYPE_FIELDS (ret
) = fields
[0];
363 TYPE_NAME (ret
) = get_identifier (name
);
367 /* Now, fill in the type. */
369 static unsigned int ubsan_var_id_num
;
370 ASM_GENERATE_INTERNAL_LABEL (tmp_name
, "Lubsan_data", ubsan_var_id_num
++);
371 tree var
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, get_identifier (tmp_name
),
373 TREE_STATIC (var
) = 1;
374 TREE_PUBLIC (var
) = 0;
375 DECL_ARTIFICIAL (var
) = 1;
376 DECL_IGNORED_P (var
) = 1;
377 DECL_EXTERNAL (var
) = 0;
379 vec
<constructor_elt
, va_gc
> *v
;
381 tree ctor
= build_constructor (ret
, v
);
383 /* If desirable, set the __ubsan_source_location element. */
384 if (loc
!= UNKNOWN_LOCATION
)
385 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, ubsan_source_location (loc
));
387 size_t nelts
= vec_safe_length (saved_args
);
388 for (i
= 0; i
< nelts
; i
++)
390 t
= (*saved_args
)[i
];
391 CONSTRUCTOR_APPEND_ELT (v
, NULL_TREE
, t
);
394 TREE_CONSTANT (ctor
) = 1;
395 TREE_STATIC (ctor
) = 1;
396 DECL_INITIAL (var
) = ctor
;
397 rest_of_decl_compilation (var
, 1, 0);
402 /* Instrument the __builtin_unreachable call. We just call the libubsan
406 ubsan_instrument_unreachable (location_t loc
)
408 tree data
= ubsan_create_data ("__ubsan_unreachable_data", loc
, NULL_TREE
);
409 tree t
= builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE
);
410 return build_call_expr_loc (loc
, t
, 1, build_fold_addr_expr_loc (loc
, data
));
413 /* Return true if T is a call to a libubsan routine. */
416 is_ubsan_builtin_p (tree t
)
418 gcc_checking_assert (TREE_CODE (t
) == FUNCTION_DECL
);
419 return strncmp (IDENTIFIER_POINTER (DECL_NAME (t
)),
420 "__builtin___ubsan_", 18) == 0;
423 #include "gt-ubsan.h"