LCOV - code coverage report
Current view: top level - gcc - ubsan.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.3 % 1394 1343
Test Date: 2026-05-30 15:37:04 Functions: 97.1 % 35 34
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* UndefinedBehaviorSanitizer, undefined behavior detector.
       2              :    Copyright (C) 2013-2026 Free Software Foundation, Inc.
       3              :    Contributed by Marek Polacek <polacek@redhat.com>
       4              : 
       5              : This file is part of GCC.
       6              : 
       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
      10              : version.
      11              : 
      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
      15              : for more details.
      16              : 
      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/>.  */
      20              : 
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "backend.h"
      25              : #include "rtl.h"
      26              : #include "c-family/c-common.h"
      27              : #include "gimple.h"
      28              : #include "cfghooks.h"
      29              : #include "tree-pass.h"
      30              : #include "memmodel.h"
      31              : #include "tm_p.h"
      32              : #include "ssa.h"
      33              : #include "cgraph.h"
      34              : #include "tree-pretty-print.h"
      35              : #include "stor-layout.h"
      36              : #include "cfganal.h"
      37              : #include "gimple-iterator.h"
      38              : #include "output.h"
      39              : #include "cfgloop.h"
      40              : #include "ubsan.h"
      41              : #include "expr.h"
      42              : #include "stringpool.h"
      43              : #include "attribs.h"
      44              : #include "asan.h"
      45              : #include "gimplify-me.h"
      46              : #include "dfp.h"
      47              : #include "builtins.h"
      48              : #include "tree-object-size.h"
      49              : #include "tree-cfg.h"
      50              : #include "gimple-fold.h"
      51              : #include "varasm.h"
      52              : #include "realmpfr.h"
      53              : #include "target.h"
      54              : #include "langhooks.h"
      55              : 
      56              : /* Map from a tree to a VAR_DECL tree.  */
      57              : 
      58              : struct GTY((for_user)) tree_type_map {
      59              :   struct tree_map_base type;
      60              :   tree decl;
      61              : };
      62              : 
      63              : struct tree_type_map_cache_hasher : ggc_cache_ptr_hash<tree_type_map>
      64              : {
      65              :   static inline hashval_t
      66       104460 :   hash (tree_type_map *t)
      67              :   {
      68       104460 :     return TYPE_UID (t->type.from);
      69              :   }
      70              : 
      71              :   static inline bool
      72       119479 :   equal (tree_type_map *a, tree_type_map *b)
      73              :   {
      74       119479 :     return a->type.from == b->type.from;
      75              :   }
      76              : 
      77              :   static int
      78         2111 :   keep_cache_entry (tree_type_map *&m)
      79              :   {
      80         2111 :     return ggc_marked_p (m->type.from);
      81              :   }
      82              : };
      83              : 
      84              : static GTY ((cache))
      85              :      hash_table<tree_type_map_cache_hasher> *decl_tree_for_type;
      86              : 
      87              : /* Lookup a VAR_DECL for TYPE, and return it if we find one.  */
      88              : 
      89              : static tree
      90        39114 : decl_for_type_lookup (tree type)
      91              : {
      92              :   /* If the hash table is not initialized yet, create it now.  */
      93        39114 :   if (decl_tree_for_type == NULL)
      94              :     {
      95         2462 :       decl_tree_for_type
      96         2462 :         = hash_table<tree_type_map_cache_hasher>::create_ggc (10);
      97              :       /* That also means we don't have to bother with the lookup.  */
      98         2462 :       return NULL_TREE;
      99              :     }
     100              : 
     101        36652 :   struct tree_type_map *h, in;
     102        36652 :   in.type.from = type;
     103              : 
     104        36652 :   h = decl_tree_for_type->find_with_hash (&in, TYPE_UID (type));
     105        36652 :   return h ? h->decl : NULL_TREE;
     106              : }
     107              : 
     108              : /* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable.  */
     109              : 
     110              : static void
     111         5366 : decl_for_type_insert (tree type, tree decl)
     112              : {
     113         5366 :   struct tree_type_map *h;
     114              : 
     115         5366 :   h = ggc_alloc<tree_type_map> ();
     116         5366 :   h->type.from = type;
     117         5366 :   h->decl = decl;
     118         5366 :   *decl_tree_for_type->find_slot_with_hash (h, TYPE_UID (type), INSERT) = h;
     119         5366 : }
     120              : 
     121              : /* Helper routine, which encodes a value in the pointer_sized_int_node.
     122              :    Arguments with precision <= POINTER_SIZE are passed directly,
     123              :    the rest is passed by reference.  T is a value we are to encode.
     124              :    PHASE determines when this function is called.  */
     125              : 
     126              : tree
     127        27641 : ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase)
     128              : {
     129        27641 :   tree type = TREE_TYPE (t);
     130        27641 :   if (BITINT_TYPE_P (type))
     131              :     {
     132          290 :       if (TYPE_PRECISION (type) <= POINTER_SIZE)
     133              :         {
     134          102 :           type = pointer_sized_int_node;
     135          102 :           t = fold_build1 (NOP_EXPR, type, t);
     136              :         }
     137              :       else
     138              :         {
     139          376 :           if (TYPE_PRECISION (type) > MAX_FIXED_MODE_SIZE)
     140           86 :             return build_zero_cst (pointer_sized_int_node);
     141          102 :           type = build_nonstandard_integer_type (MAX_FIXED_MODE_SIZE,
     142          102 :                                                  TYPE_UNSIGNED (type));
     143          102 :           t = fold_build1 (NOP_EXPR, type, t);
     144              :         }
     145              :     }
     146        27555 :   scalar_mode mode = SCALAR_TYPE_MODE (type);
     147        27555 :   const unsigned int bitsize = GET_MODE_BITSIZE (mode);
     148        27555 :   if (bitsize <= POINTER_SIZE)
     149        23823 :     switch (TREE_CODE (type))
     150              :       {
     151        14877 :       case BOOLEAN_TYPE:
     152        14877 :       case ENUMERAL_TYPE:
     153        14877 :       case INTEGER_TYPE:
     154        14877 :         return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
     155         8946 :       case REAL_TYPE:
     156         8946 :         {
     157         8946 :           tree itype = build_nonstandard_integer_type (bitsize, true);
     158         8946 :           t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
     159         8946 :           return fold_convert (pointer_sized_int_node, t);
     160              :         }
     161            0 :       default:
     162            0 :         gcc_unreachable ();
     163              :       }
     164              :   else
     165              :     {
     166         3732 :       if (!DECL_P (t) || !TREE_ADDRESSABLE (t))
     167              :         {
     168              :           /* The reason for this is that we don't want to pessimize
     169              :              code by making vars unnecessarily addressable.  */
     170         3732 :           tree var;
     171         3732 :           if (phase != UBSAN_ENCODE_VALUE_GENERIC)
     172              :             {
     173          263 :               var = create_tmp_var (type);
     174          263 :               mark_addressable (var);
     175              :             }
     176              :           else
     177              :             {
     178         3469 :               var = create_tmp_var_raw (type);
     179         3469 :               TREE_ADDRESSABLE (var) = 1;
     180         3469 :               DECL_CONTEXT (var) = current_function_decl;
     181              :             }
     182         3732 :           if (phase == UBSAN_ENCODE_VALUE_RTL)
     183              :             {
     184          526 :               rtx mem = assign_stack_temp_for_type (mode, GET_MODE_SIZE (mode),
     185              :                                                     type);
     186          263 :               SET_DECL_RTL (var, mem);
     187          263 :               expand_assignment (var, t, false);
     188          263 :               return build_fold_addr_expr (var);
     189              :             }
     190         3469 :           if (phase != UBSAN_ENCODE_VALUE_GENERIC)
     191              :             {
     192            0 :               tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
     193            0 :               t = build_fold_addr_expr (var);
     194            0 :               return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
     195              :             }
     196              :           else
     197              :             {
     198         3469 :               var = build4 (TARGET_EXPR, type, var, t, NULL_TREE, NULL_TREE);
     199         3469 :               return build_fold_addr_expr (var);
     200              :             }
     201              :         }
     202              :       else
     203            0 :         return build_fold_addr_expr (t);
     204              :     }
     205              : }
     206              : 
     207              : /* Cached ubsan_get_type_descriptor_type () return value.  */
     208              : static GTY(()) tree ubsan_type_descriptor_type;
     209              : 
     210              : /* Build
     211              :    struct __ubsan_type_descriptor
     212              :    {
     213              :      unsigned short __typekind;
     214              :      unsigned short __typeinfo;
     215              :      char __typename[];
     216              :    }
     217              :    type.  */
     218              : 
     219              : static tree
     220        34341 : ubsan_get_type_descriptor_type (void)
     221              : {
     222        34341 :   static const char *field_names[3]
     223              :     = { "__typekind", "__typeinfo", "__typename" };
     224        34341 :   tree fields[3], ret;
     225              : 
     226        34341 :   if (ubsan_type_descriptor_type)
     227              :     return ubsan_type_descriptor_type;
     228              : 
     229         2683 :   tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
     230         2683 :   tree flex_arr_type = build_array_type (char_type_node, itype);
     231              : 
     232         2683 :   ret = make_node (RECORD_TYPE);
     233        10732 :   for (int i = 0; i < 3; i++)
     234              :     {
     235         8049 :       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
     236              :                               get_identifier (field_names[i]),
     237              :                               (i == 2) ? flex_arr_type
     238              :                               : short_unsigned_type_node);
     239         8049 :       DECL_CONTEXT (fields[i]) = ret;
     240         8049 :       if (i)
     241         5366 :         DECL_CHAIN (fields[i - 1]) = fields[i];
     242              :     }
     243         2683 :   tree type_decl = build_decl (input_location, TYPE_DECL,
     244              :                                get_identifier ("__ubsan_type_descriptor"),
     245              :                                ret);
     246         2683 :   DECL_IGNORED_P (type_decl) = 1;
     247         2683 :   DECL_ARTIFICIAL (type_decl) = 1;
     248         2683 :   TYPE_FIELDS (ret) = fields[0];
     249         2683 :   TYPE_NAME (ret) = type_decl;
     250         2683 :   TYPE_STUB_DECL (ret) = type_decl;
     251         2683 :   TYPE_ARTIFICIAL (ret) = 1;
     252         2683 :   layout_type (ret);
     253         2683 :   ubsan_type_descriptor_type = ret;
     254         2683 :   return ret;
     255              : }
     256              : 
     257              : /* Cached ubsan_get_source_location_type () return value.  */
     258              : static GTY(()) tree ubsan_source_location_type;
     259              : 
     260              : /* Build
     261              :    struct __ubsan_source_location
     262              :    {
     263              :      const char *__filename;
     264              :      unsigned int __line;
     265              :      unsigned int __column;
     266              :    }
     267              :    type.  */
     268              : 
     269              : tree
     270        69783 : ubsan_get_source_location_type (void)
     271              : {
     272        69783 :   static const char *field_names[3]
     273              :     = { "__filename", "__line", "__column" };
     274        69783 :   tree fields[3], ret;
     275        69783 :   if (ubsan_source_location_type)
     276              :     return ubsan_source_location_type;
     277              : 
     278         3535 :   tree const_char_type = build_qualified_type (char_type_node,
     279              :                                                TYPE_QUAL_CONST);
     280              : 
     281         3535 :   ret = make_node (RECORD_TYPE);
     282        14140 :   for (int i = 0; i < 3; i++)
     283              :     {
     284        14140 :       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
     285              :                               get_identifier (field_names[i]),
     286         3535 :                               (i == 0) ? build_pointer_type (const_char_type)
     287              :                               : unsigned_type_node);
     288        10605 :       DECL_CONTEXT (fields[i]) = ret;
     289        10605 :       if (i)
     290         7070 :         DECL_CHAIN (fields[i - 1]) = fields[i];
     291              :     }
     292         3535 :   tree type_decl = build_decl (input_location, TYPE_DECL,
     293              :                                get_identifier ("__ubsan_source_location"),
     294              :                                ret);
     295         3535 :   DECL_IGNORED_P (type_decl) = 1;
     296         3535 :   DECL_ARTIFICIAL (type_decl) = 1;
     297         3535 :   TYPE_FIELDS (ret) = fields[0];
     298         3535 :   TYPE_NAME (ret) = type_decl;
     299         3535 :   TYPE_STUB_DECL (ret) = type_decl;
     300         3535 :   TYPE_ARTIFICIAL (ret) = 1;
     301         3535 :   layout_type (ret);
     302         3535 :   ubsan_source_location_type = ret;
     303         3535 :   return ret;
     304              : }
     305              : 
     306              : /* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
     307              :    type with its fields filled from a location_t LOC.  */
     308              : 
     309              : static tree
     310        29803 : ubsan_source_location (location_t loc)
     311              : {
     312        29803 :   expanded_location xloc;
     313        29803 :   tree type = ubsan_get_source_location_type ();
     314              : 
     315        29803 :   xloc = expand_location (loc);
     316        29803 :   tree str;
     317        29803 :   if (xloc.file == NULL)
     318              :     {
     319          935 :       str = build_int_cst (ptr_type_node, 0);
     320          935 :       xloc.line = 0;
     321          935 :       xloc.column = 0;
     322              :     }
     323              :   else
     324              :     {
     325              :       /* Fill in the values from LOC.  */
     326        28868 :       size_t len = strlen (xloc.file) + 1;
     327        28868 :       str = build_string (len, xloc.file);
     328        28868 :       TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
     329        28868 :       TREE_READONLY (str) = 1;
     330        28868 :       TREE_STATIC (str) = 1;
     331        28868 :       str = build_fold_addr_expr (str);
     332              :     }
     333        29803 :   tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
     334              :                                     build_int_cst (unsigned_type_node,
     335        29803 :                                                    xloc.line), NULL_TREE,
     336              :                                     build_int_cst (unsigned_type_node,
     337        29803 :                                                    xloc.column));
     338        29803 :   TREE_CONSTANT (ctor) = 1;
     339        29803 :   TREE_STATIC (ctor) = 1;
     340              : 
     341        29803 :   return ctor;
     342              : }
     343              : 
     344              : /* This routine returns a magic number for TYPE.  */
     345              : 
     346              : static unsigned short
     347         3884 : get_ubsan_type_info_for_type (tree type)
     348              : {
     349         3884 :   if (SCALAR_FLOAT_TYPE_P (type))
     350          213 :     return tree_to_uhwi (TYPE_SIZE (type));
     351         3671 :   else if (INTEGRAL_TYPE_P (type))
     352              :     {
     353         3671 :       int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
     354            0 :       gcc_assert (prec != -1);
     355         3671 :       return (prec << 1) | !TYPE_UNSIGNED (type);
     356              :     }
     357              :   else
     358              :     return 0;
     359              : }
     360              : 
     361              : /* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
     362              :    descriptor.  It first looks into the hash table; if not found,
     363              :    create the VAR_DECL, put it into the hash table and return the
     364              :    ADDR_EXPR of it.  TYPE describes a particular type.  PSTYLE is
     365              :    an enum controlling how we want to print the type.  */
     366              : 
     367              : tree
     368        39114 : ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
     369              : {
     370              :   /* See through any typedefs.  */
     371        39114 :   type = TYPE_MAIN_VARIANT (type);
     372        39114 :   tree type3 = type;
     373        39114 :   if (pstyle == UBSAN_PRINT_FORCE_INT)
     374              :     {
     375              :       /* Temporary hack for -fsanitize=shift with _BitInt(129) and more.
     376              :          libubsan crashes if it is not TK_Integer type.  */
     377         1104 :       if (BITINT_TYPE_P (type) && TYPE_PRECISION (type) > MAX_FIXED_MODE_SIZE)
     378           16 :         type3 = build_qualified_type (type, TYPE_QUAL_CONST);
     379         1024 :       if (type3 == type)
     380         1008 :         pstyle = UBSAN_PRINT_NORMAL;
     381              :     }
     382              : 
     383        39114 :   tree decl = decl_for_type_lookup (type3);
     384              :   /* It is possible that some of the earlier created DECLs were found
     385              :      unused, in that case they weren't emitted and varpool_node::get
     386              :      returns NULL node on them.  But now we really need them.  Thus,
     387              :      renew them here.  */
     388        39114 :   if (decl != NULL_TREE && varpool_node::get (decl))
     389              :     {
     390        33748 :       return build_fold_addr_expr (decl);
     391              :     }
     392              : 
     393         5366 :   tree dtype = ubsan_get_type_descriptor_type ();
     394         5366 :   tree type2 = type;
     395         5366 :   const char *tname = NULL;
     396         5366 :   pretty_printer pretty_name;
     397         5366 :   unsigned char deref_depth = 0;
     398         5366 :   unsigned short tkind, tinfo;
     399         5366 :   char tname_bitint[sizeof ("unsigned _BitInt(2147483647)")];
     400              : 
     401              :   /* Get the name of the type, or the name of the pointer type.  */
     402         5366 :   if (pstyle == UBSAN_PRINT_POINTER)
     403              :     {
     404         1172 :       gcc_assert (POINTER_TYPE_P (type));
     405         1172 :       type2 = TREE_TYPE (type);
     406              : 
     407              :       /* Remove any '*' operators from TYPE.  */
     408         1296 :       while (POINTER_TYPE_P (type2))
     409          124 :         deref_depth++, type2 = TREE_TYPE (type2);
     410              : 
     411         1172 :       if (TREE_CODE (type2) == METHOD_TYPE)
     412            0 :         type2 = TYPE_METHOD_BASETYPE (type2);
     413              :     }
     414              : 
     415              :   /* If an array, get its type.  */
     416         5366 :   type2 = strip_array_types (type2);
     417              : 
     418         5366 :   if (pstyle == UBSAN_PRINT_ARRAY)
     419              :     {
     420         1045 :       while (POINTER_TYPE_P (type2))
     421           54 :         deref_depth++, type2 = TREE_TYPE (type2);
     422              :     }
     423              : 
     424         5366 :   if (TYPE_NAME (type2) != NULL)
     425              :     {
     426         5261 :       if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
     427          687 :         tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
     428         4574 :       else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
     429         4571 :         tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
     430              :     }
     431              : 
     432         5258 :   if (tname == NULL)
     433              :     {
     434          108 :       if (BITINT_TYPE_P (type2))
     435              :         {
     436          152 :           snprintf (tname_bitint, sizeof (tname_bitint),
     437           38 :                     "%s_BitInt(%d)", TYPE_UNSIGNED (type2) ? "unsigned " : "",
     438           38 :                     TYPE_PRECISION (type2));
     439           38 :           tname = tname_bitint;
     440              :         }
     441              :       else
     442              :         /* We weren't able to determine the type name.  */
     443              :         tname = "<unknown>";
     444              :     }
     445              : 
     446         5366 :   pp_quote (&pretty_name);
     447              : 
     448         5366 :   tree eltype = type;
     449         5366 :   if (pstyle == UBSAN_PRINT_POINTER)
     450              :     {
     451         1172 :       pp_printf (&pretty_name, "%s%s%s%s%s%s%s",
     452         1172 :                  TYPE_VOLATILE (type2) ? "volatile " : "",
     453         1172 :                  TYPE_READONLY (type2) ? "const " : "",
     454         1172 :                  TYPE_RESTRICT (type2) ? "restrict " : "",
     455         1172 :                  TYPE_ATOMIC (type2) ? "_Atomic " : "",
     456         1172 :                  TREE_CODE (type2) == RECORD_TYPE
     457              :                  ? "struct "
     458              :                  : TREE_CODE (type2) == UNION_TYPE
     459          707 :                    ? "union " : "", tname,
     460              :                  deref_depth == 0 ? "" : " ");
     461         2468 :       while (deref_depth-- > 0)
     462          124 :         pp_star (&pretty_name);
     463              :     }
     464         4194 :   else if (pstyle == UBSAN_PRINT_ARRAY)
     465              :     {
     466              :       /* Pretty print the array dimensions.  */
     467          991 :       gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
     468          991 :       tree t = type;
     469          991 :       pp_string (&pretty_name, tname);
     470          991 :       pp_space (&pretty_name);
     471         2036 :       while (deref_depth-- > 0)
     472           54 :         pp_star (&pretty_name);
     473         2158 :       while (TREE_CODE (t) == ARRAY_TYPE)
     474              :         {
     475         1167 :           pp_left_bracket (&pretty_name);
     476         1167 :           tree dom = TYPE_DOMAIN (t);
     477         1167 :           if (dom != NULL_TREE
     478         1167 :               && TYPE_MAX_VALUE (dom) != NULL_TREE
     479         2066 :               && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
     480              :             {
     481          559 :               unsigned HOST_WIDE_INT m;
     482          559 :               if (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))
     483          559 :                   && (m = tree_to_uhwi (TYPE_MAX_VALUE (dom))) + 1 != 0)
     484          547 :                 pp_unsigned_wide_integer (&pretty_name, m + 1);
     485              :               else
     486           12 :                 pp_wide_int (&pretty_name,
     487           24 :                              wi::add (wi::to_widest (TYPE_MAX_VALUE (dom)), 1),
     488           12 :                              TYPE_SIGN (TREE_TYPE (dom)));
     489              :             }
     490              :           else
     491              :             /* ??? We can't determine the variable name; print VLA unspec.  */
     492          608 :             pp_star (&pretty_name);
     493         1167 :           pp_right_bracket (&pretty_name);
     494         1167 :           t = TREE_TYPE (t);
     495              :         }
     496              : 
     497              :       /* Save the tree with stripped types.  */
     498              :       eltype = t;
     499              :     }
     500              :   else
     501         3203 :     pp_string (&pretty_name, tname);
     502              : 
     503         5366 :   pp_quote (&pretty_name);
     504              : 
     505         5366 :   switch (TREE_CODE (eltype))
     506              :     {
     507              :     case BOOLEAN_TYPE:
     508              :     case INTEGER_TYPE:
     509              :       tkind = 0x0000;
     510              :       break;
     511           16 :     case ENUMERAL_TYPE:
     512           16 :       if (!BITINT_TYPE_P (eltype))
     513              :         {
     514              :           tkind = 0x0000;
     515              :           break;
     516              :         }
     517              :       /* FALLTHRU */
     518           38 :     case BITINT_TYPE:
     519           76 :       if (TYPE_PRECISION (eltype) <= MAX_FIXED_MODE_SIZE)
     520              :         tkind = 0x0000;
     521              :       else
     522              :         tkind = 0xffff;
     523              :       break;
     524          247 :     case REAL_TYPE:
     525              :       /* FIXME: libubsan right now only supports float, double and
     526              :          long double type formats.  */
     527          247 :       if (TYPE_MODE (eltype) == TYPE_MODE (float_type_node)
     528          190 :           || TYPE_MODE (eltype) == TYPE_MODE (double_type_node)
     529          324 :           || TYPE_MODE (eltype) == TYPE_MODE (long_double_type_node))
     530              :         tkind = 0x0001;
     531              :       else
     532              :         tkind = 0xffff;
     533              :       break;
     534              :     default:
     535              :       tkind = 0xffff;
     536              :       break;
     537              :     }
     538         3876 :   tinfo = tkind == 0xffff ? 0 : get_ubsan_type_info_for_type (eltype);
     539              : 
     540         5366 :   if (pstyle == UBSAN_PRINT_FORCE_INT)
     541              :     {
     542            8 :       tkind = 0x0000;
     543            8 :       tree t = build_nonstandard_integer_type (MAX_FIXED_MODE_SIZE,
     544            8 :                                                TYPE_UNSIGNED (eltype));
     545            8 :       tinfo = get_ubsan_type_info_for_type (t);
     546              :     }
     547              : 
     548              :   /* Create a new VAR_DECL of type descriptor.  */
     549         5366 :   const char *tmp = pp_formatted_text (&pretty_name);
     550         5366 :   size_t len = strlen (tmp) + 1;
     551         5366 :   tree str = build_string (len, tmp);
     552         5366 :   TREE_TYPE (str) = build_array_type_nelts (char_type_node, len);
     553         5366 :   TREE_READONLY (str) = 1;
     554         5366 :   TREE_STATIC (str) = 1;
     555              : 
     556         5366 :   decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
     557              :                      generate_internal_label ("Lubsan_type"), dtype);
     558         5366 :   TREE_STATIC (decl) = 1;
     559         5366 :   TREE_PUBLIC (decl) = 0;
     560         5366 :   DECL_ARTIFICIAL (decl) = 1;
     561         5366 :   DECL_IGNORED_P (decl) = 1;
     562         5366 :   DECL_EXTERNAL (decl) = 0;
     563         5366 :   DECL_SIZE (decl)
     564         5366 :     = size_binop (PLUS_EXPR, DECL_SIZE (decl), TYPE_SIZE (TREE_TYPE (str)));
     565         5366 :   DECL_SIZE_UNIT (decl)
     566         5366 :     = size_binop (PLUS_EXPR, DECL_SIZE_UNIT (decl),
     567              :                   TYPE_SIZE_UNIT (TREE_TYPE (str)));
     568              : 
     569         5366 :   tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
     570              :                                     build_int_cst (short_unsigned_type_node,
     571         5366 :                                                    tkind), NULL_TREE,
     572              :                                     build_int_cst (short_unsigned_type_node,
     573         5366 :                                                    tinfo), NULL_TREE, str);
     574         5366 :   TREE_CONSTANT (ctor) = 1;
     575         5366 :   TREE_STATIC (ctor) = 1;
     576         5366 :   DECL_INITIAL (decl) = ctor;
     577         5366 :   varpool_node::finalize_decl (decl);
     578              : 
     579              :   /* Save the VAR_DECL into the hash table.  */
     580         5366 :   decl_for_type_insert (type3, decl);
     581              : 
     582         5366 :   return build_fold_addr_expr (decl);
     583         5366 : }
     584              : 
     585              : /* Create a structure for the ubsan library.  NAME is a name of the new
     586              :    structure.  LOCCNT is number of locations, PLOC points to array of
     587              :    locations.  The arguments in ... are of __ubsan_type_descriptor type
     588              :    and there are at most two of them, followed by NULL_TREE, followed
     589              :    by optional extra arguments and another NULL_TREE.  */
     590              : 
     591              : tree
     592        28975 : ubsan_create_data (const char *name, int loccnt, const location_t *ploc, ...)
     593              : {
     594        28975 :   va_list args;
     595        28975 :   tree ret, t;
     596        28975 :   tree fields[6];
     597        28975 :   vec<tree, va_gc> *saved_args = NULL;
     598        28975 :   size_t i = 0;
     599        28975 :   int j;
     600              : 
     601              :   /* It is possible that PCH zapped table with definitions of sanitizer
     602              :      builtins.  Reinitialize them if needed.  */
     603        28975 :   initialize_sanitizer_builtins ();
     604              : 
     605              :   /* Firstly, create a pointer to type descriptor type.  */
     606        28975 :   tree td_type = ubsan_get_type_descriptor_type ();
     607        28975 :   td_type = build_pointer_type (td_type);
     608              : 
     609              :   /* Create the structure type.  */
     610        28975 :   ret = make_node (RECORD_TYPE);
     611        87753 :   for (j = 0; j < loccnt; j++)
     612              :     {
     613        29803 :       gcc_checking_assert (i < 2);
     614        29803 :       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
     615              :                               ubsan_get_source_location_type ());
     616        29803 :       DECL_CONTEXT (fields[i]) = ret;
     617        29803 :       if (i)
     618          828 :         DECL_CHAIN (fields[i - 1]) = fields[i];
     619        29803 :       i++;
     620              :     }
     621              : 
     622        28975 :   va_start (args, ploc);
     623        68089 :   for (t = va_arg (args, tree); t != NULL_TREE;
     624        39114 :        i++, t = va_arg (args, tree))
     625              :     {
     626        39114 :       gcc_checking_assert (i < 4);
     627              :       /* Save the tree arguments for later use.  */
     628        39114 :       vec_safe_push (saved_args, t);
     629        39114 :       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
     630              :                               td_type);
     631        39114 :       DECL_CONTEXT (fields[i]) = ret;
     632        39114 :       if (i)
     633        39114 :         DECL_CHAIN (fields[i - 1]) = fields[i];
     634              :     }
     635              : 
     636        37453 :   for (t = va_arg (args, tree); t != NULL_TREE;
     637         8478 :        i++, t = va_arg (args, tree))
     638              :     {
     639         8478 :       gcc_checking_assert (i < 6);
     640              :       /* Save the tree arguments for later use.  */
     641         8478 :       vec_safe_push (saved_args, t);
     642         8478 :       fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
     643         8478 :                               TREE_TYPE (t));
     644         8478 :       DECL_CONTEXT (fields[i]) = ret;
     645         8478 :       if (i)
     646         8478 :         DECL_CHAIN (fields[i - 1]) = fields[i];
     647              :     }
     648        28975 :   va_end (args);
     649              : 
     650        28975 :   tree type_decl = build_decl (input_location, TYPE_DECL,
     651              :                                get_identifier (name), ret);
     652        28975 :   DECL_IGNORED_P (type_decl) = 1;
     653        28975 :   DECL_ARTIFICIAL (type_decl) = 1;
     654        28975 :   TYPE_FIELDS (ret) = fields[0];
     655        28975 :   TYPE_NAME (ret) = type_decl;
     656        28975 :   TYPE_STUB_DECL (ret) = type_decl;
     657        28975 :   TYPE_ARTIFICIAL (ret) = 1;
     658        28975 :   layout_type (ret);
     659              : 
     660              :   /* Now, fill in the type.  */
     661        28975 :   tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
     662              :                          generate_internal_label ("Lubsan_data"), ret);
     663        28975 :   TREE_STATIC (var) = 1;
     664        28975 :   TREE_PUBLIC (var) = 0;
     665        28975 :   DECL_ARTIFICIAL (var) = 1;
     666        28975 :   DECL_IGNORED_P (var) = 1;
     667        28975 :   DECL_EXTERNAL (var) = 0;
     668              : 
     669        28975 :   vec<constructor_elt, va_gc> *v;
     670        28975 :   vec_alloc (v, i);
     671        28975 :   tree ctor = build_constructor (ret, v);
     672              : 
     673              :   /* If desirable, set the __ubsan_source_location element.  */
     674        58778 :   for (j = 0; j < loccnt; j++)
     675              :     {
     676        29803 :       location_t loc = LOCATION_LOCUS (ploc[j]);
     677        29803 :       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
     678              :     }
     679              : 
     680        28975 :   size_t nelts = vec_safe_length (saved_args);
     681        76567 :   for (i = 0; i < nelts; i++)
     682              :     {
     683        47592 :       t = (*saved_args)[i];
     684        47592 :       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
     685              :     }
     686              : 
     687        28975 :   TREE_CONSTANT (ctor) = 1;
     688        28975 :   TREE_STATIC (ctor) = 1;
     689        28975 :   DECL_INITIAL (var) = ctor;
     690        28975 :   varpool_node::finalize_decl (var);
     691              : 
     692        28975 :   return var;
     693              : }
     694              : 
     695              : /* Shared between *build_builtin_unreachable.  */
     696              : 
     697              : tree
     698     19530108 : sanitize_unreachable_fn (tree *data, location_t loc)
     699              : {
     700     19530108 :   tree fn = NULL_TREE;
     701     19530108 :   bool san = sanitize_flags_p (SANITIZE_UNREACHABLE);
     702     19530108 :   if (san
     703     19530108 :       ? (flag_sanitize_trap & SANITIZE_UNREACHABLE)
     704     19529906 :       : flag_unreachable_traps)
     705              :     {
     706       836377 :       fn = builtin_decl_explicit (BUILT_IN_UNREACHABLE_TRAP);
     707       836377 :       *data = NULL_TREE;
     708              :     }
     709     18693731 :   else if (san)
     710              :     {
     711              :       /* Call ubsan_create_data first as it initializes SANITIZER built-ins.  */
     712          202 :       *data = ubsan_create_data ("__ubsan_unreachable_data", 1, &loc,
     713              :                                  NULL_TREE, NULL_TREE);
     714          202 :       fn = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
     715          202 :       *data = build_fold_addr_expr_loc (loc, *data);
     716              :     }
     717              :   else
     718              :     {
     719     18693529 :       fn = builtin_decl_explicit (BUILT_IN_UNREACHABLE);
     720     18693529 :       *data = NULL_TREE;
     721              :     }
     722     19530108 :   return fn;
     723              : }
     724              : 
     725              : /* Rewrite a gcall to __builtin_unreachable for -fsanitize=unreachable.  Called
     726              :    by the sanopt pass.  */
     727              : 
     728              : bool
     729            0 : ubsan_instrument_unreachable (gimple_stmt_iterator *gsi)
     730              : {
     731            0 :   location_t loc = gimple_location (gsi_stmt (*gsi));
     732            0 :   gimple *g = gimple_build_builtin_unreachable (loc);
     733            0 :   gsi_replace (gsi, g, false);
     734            0 :   return false;
     735              : }
     736              : 
     737              : /* Return true if T is a call to a libubsan routine.  */
     738              : 
     739              : bool
     740    137857516 : is_ubsan_builtin_p (tree t)
     741              : {
     742    137857516 :   return TREE_CODE (t) == FUNCTION_DECL
     743    137857515 :          && fndecl_built_in_p (t, BUILT_IN_NORMAL)
     744    147356895 :          && strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
     745    137857516 :                      "__builtin___ubsan_", 18) == 0;
     746              : }
     747              : 
     748              : /* Create a callgraph edge for statement STMT.  */
     749              : 
     750              : static void
     751         3394 : ubsan_create_edge (gimple *stmt)
     752              : {
     753         3394 :   gcall *call_stmt = dyn_cast <gcall *> (stmt);
     754         3394 :   basic_block bb = gimple_bb (stmt);
     755         3394 :   cgraph_node *node = cgraph_node::get (current_function_decl);
     756         3394 :   tree decl = gimple_call_fndecl (call_stmt);
     757         3394 :   if (decl)
     758         3394 :     node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count);
     759         3394 : }
     760              : 
     761              : /* Expand the UBSAN_BOUNDS special builtin function.  */
     762              : 
     763              : bool
     764         1638 : ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
     765              : {
     766         1638 :   gimple *stmt = gsi_stmt (*gsi);
     767         1638 :   location_t loc = gimple_location (stmt);
     768         1638 :   gcc_assert (gimple_call_num_args (stmt) == 3);
     769              : 
     770              :   /* Pick up the arguments of the UBSAN_BOUNDS call.  */
     771         1638 :   tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
     772         1638 :   tree index = gimple_call_arg (stmt, 1);
     773         1638 :   tree orig_index = index;
     774         1638 :   tree bound = gimple_call_arg (stmt, 2);
     775              : 
     776         1638 :   gimple_stmt_iterator gsi_orig = *gsi;
     777              : 
     778              :   /* Create condition "if (index >= bound)".  */
     779         1638 :   basic_block then_bb, fallthru_bb;
     780         1638 :   gimple_stmt_iterator cond_insert_point
     781         1638 :     = create_cond_insert_point (gsi, false, false, true,
     782              :                                 &then_bb, &fallthru_bb);
     783         1638 :   index = fold_convert (TREE_TYPE (bound), index);
     784         1638 :   index = force_gimple_operand_gsi (&cond_insert_point, index,
     785              :                                     true, NULL_TREE,
     786              :                                     false, GSI_NEW_STMT);
     787         1638 :   gimple *g = gimple_build_cond (GE_EXPR, index, bound, NULL_TREE, NULL_TREE);
     788         1638 :   gimple_set_location (g, loc);
     789         1638 :   gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
     790              : 
     791              :   /* Generate __ubsan_handle_out_of_bounds call.  */
     792         1638 :   *gsi = gsi_after_labels (then_bb);
     793         1638 :   if (flag_sanitize_trap & SANITIZE_BOUNDS)
     794            0 :     g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
     795              :   else
     796              :     {
     797         1638 :       tree data
     798         1638 :         = ubsan_create_data ("__ubsan_out_of_bounds_data", 1, &loc,
     799              :                              ubsan_type_descriptor (type, UBSAN_PRINT_ARRAY),
     800         1638 :                              ubsan_type_descriptor (TREE_TYPE (orig_index)),
     801              :                              NULL_TREE, NULL_TREE);
     802         1638 :       data = build_fold_addr_expr_loc (loc, data);
     803          116 :       enum built_in_function bcode
     804         1638 :         = (flag_sanitize_recover & SANITIZE_BOUNDS)
     805         1638 :           ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
     806              :           : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
     807         1638 :       tree fn = builtin_decl_explicit (bcode);
     808         1638 :       tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE);
     809         1638 :       val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true,
     810              :                                       GSI_SAME_STMT);
     811         1638 :       g = gimple_build_call (fn, 2, data, val);
     812              :     }
     813         1638 :   gimple_set_location (g, loc);
     814         1638 :   gsi_insert_before (gsi, g, GSI_SAME_STMT);
     815              : 
     816              :   /* Get rid of the UBSAN_BOUNDS call from the IR.  */
     817         1638 :   unlink_stmt_vdef (stmt);
     818         1638 :   gsi_remove (&gsi_orig, true);
     819              : 
     820              :   /* Point GSI to next logical statement.  */
     821         1638 :   *gsi = gsi_start_bb (fallthru_bb);
     822         1638 :   return true;
     823              : }
     824              : 
     825              : /* Expand UBSAN_NULL internal call.  The type is kept on the ckind
     826              :    argument which is a constant, because the middle-end treats pointer
     827              :    conversions as useless and therefore the type of the first argument
     828              :    could be changed to any other pointer type.  */
     829              : 
     830              : bool
     831         2942 : ubsan_expand_null_ifn (gimple_stmt_iterator *gsip)
     832              : {
     833         2942 :   gimple_stmt_iterator gsi = *gsip;
     834         2942 :   gimple *stmt = gsi_stmt (gsi);
     835         2942 :   location_t loc = gimple_location (stmt);
     836         2942 :   gcc_assert (gimple_call_num_args (stmt) == 3);
     837         2942 :   tree ptr = gimple_call_arg (stmt, 0);
     838         2942 :   tree ckind = gimple_call_arg (stmt, 1);
     839         2942 :   tree align = gimple_call_arg (stmt, 2);
     840         2942 :   tree check_align = NULL_TREE;
     841         2942 :   bool check_null;
     842              : 
     843         2942 :   basic_block cur_bb = gsi_bb (gsi);
     844              : 
     845         2942 :   gimple *g;
     846         2942 :   if (!integer_zerop (align))
     847              :     {
     848         2041 :       unsigned int ptralign = get_pointer_alignment (ptr) / BITS_PER_UNIT;
     849         2041 :       if (compare_tree_int (align, ptralign) == 1)
     850              :         {
     851         1574 :           check_align = make_ssa_name (pointer_sized_int_node);
     852         1574 :           g = gimple_build_assign (check_align, NOP_EXPR, ptr);
     853         1574 :           gimple_set_location (g, loc);
     854         1574 :           gsi_insert_before (&gsi, g, GSI_SAME_STMT);
     855              :         }
     856              :     }
     857         2942 :   check_null = sanitize_flags_p (SANITIZE_NULL);
     858         2942 :   if (check_null && POINTER_TYPE_P (TREE_TYPE (ptr)))
     859              :     {
     860         2644 :       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (ptr)));
     861         2644 :       if (!ADDR_SPACE_GENERIC_P (as)
     862         2644 :           && targetm.addr_space.zero_address_valid (as))
     863              :         check_null = false;
     864              :     }
     865              : 
     866         2942 :   if (check_align == NULL_TREE && !check_null)
     867              :     {
     868           20 :       gsi_remove (gsip, true);
     869              :       /* Unlink the UBSAN_NULLs vops before replacing it.  */
     870           20 :       unlink_stmt_vdef (stmt);
     871           20 :       return true;
     872              :     }
     873              : 
     874              :   /* Split the original block holding the pointer dereference.  */
     875         2922 :   edge e = split_block (cur_bb, stmt);
     876              : 
     877              :   /* Get a hold on the 'condition block', the 'then block' and the
     878              :      'else block'.  */
     879         2922 :   basic_block cond_bb = e->src;
     880         2922 :   basic_block fallthru_bb = e->dest;
     881         2922 :   basic_block then_bb = create_empty_bb (cond_bb);
     882         2922 :   add_bb_to_loop (then_bb, cond_bb->loop_father);
     883         2922 :   loops_state_set (LOOPS_NEED_FIXUP);
     884              : 
     885              :   /* Make an edge coming from the 'cond block' into the 'then block';
     886              :      this edge is unlikely taken, so set up the probability accordingly.  */
     887         2922 :   e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
     888         2922 :   e->probability = profile_probability::very_unlikely ();
     889         2922 :   then_bb->count = e->count ();
     890              : 
     891              :   /* Connect 'then block' with the 'else block'.  This is needed
     892              :      as the ubsan routines we call in the 'then block' are not noreturn.
     893              :      The 'then block' only has one outcoming edge.  */
     894         2922 :   make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
     895              : 
     896              :   /* Set up the fallthrough basic block.  */
     897         2922 :   e = find_edge (cond_bb, fallthru_bb);
     898         2922 :   e->flags = EDGE_FALSE_VALUE;
     899         2922 :   e->probability = profile_probability::very_likely ();
     900              : 
     901              :   /* Update dominance info for the newly created then_bb; note that
     902              :      fallthru_bb's dominance info has already been updated by
     903              :      split_block.  */
     904         2922 :   if (dom_info_available_p (CDI_DOMINATORS))
     905         2922 :     set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
     906              : 
     907              :   /* Put the ubsan builtin call into the newly created BB.  */
     908         2922 :   if (flag_sanitize_trap & ((check_align ? SANITIZE_ALIGNMENT + 0 : 0)
     909         3204 :                             | (check_null ? SANITIZE_NULL + 0 : 0)))
     910          106 :     g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
     911              :   else
     912              :     {
     913          542 :       enum built_in_function bcode
     914         2869 :         = (flag_sanitize_recover & ((check_align ? SANITIZE_ALIGNMENT + 0 : 0)
     915              :                                     | (check_null ? SANITIZE_NULL + 0 : 0)))
     916         2869 :           ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
     917              :           : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT;
     918         2869 :       tree fn = builtin_decl_implicit (bcode);
     919         2869 :       int align_log = tree_log2 (align);
     920         2869 :       tree data
     921         5738 :         = ubsan_create_data ("__ubsan_null_data", 1, &loc,
     922         2869 :                              ubsan_type_descriptor (TREE_TYPE (ckind),
     923              :                                                     UBSAN_PRINT_POINTER),
     924              :                              NULL_TREE,
     925              :                              build_int_cst (unsigned_char_type_node,
     926         2869 :                                             MAX (align_log, 0)),
     927              :                              fold_convert (unsigned_char_type_node, ckind),
     928              :                              NULL_TREE);
     929         2869 :       data = build_fold_addr_expr_loc (loc, data);
     930         4214 :       g = gimple_build_call (fn, 2, data,
     931              :                              check_align ? check_align
     932         1345 :                              : build_zero_cst (pointer_sized_int_node));
     933              :     }
     934         2922 :   gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
     935         2922 :   gimple_set_location (g, loc);
     936         2922 :   gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
     937              : 
     938              :   /* Unlink the UBSAN_NULLs vops before replacing it.  */
     939         2922 :   unlink_stmt_vdef (stmt);
     940              : 
     941         2922 :   if (check_null)
     942              :     {
     943         2640 :       g = gimple_build_cond (EQ_EXPR, ptr, build_int_cst (TREE_TYPE (ptr), 0),
     944              :                              NULL_TREE, NULL_TREE);
     945         2640 :       gimple_set_location (g, loc);
     946              : 
     947              :       /* Replace the UBSAN_NULL with a GIMPLE_COND stmt.  */
     948         2640 :       gsi_replace (&gsi, g, false);
     949         2640 :       stmt = g;
     950              :     }
     951              : 
     952         2922 :   if (check_align)
     953              :     {
     954         1574 :       if (check_null)
     955              :         {
     956              :           /* Split the block with the condition again.  */
     957         1292 :           e = split_block (cond_bb, stmt);
     958         1292 :           basic_block cond1_bb = e->src;
     959         1292 :           basic_block cond2_bb = e->dest;
     960              : 
     961              :           /* Make an edge coming from the 'cond1 block' into the 'then block';
     962              :              this edge is unlikely taken, so set up the probability
     963              :              accordingly.  */
     964         1292 :           e = make_edge (cond1_bb, then_bb, EDGE_TRUE_VALUE);
     965         1292 :           e->probability = profile_probability::very_unlikely ();
     966              : 
     967              :           /* Set up the fallthrough basic block.  */
     968         1292 :           e = find_edge (cond1_bb, cond2_bb);
     969         1292 :           e->flags = EDGE_FALSE_VALUE;
     970         1292 :           e->probability = profile_probability::very_likely ();
     971              : 
     972              :           /* Update dominance info.  */
     973         1292 :           if (dom_info_available_p (CDI_DOMINATORS))
     974              :             {
     975         1292 :               set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond1_bb);
     976         1292 :               set_immediate_dominator (CDI_DOMINATORS, then_bb, cond1_bb);
     977              :             }
     978              : 
     979         2584 :           gsi2 = gsi_start_bb (cond2_bb);
     980              :         }
     981              : 
     982         3148 :       tree mask = build_int_cst (pointer_sized_int_node,
     983         1574 :                                  tree_to_uhwi (align) - 1);
     984         1574 :       g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
     985              :                                BIT_AND_EXPR, check_align, mask);
     986         1574 :       gimple_set_location (g, loc);
     987         1574 :       if (check_null)
     988         1292 :         gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
     989              :       else
     990          282 :         gsi_insert_before (&gsi, g, GSI_SAME_STMT);
     991              : 
     992         1574 :       g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g),
     993              :                              build_int_cst (pointer_sized_int_node, 0),
     994              :                              NULL_TREE, NULL_TREE);
     995         1574 :       gimple_set_location (g, loc);
     996         1574 :       if (check_null)
     997         1292 :         gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
     998              :       else
     999              :         /* Replace the UBSAN_NULL with a GIMPLE_COND stmt.  */
    1000          282 :         gsi_replace (&gsi, g, false);
    1001              :     }
    1002              :   return false;
    1003              : }
    1004              : 
    1005              : #define OBJSZ_MAX_OFFSET (1024 * 16)
    1006              : 
    1007              : /* Expand UBSAN_OBJECT_SIZE internal call.  */
    1008              : 
    1009              : bool
    1010          368 : ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi)
    1011              : {
    1012          368 :   gimple *stmt = gsi_stmt (*gsi);
    1013          368 :   location_t loc = gimple_location (stmt);
    1014          368 :   gcc_assert (gimple_call_num_args (stmt) == 4);
    1015              : 
    1016          368 :   tree ptr = gimple_call_arg (stmt, 0);
    1017          368 :   tree offset = gimple_call_arg (stmt, 1);
    1018          368 :   tree size = gimple_call_arg (stmt, 2);
    1019          368 :   tree ckind = gimple_call_arg (stmt, 3);
    1020          368 :   gimple_stmt_iterator gsi_orig = *gsi;
    1021          368 :   gimple *g;
    1022              : 
    1023              :   /* See if we can discard the check.  */
    1024          368 :   if (TREE_CODE (size) == INTEGER_CST
    1025          368 :       && integer_all_onesp (size))
    1026              :     /* Yes, __builtin_object_size couldn't determine the
    1027              :        object size.  */;
    1028          368 :   else if (TREE_CODE (offset) == INTEGER_CST
    1029          113 :            && wi::to_widest (offset) >= -OBJSZ_MAX_OFFSET
    1030          481 :            && wi::to_widest (offset) <= -1)
    1031              :     /* The offset is in range [-16K, -1].  */;
    1032              :   else
    1033              :     {
    1034              :       /* if (offset > objsize) */
    1035          368 :       basic_block then_bb, fallthru_bb;
    1036          368 :       gimple_stmt_iterator cond_insert_point
    1037          368 :         = create_cond_insert_point (gsi, false, false, true,
    1038              :                                     &then_bb, &fallthru_bb);
    1039          368 :       g = gimple_build_cond (GT_EXPR, offset, size, NULL_TREE, NULL_TREE);
    1040          368 :       gimple_set_location (g, loc);
    1041          368 :       gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
    1042              : 
    1043              :       /* If the offset is small enough, we don't need the second
    1044              :          run-time check.  */
    1045          368 :       if (TREE_CODE (offset) == INTEGER_CST
    1046          113 :           && wi::to_widest (offset) >= 0
    1047          481 :           && wi::to_widest (offset) <= OBJSZ_MAX_OFFSET)
    1048          101 :         *gsi = gsi_after_labels (then_bb);
    1049              :       else
    1050              :         {
    1051              :           /* Don't issue run-time error if (ptr > ptr + offset).  That
    1052              :              may happen when computing a POINTER_PLUS_EXPR.  */
    1053          267 :           basic_block then2_bb, fallthru2_bb;
    1054              : 
    1055          267 :           gimple_stmt_iterator gsi2 = gsi_after_labels (then_bb);
    1056          267 :           cond_insert_point = create_cond_insert_point (&gsi2, false, false,
    1057              :                                                         true, &then2_bb,
    1058              :                                                         &fallthru2_bb);
    1059              :           /* Convert the pointer to an integer type.  */
    1060          267 :           tree p = make_ssa_name (pointer_sized_int_node);
    1061          267 :           g = gimple_build_assign (p, NOP_EXPR, ptr);
    1062          267 :           gimple_set_location (g, loc);
    1063          267 :           gsi_insert_before (&cond_insert_point, g, GSI_NEW_STMT);
    1064          267 :           p = gimple_assign_lhs (g);
    1065              :           /* Compute ptr + offset.  */
    1066          267 :           g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
    1067              :                                    PLUS_EXPR, p, offset);
    1068          267 :           gimple_set_location (g, loc);
    1069          267 :           gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
    1070              :           /* Now build the conditional and put it into the IR.  */
    1071          267 :           g = gimple_build_cond (LE_EXPR, p, gimple_assign_lhs (g),
    1072              :                                  NULL_TREE, NULL_TREE);
    1073          267 :           gimple_set_location (g, loc);
    1074          267 :           gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
    1075          267 :           *gsi = gsi_after_labels (then2_bb);
    1076              :         }
    1077              : 
    1078              :       /* Generate __ubsan_handle_type_mismatch call.  */
    1079          368 :       if (flag_sanitize_trap & SANITIZE_OBJECT_SIZE)
    1080            0 :         g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
    1081              :       else
    1082              :         {
    1083          368 :           tree data
    1084          736 :             = ubsan_create_data ("__ubsan_objsz_data", 1, &loc,
    1085          368 :                                  ubsan_type_descriptor (TREE_TYPE (ptr),
    1086              :                                                         UBSAN_PRINT_POINTER),
    1087              :                                  NULL_TREE,
    1088              :                                  build_zero_cst (unsigned_char_type_node),
    1089              :                                  ckind,
    1090              :                                  NULL_TREE);
    1091          368 :           data = build_fold_addr_expr_loc (loc, data);
    1092           66 :           enum built_in_function bcode
    1093          368 :             = (flag_sanitize_recover & SANITIZE_OBJECT_SIZE)
    1094          368 :               ? BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1
    1095              :               : BUILT_IN_UBSAN_HANDLE_TYPE_MISMATCH_V1_ABORT;
    1096          368 :           tree p = make_ssa_name (pointer_sized_int_node);
    1097          368 :           g = gimple_build_assign (p, NOP_EXPR, ptr);
    1098          368 :           gimple_set_location (g, loc);
    1099          368 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    1100          368 :           g = gimple_build_call (builtin_decl_explicit (bcode), 2, data, p);
    1101              :         }
    1102          368 :       gimple_set_location (g, loc);
    1103          368 :       gsi_insert_before (gsi, g, GSI_SAME_STMT);
    1104              : 
    1105              :       /* Point GSI to next logical statement.  */
    1106          368 :       *gsi = gsi_start_bb (fallthru_bb);
    1107              : 
    1108              :       /* Get rid of the UBSAN_OBJECT_SIZE call from the IR.  */
    1109          368 :       unlink_stmt_vdef (stmt);
    1110          368 :       gsi_remove (&gsi_orig, true);
    1111          368 :       return true;
    1112              :     }
    1113              : 
    1114              :   /* Get rid of the UBSAN_OBJECT_SIZE call from the IR.  */
    1115            0 :   unlink_stmt_vdef (stmt);
    1116            0 :   gsi_remove (gsi, true);
    1117            0 :   return true;
    1118              : }
    1119              : 
    1120              : /* Expand UBSAN_PTR internal call.  */
    1121              : 
    1122              : bool
    1123         1564 : ubsan_expand_ptr_ifn (gimple_stmt_iterator *gsip)
    1124              : {
    1125         1564 :   gimple_stmt_iterator gsi = *gsip;
    1126         1564 :   gimple *stmt = gsi_stmt (gsi);
    1127         1564 :   location_t loc = gimple_location (stmt);
    1128         1564 :   gcc_assert (gimple_call_num_args (stmt) == 2);
    1129         1564 :   tree ptr = gimple_call_arg (stmt, 0);
    1130         1564 :   tree off = gimple_call_arg (stmt, 1);
    1131              : 
    1132         1564 :   if (integer_zerop (off))
    1133              :     {
    1134            0 :       gsi_remove (gsip, true);
    1135            0 :       unlink_stmt_vdef (stmt);
    1136            0 :       return true;
    1137              :     }
    1138              : 
    1139         1564 :   basic_block cur_bb = gsi_bb (gsi);
    1140         1564 :   tree ptrplusoff = make_ssa_name (pointer_sized_int_node);
    1141         1564 :   tree ptri = make_ssa_name (pointer_sized_int_node);
    1142         1564 :   int pos_neg = get_range_pos_neg (off);
    1143              : 
    1144              :   /* Split the original block holding the pointer dereference.  */
    1145         1564 :   edge e = split_block (cur_bb, stmt);
    1146              : 
    1147              :   /* Get a hold on the 'condition block', the 'then block' and the
    1148              :      'else block'.  */
    1149         1564 :   basic_block cond_bb = e->src;
    1150         1564 :   basic_block fallthru_bb = e->dest;
    1151         1564 :   basic_block then_bb = create_empty_bb (cond_bb);
    1152         1564 :   basic_block cond_pos_bb = NULL, cond_neg_bb = NULL;
    1153         1564 :   add_bb_to_loop (then_bb, cond_bb->loop_father);
    1154         1564 :   loops_state_set (LOOPS_NEED_FIXUP);
    1155              : 
    1156              :   /* Set up the fallthrough basic block.  */
    1157         1564 :   e->flags = EDGE_FALSE_VALUE;
    1158         1564 :   if (pos_neg != 3)
    1159              :     {
    1160         1085 :       e->probability = profile_probability::very_likely ();
    1161              : 
    1162              :       /* Connect 'then block' with the 'else block'.  This is needed
    1163              :          as the ubsan routines we call in the 'then block' are not noreturn.
    1164              :          The 'then block' only has one outcoming edge.  */
    1165         1085 :       make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
    1166              : 
    1167              :       /* Make an edge coming from the 'cond block' into the 'then block';
    1168              :          this edge is unlikely taken, so set up the probability
    1169              :          accordingly.  */
    1170         1085 :       e = make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
    1171         1085 :       e->probability = profile_probability::very_unlikely ();
    1172         1085 :       then_bb->count = e->count ();
    1173              :     }
    1174              :   else
    1175              :     {
    1176          479 :       e->probability = profile_probability::even ();
    1177              : 
    1178          479 :       e = split_block (fallthru_bb, (gimple *) NULL);
    1179          479 :       cond_neg_bb = e->src;
    1180          479 :       fallthru_bb = e->dest;
    1181          479 :       e->probability = profile_probability::very_likely ();
    1182          479 :       e->flags = EDGE_FALSE_VALUE;
    1183              : 
    1184          479 :       e = make_edge (cond_neg_bb, then_bb, EDGE_TRUE_VALUE);
    1185          479 :       e->probability = profile_probability::very_unlikely ();
    1186          479 :       then_bb->count = e->count ();
    1187              : 
    1188          479 :       cond_pos_bb = create_empty_bb (cond_bb);
    1189          479 :       add_bb_to_loop (cond_pos_bb, cond_bb->loop_father);
    1190              : 
    1191          479 :       e = make_edge (cond_bb, cond_pos_bb, EDGE_TRUE_VALUE);
    1192          479 :       e->probability = profile_probability::even ();
    1193          479 :       cond_pos_bb->count = e->count ();
    1194              : 
    1195          479 :       e = make_edge (cond_pos_bb, then_bb, EDGE_TRUE_VALUE);
    1196          479 :       e->probability = profile_probability::very_unlikely ();
    1197              : 
    1198          479 :       e = make_edge (cond_pos_bb, fallthru_bb, EDGE_FALSE_VALUE);
    1199          479 :       e->probability = profile_probability::very_likely ();
    1200              : 
    1201          479 :       make_single_succ_edge (then_bb, fallthru_bb, EDGE_FALLTHRU);
    1202              :     }
    1203              : 
    1204         1564 :   gimple *g = gimple_build_assign (ptri, NOP_EXPR, ptr);
    1205         1564 :   gimple_set_location (g, loc);
    1206         1564 :   gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    1207         1564 :   g = gimple_build_assign (ptrplusoff, PLUS_EXPR, ptri, off);
    1208         1564 :   gimple_set_location (g, loc);
    1209         1564 :   gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    1210              : 
    1211              :   /* Update dominance info for the newly created then_bb; note that
    1212              :      fallthru_bb's dominance info has already been updated by
    1213              :      split_block.  */
    1214         1564 :   if (dom_info_available_p (CDI_DOMINATORS))
    1215              :     {
    1216         1564 :       set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
    1217         1564 :       if (pos_neg == 3)
    1218              :         {
    1219          479 :           set_immediate_dominator (CDI_DOMINATORS, cond_pos_bb, cond_bb);
    1220          479 :           set_immediate_dominator (CDI_DOMINATORS, fallthru_bb, cond_bb);
    1221              :         }
    1222              :     }
    1223              : 
    1224              :   /* Put the ubsan builtin call into the newly created BB.  */
    1225         1564 :   if (flag_sanitize_trap & SANITIZE_POINTER_OVERFLOW)
    1226            0 :     g = gimple_build_call (builtin_decl_implicit (BUILT_IN_TRAP), 0);
    1227              :   else
    1228              :     {
    1229          345 :       enum built_in_function bcode
    1230         1564 :         = (flag_sanitize_recover & SANITIZE_POINTER_OVERFLOW)
    1231         1564 :           ? BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW
    1232              :           : BUILT_IN_UBSAN_HANDLE_POINTER_OVERFLOW_ABORT;
    1233         1564 :       tree fn = builtin_decl_implicit (bcode);
    1234         1564 :       tree data
    1235         1564 :         = ubsan_create_data ("__ubsan_ptrovf_data", 1, &loc,
    1236              :                              NULL_TREE, NULL_TREE);
    1237         1564 :       data = build_fold_addr_expr_loc (loc, data);
    1238         1564 :       g = gimple_build_call (fn, 3, data, ptr, ptrplusoff);
    1239              :     }
    1240         1564 :   gimple_stmt_iterator gsi2 = gsi_start_bb (then_bb);
    1241         1564 :   gimple_set_location (g, loc);
    1242         1564 :   gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
    1243              : 
    1244              :   /* Unlink the UBSAN_PTRs vops before replacing it.  */
    1245         1564 :   unlink_stmt_vdef (stmt);
    1246              : 
    1247         1564 :   if (TREE_CODE (off) == INTEGER_CST)
    1248         1968 :     g = gimple_build_cond (wi::neg_p (wi::to_wide (off)) ? LT_EXPR : GE_EXPR,
    1249              :                            ptri, fold_build1 (NEGATE_EXPR, sizetype, off),
    1250              :                            NULL_TREE, NULL_TREE);
    1251          529 :   else if (pos_neg != 3)
    1252           50 :     g = gimple_build_cond (pos_neg == 1 ? LT_EXPR : GT_EXPR,
    1253              :                            ptrplusoff, ptri, NULL_TREE, NULL_TREE);
    1254              :   else
    1255              :     {
    1256          479 :       gsi2 = gsi_start_bb (cond_pos_bb);
    1257          479 :       g = gimple_build_cond (LT_EXPR, ptrplusoff, ptri, NULL_TREE, NULL_TREE);
    1258          479 :       gimple_set_location (g, loc);
    1259          479 :       gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
    1260              : 
    1261          479 :       gsi2 = gsi_start_bb (cond_neg_bb);
    1262          479 :       g = gimple_build_cond (GT_EXPR, ptrplusoff, ptri, NULL_TREE, NULL_TREE);
    1263          479 :       gimple_set_location (g, loc);
    1264          479 :       gsi_insert_after (&gsi2, g, GSI_NEW_STMT);
    1265              : 
    1266          479 :       tree t = gimple_build (&gsi, true, GSI_SAME_STMT,
    1267              :                              loc, NOP_EXPR, ssizetype, off);
    1268          479 :       g = gimple_build_cond (GE_EXPR, t, ssize_int (0),
    1269              :                              NULL_TREE, NULL_TREE);
    1270              :     }
    1271         1564 :   gimple_set_location (g, loc);
    1272              :   /* Replace the UBSAN_PTR with a GIMPLE_COND stmt.  */
    1273         1564 :   gsi_replace (&gsi, g, false);
    1274         1564 :   return false;
    1275              : }
    1276              : 
    1277              : 
    1278              : /* Cached __ubsan_vptr_type_cache decl.  */
    1279              : static GTY(()) tree ubsan_vptr_type_cache_decl;
    1280              : 
    1281              : /* Expand UBSAN_VPTR internal call.  The type is kept on the ckind
    1282              :    argument which is a constant, because the middle-end treats pointer
    1283              :    conversions as useless and therefore the type of the first argument
    1284              :    could be changed to any other pointer type.  */
    1285              : 
    1286              : bool
    1287          498 : ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip)
    1288              : {
    1289          498 :   gimple_stmt_iterator gsi = *gsip;
    1290          498 :   gimple *stmt = gsi_stmt (gsi);
    1291          498 :   location_t loc = gimple_location (stmt);
    1292          498 :   gcc_assert (gimple_call_num_args (stmt) == 5);
    1293          498 :   tree op = gimple_call_arg (stmt, 0);
    1294          498 :   tree vptr = gimple_call_arg (stmt, 1);
    1295          498 :   tree str_hash = gimple_call_arg (stmt, 2);
    1296          498 :   tree ti_decl_addr = gimple_call_arg (stmt, 3);
    1297          498 :   tree ckind_tree = gimple_call_arg (stmt, 4);
    1298          498 :   ubsan_null_ckind ckind = (ubsan_null_ckind) tree_to_uhwi (ckind_tree);
    1299          498 :   tree type = TREE_TYPE (TREE_TYPE (ckind_tree));
    1300          498 :   gimple *g;
    1301          498 :   basic_block fallthru_bb = NULL;
    1302              : 
    1303          498 :   if (ckind == UBSAN_DOWNCAST_POINTER)
    1304              :     {
    1305              :       /* Guard everything with if (op != NULL) { ... }.  */
    1306           36 :       basic_block then_bb;
    1307           36 :       gimple_stmt_iterator cond_insert_point
    1308           36 :         = create_cond_insert_point (gsip, false, false, true,
    1309              :                                     &then_bb, &fallthru_bb);
    1310           36 :       g = gimple_build_cond (NE_EXPR, op, build_zero_cst (TREE_TYPE (op)),
    1311              :                              NULL_TREE, NULL_TREE);
    1312           36 :       gimple_set_location (g, loc);
    1313           36 :       gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
    1314           36 :       *gsip = gsi_after_labels (then_bb);
    1315           36 :       gsi_remove (&gsi, false);
    1316           36 :       gsi_insert_before (gsip, stmt, GSI_NEW_STMT);
    1317           36 :       gsi = *gsip;
    1318              :     }
    1319              : 
    1320          498 :   tree htype = TREE_TYPE (str_hash);
    1321          498 :   tree cst = wide_int_to_tree (htype,
    1322          498 :                                wi::uhwi (((uint64_t) 0x9ddfea08 << 32)
    1323              :                                | 0xeb382d69, 64));
    1324          498 :   g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
    1325              :                            vptr, str_hash);
    1326          498 :   gimple_set_location (g, loc);
    1327          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1328          498 :   g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
    1329              :                            gimple_assign_lhs (g), cst);
    1330          498 :   gimple_set_location (g, loc);
    1331          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1332          498 :   tree t1 = gimple_assign_lhs (g);
    1333          498 :   g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
    1334              :                            t1, build_int_cst (integer_type_node, 47));
    1335          498 :   gimple_set_location (g, loc);
    1336          498 :   tree t2 = gimple_assign_lhs (g);
    1337          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1338          498 :   g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
    1339              :                            vptr, t1);
    1340          498 :   gimple_set_location (g, loc);
    1341          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1342          498 :   g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
    1343              :                            t2, gimple_assign_lhs (g));
    1344          498 :   gimple_set_location (g, loc);
    1345          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1346          498 :   g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
    1347              :                            gimple_assign_lhs (g), cst);
    1348          498 :   gimple_set_location (g, loc);
    1349          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1350          498 :   tree t3 = gimple_assign_lhs (g);
    1351          498 :   g = gimple_build_assign (make_ssa_name (htype), LSHIFT_EXPR,
    1352              :                            t3, build_int_cst (integer_type_node, 47));
    1353          498 :   gimple_set_location (g, loc);
    1354          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1355          498 :   g = gimple_build_assign (make_ssa_name (htype), BIT_XOR_EXPR,
    1356              :                            t3, gimple_assign_lhs (g));
    1357          498 :   gimple_set_location (g, loc);
    1358          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1359          498 :   g = gimple_build_assign (make_ssa_name (htype), MULT_EXPR,
    1360              :                            gimple_assign_lhs (g), cst);
    1361          498 :   gimple_set_location (g, loc);
    1362          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1363          498 :   if (!useless_type_conversion_p (pointer_sized_int_node, htype))
    1364              :     {
    1365            0 :       g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
    1366              :                                NOP_EXPR, gimple_assign_lhs (g));
    1367            0 :       gimple_set_location (g, loc);
    1368            0 :       gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1369              :     }
    1370          498 :   tree hash = gimple_assign_lhs (g);
    1371              : 
    1372          498 :   if (ubsan_vptr_type_cache_decl == NULL_TREE)
    1373              :     {
    1374          100 :       tree atype = build_array_type_nelts (pointer_sized_int_node, 128);
    1375          100 :       tree array = build_decl (UNKNOWN_LOCATION, VAR_DECL,
    1376              :                                get_identifier ("__ubsan_vptr_type_cache"),
    1377              :                                atype);
    1378          100 :       DECL_ARTIFICIAL (array) = 1;
    1379          100 :       DECL_IGNORED_P (array) = 1;
    1380          100 :       TREE_PUBLIC (array) = 1;
    1381          100 :       TREE_STATIC (array) = 1;
    1382          100 :       DECL_EXTERNAL (array) = 1;
    1383          100 :       DECL_VISIBILITY (array) = VISIBILITY_DEFAULT;
    1384          100 :       DECL_VISIBILITY_SPECIFIED (array) = 1;
    1385          100 :       varpool_node::finalize_decl (array);
    1386          100 :       ubsan_vptr_type_cache_decl = array;
    1387              :    }
    1388              : 
    1389          498 :   g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
    1390              :                            BIT_AND_EXPR, hash,
    1391              :                            build_int_cst (pointer_sized_int_node, 127));
    1392          498 :   gimple_set_location (g, loc);
    1393          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1394              : 
    1395          498 :   tree c = build4_loc (loc, ARRAY_REF, pointer_sized_int_node,
    1396              :                        ubsan_vptr_type_cache_decl, gimple_assign_lhs (g),
    1397              :                        NULL_TREE, NULL_TREE);
    1398          498 :   g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
    1399              :                            ARRAY_REF, c);
    1400          498 :   gimple_set_location (g, loc);
    1401          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1402              : 
    1403          498 :   basic_block then_bb, fallthru2_bb;
    1404          498 :   gimple_stmt_iterator cond_insert_point
    1405          498 :     = create_cond_insert_point (gsip, false, false, true,
    1406              :                                 &then_bb, &fallthru2_bb);
    1407          498 :   g = gimple_build_cond (NE_EXPR, gimple_assign_lhs (g), hash,
    1408              :                          NULL_TREE, NULL_TREE);
    1409          498 :   gimple_set_location (g, loc);
    1410          498 :   gsi_insert_after (&cond_insert_point, g, GSI_NEW_STMT);
    1411          498 :   *gsip = gsi_after_labels (then_bb);
    1412          498 :   if (fallthru_bb == NULL)
    1413          462 :     fallthru_bb = fallthru2_bb;
    1414              : 
    1415          498 :   tree data
    1416          498 :     = ubsan_create_data ("__ubsan_vptr_data", 1, &loc,
    1417              :                          ubsan_type_descriptor (type), NULL_TREE, ti_decl_addr,
    1418          498 :                          build_int_cst (unsigned_char_type_node, ckind),
    1419              :                          NULL_TREE);
    1420          498 :   data = build_fold_addr_expr_loc (loc, data);
    1421          134 :   enum built_in_function bcode
    1422          498 :     = (flag_sanitize_recover & SANITIZE_VPTR)
    1423          498 :       ? BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS
    1424              :       : BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT;
    1425              : 
    1426          498 :   g = gimple_build_call (builtin_decl_explicit (bcode), 3, data, op, hash);
    1427          498 :   gimple_set_location (g, loc);
    1428          498 :   gsi_insert_before (gsip, g, GSI_SAME_STMT);
    1429              : 
    1430              :   /* Point GSI to next logical statement.  */
    1431          498 :   *gsip = gsi_start_bb (fallthru_bb);
    1432              : 
    1433              :   /* Get rid of the UBSAN_VPTR call from the IR.  */
    1434          498 :   unlink_stmt_vdef (stmt);
    1435          498 :   gsi_remove (&gsi, true);
    1436          498 :   return true;
    1437              : }
    1438              : 
    1439              : /* Instrument a memory reference.  BASE is the base of MEM, IS_LHS says
    1440              :    whether the pointer is on the left hand side of the assignment.  */
    1441              : 
    1442              : static void
    1443         3700 : instrument_mem_ref (tree mem, tree base, gimple_stmt_iterator *iter,
    1444              :                     bool is_lhs)
    1445              : {
    1446         3700 :   enum ubsan_null_ckind ikind = is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF;
    1447         3700 :   unsigned int align = 0;
    1448         3700 :   if (sanitize_flags_p (SANITIZE_ALIGNMENT))
    1449              :     {
    1450         3408 :       align = min_align_of_type (TREE_TYPE (base));
    1451         3408 :       if (align <= 1)
    1452              :         align = 0;
    1453              :     }
    1454              :   if (align == 0)
    1455              :     {
    1456          753 :       if (!sanitize_flags_p (SANITIZE_NULL))
    1457         3700 :         return;
    1458          742 :       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (base));
    1459          742 :       if (!ADDR_SPACE_GENERIC_P (as)
    1460          742 :           && targetm.addr_space.zero_address_valid (as))
    1461              :         return;
    1462              :     }
    1463         3682 :   tree t = TREE_OPERAND (base, 0);
    1464         3682 :   if (!POINTER_TYPE_P (TREE_TYPE (t)))
    1465              :     return;
    1466         3682 :   if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (base)) && mem != base)
    1467              :     ikind = UBSAN_MEMBER_ACCESS;
    1468         3682 :   tree kind = build_int_cst (build_pointer_type (TREE_TYPE (base)), ikind);
    1469         3682 :   tree alignt = build_int_cst (pointer_sized_int_node, align);
    1470         3682 :   gcall *g = gimple_build_call_internal (IFN_UBSAN_NULL, 3, t, kind, alignt);
    1471         3682 :   gimple_set_location (g, gimple_location (gsi_stmt (*iter)));
    1472         3682 :   gsi_safe_insert_before (iter, g);
    1473              : }
    1474              : 
    1475              : /* Perform the pointer instrumentation.  */
    1476              : 
    1477              : static void
    1478        20065 : instrument_null (gimple_stmt_iterator gsi, tree t, bool is_lhs)
    1479              : {
    1480              :   /* Handle also e.g. &s->i.  */
    1481        20065 :   if (TREE_CODE (t) == ADDR_EXPR)
    1482          831 :     t = TREE_OPERAND (t, 0);
    1483        20065 :   tree base = get_base_address (t);
    1484        20065 :   if (base != NULL_TREE
    1485        20065 :       && TREE_CODE (base) == MEM_REF
    1486        23765 :       && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
    1487         3700 :     instrument_mem_ref (t, base, &gsi, is_lhs);
    1488        20065 : }
    1489              : 
    1490              : /* Instrument pointer arithmetics PTR p+ OFF.  */
    1491              : 
    1492              : static void
    1493         2779 : instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree ptr, tree off)
    1494              : {
    1495         2779 :   if (TYPE_PRECISION (sizetype) != POINTER_SIZE)
    1496              :     return;
    1497         2779 :   gcall *g = gimple_build_call_internal (IFN_UBSAN_PTR, 2, ptr, off);
    1498         2779 :   gimple_set_location (g, gimple_location (gsi_stmt (*gsi)));
    1499         2779 :   gsi_safe_insert_before (gsi, g);
    1500              : }
    1501              : 
    1502              : /* Instrument pointer arithmetics if any.  */
    1503              : 
    1504              : static void
    1505        26815 : maybe_instrument_pointer_overflow (gimple_stmt_iterator *gsi, tree t)
    1506              : {
    1507        26815 :   if (TYPE_PRECISION (sizetype) != POINTER_SIZE)
    1508        24841 :     return;
    1509              : 
    1510              :   /* Handle also e.g. &s->i.  */
    1511        26815 :   if (TREE_CODE (t) == ADDR_EXPR)
    1512         3106 :     t = TREE_OPERAND (t, 0);
    1513              : 
    1514        26815 :   if (!handled_component_p (t) && TREE_CODE (t) != MEM_REF)
    1515              :     return;
    1516              : 
    1517         6324 :   poly_int64 bitsize, bitpos, bytepos;
    1518         6324 :   tree offset;
    1519         6324 :   machine_mode mode;
    1520         6324 :   int volatilep = 0, reversep, unsignedp = 0;
    1521         6324 :   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
    1522              :                                     &unsignedp, &reversep, &volatilep);
    1523         6324 :   tree moff = NULL_TREE;
    1524              : 
    1525         6324 :   bool decl_p = DECL_P (inner);
    1526         6324 :   tree base;
    1527         6324 :   if (decl_p)
    1528              :     {
    1529         2757 :       if ((VAR_P (inner)
    1530              :            || TREE_CODE (inner) == PARM_DECL
    1531              :            || TREE_CODE (inner) == RESULT_DECL)
    1532         2757 :           && DECL_REGISTER (inner))
    1533         1797 :         return;
    1534         2757 :       base = inner;
    1535              :       /* If BASE is a fixed size automatic variable or
    1536              :          global variable defined in the current TU and bitpos
    1537              :          fits, don't instrument anything.  */
    1538         2757 :       poly_int64 base_size;
    1539         2757 :       if (offset == NULL_TREE
    1540         2434 :           && maybe_ne (bitpos, 0)
    1541              :           && (VAR_P (base)
    1542              :               || TREE_CODE (base) == PARM_DECL
    1543              :               || TREE_CODE (base) == RESULT_DECL)
    1544         1815 :           && poly_int_tree_p (DECL_SIZE (base), &base_size)
    1545         1815 :           && known_ge (base_size, bitpos)
    1546         4572 :           && (!is_global_var (base) || decl_binds_to_current_def_p (base)))
    1547         1797 :         return;
    1548              :     }
    1549         3567 :   else if (TREE_CODE (inner) == MEM_REF)
    1550              :     {
    1551         3163 :       base = TREE_OPERAND (inner, 0);
    1552         3163 :       if (TREE_CODE (base) == ADDR_EXPR
    1553            0 :           && DECL_P (TREE_OPERAND (base, 0))
    1554            0 :           && !TREE_ADDRESSABLE (TREE_OPERAND (base, 0))
    1555         3163 :           && !is_global_var (TREE_OPERAND (base, 0)))
    1556              :         return;
    1557         3163 :       moff = TREE_OPERAND (inner, 1);
    1558         3163 :       if (integer_zerop (moff))
    1559         3155 :         moff = NULL_TREE;
    1560              :     }
    1561              :   else
    1562              :     return;
    1563              : 
    1564         4123 :   if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
    1565              :     return;
    1566         4123 :   bytepos = bits_to_bytes_round_down (bitpos);
    1567         4123 :   if (offset == NULL_TREE && known_eq (bytepos, 0) && moff == NULL_TREE)
    1568              :     return;
    1569              : 
    1570         1974 :   tree base_addr = base;
    1571         1974 :   if (decl_p)
    1572          341 :     base_addr = build1 (ADDR_EXPR,
    1573          341 :                         build_pointer_type (TREE_TYPE (base)), base);
    1574         1974 :   t = offset;
    1575         1974 :   if (maybe_ne (bytepos, 0))
    1576              :     {
    1577         1822 :       if (t)
    1578          621 :         t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
    1579              :                          build_int_cst (TREE_TYPE (t), bytepos));
    1580              :       else
    1581         1201 :         t = size_int (bytepos);
    1582              :     }
    1583         1974 :   if (moff)
    1584              :     {
    1585            8 :       if (t)
    1586            0 :         t = fold_build2 (PLUS_EXPR, TREE_TYPE (t), t,
    1587              :                          fold_convert (TREE_TYPE (t), moff));
    1588              :       else
    1589            8 :         t = fold_convert (sizetype, moff);
    1590              :     }
    1591         1974 :   gimple_seq seq, this_seq;
    1592         1974 :   t = force_gimple_operand (t, &seq, true, NULL_TREE);
    1593         1974 :   base_addr = force_gimple_operand (base_addr, &this_seq, true, NULL_TREE);
    1594         1974 :   gimple_seq_add_seq_without_update (&seq, this_seq);
    1595         1974 :   gsi_safe_insert_seq_before (gsi, seq);
    1596         1974 :   instrument_pointer_overflow (gsi, base_addr, t);
    1597              : }
    1598              : 
    1599              : /* Build an ubsan builtin call for the signed-integer-overflow
    1600              :    sanitization.  CODE says what kind of builtin are we building,
    1601              :    LOC is a location, LHSTYPE is the type of LHS, OP0 and OP1
    1602              :    are operands of the binary operation.  */
    1603              : 
    1604              : tree
    1605         5492 : ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype,
    1606              :                               tree op0, tree op1, tree *datap)
    1607              : {
    1608         5492 :   if (flag_sanitize_trap & SANITIZE_SI_OVERFLOW)
    1609          322 :     return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
    1610              : 
    1611         5170 :   tree data;
    1612         5170 :   if (datap && *datap)
    1613              :     data = *datap;
    1614              :   else
    1615         4774 :     data = ubsan_create_data ("__ubsan_overflow_data", 1, &loc,
    1616              :                               ubsan_type_descriptor (lhstype), NULL_TREE,
    1617              :                               NULL_TREE);
    1618         4774 :   if (datap)
    1619          945 :     *datap = data;
    1620         5170 :   enum built_in_function fn_code;
    1621              : 
    1622         5170 :   switch (code)
    1623              :     {
    1624         1871 :     case PLUS_EXPR:
    1625          596 :       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
    1626         1871 :                 ? BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW
    1627              :                 : BUILT_IN_UBSAN_HANDLE_ADD_OVERFLOW_ABORT;
    1628              :       break;
    1629         1416 :     case MINUS_EXPR:
    1630          438 :       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
    1631         1416 :                 ? BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW
    1632              :                 : BUILT_IN_UBSAN_HANDLE_SUB_OVERFLOW_ABORT;
    1633              :       break;
    1634         1322 :     case MULT_EXPR:
    1635          282 :       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
    1636         1322 :                 ? BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW
    1637              :                 : BUILT_IN_UBSAN_HANDLE_MUL_OVERFLOW_ABORT;
    1638              :       break;
    1639          561 :     case NEGATE_EXPR:
    1640          165 :       fn_code = (flag_sanitize_recover & SANITIZE_SI_OVERFLOW)
    1641          561 :                 ? BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW
    1642              :                 : BUILT_IN_UBSAN_HANDLE_NEGATE_OVERFLOW_ABORT;
    1643              :       break;
    1644            0 :     default:
    1645            0 :       gcc_unreachable ();
    1646              :     }
    1647         5170 :   tree fn = builtin_decl_explicit (fn_code);
    1648        10340 :   return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR),
    1649              :                               build_fold_addr_expr_loc (loc, data),
    1650              :                               ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL),
    1651              :                               op1
    1652         4609 :                               ? ubsan_encode_value (op1,
    1653              :                                                     UBSAN_ENCODE_VALUE_RTL)
    1654         5170 :                               : NULL_TREE);
    1655              : }
    1656              : 
    1657              : /* Perform the signed integer instrumentation.  GSI is the iterator
    1658              :    pointing at statement we are trying to instrument.  */
    1659              : 
    1660              : static void
    1661        53722 : instrument_si_overflow (gimple_stmt_iterator gsi)
    1662              : {
    1663        53722 :   gimple *stmt = gsi_stmt (gsi);
    1664        53722 :   tree_code code = gimple_assign_rhs_code (stmt);
    1665        53722 :   tree lhs = gimple_assign_lhs (stmt);
    1666        53722 :   tree lhstype = TREE_TYPE (lhs);
    1667        53722 :   tree lhsinner = VECTOR_TYPE_P (lhstype) ? TREE_TYPE (lhstype) : lhstype;
    1668        53722 :   tree a, b;
    1669        53722 :   gimple *g;
    1670              : 
    1671              :   /* If this is not a signed operation, don't instrument anything here.
    1672              :      Also punt on bit-fields.  */
    1673        53722 :   if (!INTEGRAL_TYPE_P (lhsinner)
    1674        49276 :       || TYPE_OVERFLOW_WRAPS (lhsinner)
    1675        85958 :       || (!BITINT_TYPE_P (lhsinner)
    1676        63224 :           && maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (lhsinner)),
    1677        31612 :                        TYPE_PRECISION (lhsinner))))
    1678        21562 :     return;
    1679              : 
    1680        32160 :   switch (code)
    1681              :     {
    1682         6029 :     case MINUS_EXPR:
    1683         6029 :     case PLUS_EXPR:
    1684         6029 :     case MULT_EXPR:
    1685              :       /* Transform
    1686              :          i = u {+,-,*} 5;
    1687              :          into
    1688              :          i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5);  */
    1689         6029 :       a = gimple_assign_rhs1 (stmt);
    1690         6029 :       b = gimple_assign_rhs2 (stmt);
    1691         9677 :       g = gimple_build_call_internal (code == PLUS_EXPR
    1692              :                                       ? IFN_UBSAN_CHECK_ADD
    1693              :                                       : code == MINUS_EXPR
    1694         3648 :                                       ? IFN_UBSAN_CHECK_SUB
    1695              :                                       : IFN_UBSAN_CHECK_MUL, 2, a, b);
    1696         6029 :       gimple_call_set_lhs (g, lhs);
    1697         6029 :       gsi_replace (&gsi, g, true);
    1698         6029 :       break;
    1699          524 :     case NEGATE_EXPR:
    1700              :       /* Represent i = -u;
    1701              :          as
    1702              :          i = UBSAN_CHECK_SUB (0, u);  */
    1703          524 :       a = build_zero_cst (lhstype);
    1704          524 :       b = gimple_assign_rhs1 (stmt);
    1705          524 :       g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
    1706          524 :       gimple_call_set_lhs (g, lhs);
    1707          524 :       gsi_replace (&gsi, g, true);
    1708          524 :       break;
    1709           10 :     case ABS_EXPR:
    1710              :       /* Transform i = ABS_EXPR<u>;
    1711              :          into
    1712              :          _N = UBSAN_CHECK_SUB (0, u);
    1713              :          i = ABS_EXPR<_N>;  */
    1714           10 :       a = build_zero_cst (lhstype);
    1715           10 :       b = gimple_assign_rhs1 (stmt);
    1716           10 :       g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
    1717           10 :       a = make_ssa_name (lhstype);
    1718           10 :       gimple_call_set_lhs (g, a);
    1719           10 :       gimple_set_location (g, gimple_location (stmt));
    1720           10 :       gsi_insert_before (&gsi, g, GSI_SAME_STMT);
    1721           10 :       gimple_assign_set_rhs1 (stmt, a);
    1722           10 :       update_stmt (stmt);
    1723           10 :       break;
    1724              :     default:
    1725              :       break;
    1726              :     }
    1727              : }
    1728              : 
    1729              : /* Instrument loads from (non-bitfield) bool and C++ enum values
    1730              :    to check if the memory value is outside of the range of the valid
    1731              :    type values.  */
    1732              : 
    1733              : static void
    1734         4619 : instrument_bool_enum_load (gimple_stmt_iterator *gsi)
    1735              : {
    1736         4619 :   gimple *stmt = gsi_stmt (*gsi);
    1737         4619 :   tree rhs = gimple_assign_rhs1 (stmt);
    1738         4619 :   tree type = TREE_TYPE (rhs);
    1739         4619 :   tree minv = NULL_TREE, maxv = NULL_TREE;
    1740              : 
    1741         4619 :   if (TREE_CODE (type) == BOOLEAN_TYPE
    1742         4619 :       && sanitize_flags_p (SANITIZE_BOOL))
    1743              :     {
    1744           69 :       minv = boolean_false_node;
    1745           69 :       maxv = boolean_true_node;
    1746              :     }
    1747         4550 :   else if (TREE_CODE (type) == ENUMERAL_TYPE
    1748           40 :            && sanitize_flags_p (SANITIZE_ENUM)
    1749           40 :            && TREE_TYPE (type) != NULL_TREE
    1750           40 :            && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
    1751         4630 :            && (TYPE_PRECISION (TREE_TYPE (type))
    1752           40 :                < GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (type))))
    1753              :     {
    1754           12 :       minv = TYPE_MIN_VALUE (TREE_TYPE (type));
    1755           12 :       maxv = TYPE_MAX_VALUE (TREE_TYPE (type));
    1756              :     }
    1757              :   else
    1758         4538 :     return;
    1759              : 
    1760           81 :   int modebitsize = GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type));
    1761           81 :   poly_int64 bitsize, bitpos;
    1762           81 :   tree offset;
    1763           81 :   machine_mode mode;
    1764           81 :   int volatilep = 0, reversep, unsignedp = 0;
    1765           81 :   tree base = get_inner_reference (rhs, &bitsize, &bitpos, &offset, &mode,
    1766              :                                    &unsignedp, &reversep, &volatilep);
    1767           81 :   tree utype = build_nonstandard_integer_type (modebitsize, 1);
    1768              : 
    1769           58 :   if ((VAR_P (base) && DECL_HARD_REGISTER (base))
    1770          162 :       || !multiple_p (bitpos, modebitsize)
    1771           81 :       || maybe_ne (bitsize, modebitsize)
    1772          162 :       || GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (utype)) != modebitsize
    1773          162 :       || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
    1774            0 :     return;
    1775              : 
    1776           81 :   addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (rhs));
    1777           81 :   if (as != TYPE_ADDR_SPACE (utype))
    1778            7 :     utype = build_qualified_type (utype, TYPE_QUALS (utype)
    1779            7 :                                          | ENCODE_QUAL_ADDR_SPACE (as));
    1780           81 :   bool ends_bb = stmt_ends_bb_p (stmt);
    1781           81 :   location_t loc = gimple_location (stmt);
    1782           81 :   tree lhs = gimple_assign_lhs (stmt);
    1783           81 :   tree ptype = build_pointer_type (TREE_TYPE (rhs));
    1784           81 :   tree atype = reference_alias_ptr_type (rhs);
    1785           81 :   gimple *g = gimple_build_assign (make_ssa_name (ptype),
    1786              :                                    build_fold_addr_expr (rhs));
    1787           81 :   gimple_set_location (g, loc);
    1788           81 :   gsi_insert_before (gsi, g, GSI_SAME_STMT);
    1789           81 :   tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
    1790              :                      build_int_cst (atype, 0));
    1791           81 :   tree urhs = make_ssa_name (utype);
    1792           81 :   if (ends_bb)
    1793              :     {
    1794            3 :       gimple_assign_set_lhs (stmt, urhs);
    1795            3 :       g = gimple_build_assign (lhs, NOP_EXPR, urhs);
    1796            3 :       gimple_set_location (g, loc);
    1797            3 :       edge e = find_fallthru_edge (gimple_bb (stmt)->succs);
    1798            3 :       gsi_insert_on_edge_immediate (e, g);
    1799            3 :       gimple_assign_set_rhs_from_tree (gsi, mem);
    1800            3 :       update_stmt (stmt);
    1801            3 :       *gsi = gsi_for_stmt (g);
    1802            3 :       g = stmt;
    1803              :     }
    1804              :   else
    1805              :     {
    1806           78 :       g = gimple_build_assign (urhs, mem);
    1807           78 :       gimple_set_location (g, loc);
    1808           78 :       gsi_insert_before (gsi, g, GSI_SAME_STMT);
    1809              :     }
    1810           81 :   minv = fold_convert (utype, minv);
    1811           81 :   maxv = fold_convert (utype, maxv);
    1812           81 :   if (!integer_zerop (minv))
    1813              :     {
    1814            3 :       g = gimple_build_assign (make_ssa_name (utype), MINUS_EXPR, urhs, minv);
    1815            3 :       gimple_set_location (g, loc);
    1816            3 :       gsi_insert_before (gsi, g, GSI_SAME_STMT);
    1817              :     }
    1818              : 
    1819           81 :   gimple_stmt_iterator gsi2 = *gsi;
    1820           81 :   basic_block then_bb, fallthru_bb;
    1821           81 :   *gsi = create_cond_insert_point (gsi, true, false, true,
    1822              :                                    &then_bb, &fallthru_bb);
    1823           81 :   g = gimple_build_cond (GT_EXPR, gimple_assign_lhs (g),
    1824              :                          int_const_binop (MINUS_EXPR, maxv, minv),
    1825              :                          NULL_TREE, NULL_TREE);
    1826           81 :   gimple_set_location (g, loc);
    1827           81 :   gsi_insert_after (gsi, g, GSI_NEW_STMT);
    1828              : 
    1829           81 :   if (!ends_bb)
    1830              :     {
    1831           78 :       gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs);
    1832           78 :       update_stmt (stmt);
    1833              :     }
    1834              : 
    1835           81 :   gsi2 = gsi_after_labels (then_bb);
    1836           81 :   if (flag_sanitize_trap & (TREE_CODE (type) == BOOLEAN_TYPE
    1837           81 :                             ? SANITIZE_BOOL : SANITIZE_ENUM))
    1838            3 :     g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
    1839              :   else
    1840              :     {
    1841           78 :       tree data = ubsan_create_data ("__ubsan_invalid_value_data", 1, &loc,
    1842              :                                      ubsan_type_descriptor (type), NULL_TREE,
    1843              :                                      NULL_TREE);
    1844           78 :       data = build_fold_addr_expr_loc (loc, data);
    1845           16 :       enum built_in_function bcode
    1846          156 :         = (flag_sanitize_recover & (TREE_CODE (type) == BOOLEAN_TYPE
    1847           78 :                                     ? SANITIZE_BOOL : SANITIZE_ENUM))
    1848           78 :           ? BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE
    1849              :           : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT;
    1850           78 :       tree fn = builtin_decl_explicit (bcode);
    1851              : 
    1852           78 :       tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE);
    1853           78 :       val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true,
    1854              :                                       GSI_SAME_STMT);
    1855           78 :       g = gimple_build_call (fn, 2, data, val);
    1856              :     }
    1857           81 :   gimple_set_location (g, loc);
    1858           81 :   gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
    1859           81 :   ubsan_create_edge (g);
    1860           81 :   *gsi = gsi_for_stmt (stmt);
    1861              : }
    1862              : 
    1863              : /* Determine if we can propagate given LOCATION to ubsan_data descriptor to use
    1864              :    new style handlers.  Libubsan uses heuristics to destinguish between old and
    1865              :    new styles and relies on these properties for filename:
    1866              : 
    1867              :    a) Location's filename must not be NULL.
    1868              :    b) Location's filename must not be equal to "".
    1869              :    c) Location's filename must not be equal to "\1".
    1870              :    d) First two bytes of filename must not contain '\xff' symbol.  */
    1871              : 
    1872              : static bool
    1873        12097 : ubsan_use_new_style_p (location_t loc)
    1874              : {
    1875        12097 :   if (loc == UNKNOWN_LOCATION)
    1876              :     return false;
    1877              : 
    1878        12097 :   expanded_location xloc = expand_location (loc);
    1879        12097 :   if (xloc.file == NULL || startswith (xloc.file, "\1")
    1880        12097 :       || xloc.file[0] == '\0' || xloc.file[0] == '\xff'
    1881        24194 :       || xloc.file[1] == '\xff')
    1882              :     return false;
    1883              : 
    1884              :   return true;
    1885              : }
    1886              : 
    1887              : /* Instrument float point-to-integer conversion.  TYPE is an integer type of
    1888              :    destination, EXPR is floating-point expression.  */
    1889              : 
    1890              : tree
    1891        16702 : ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
    1892              : {
    1893        16702 :   tree expr_type = TREE_TYPE (expr);
    1894        16702 :   tree t, tt, fn, min, max;
    1895        16702 :   machine_mode mode = TYPE_MODE (expr_type);
    1896        16702 :   int prec = TYPE_PRECISION (type);
    1897        16702 :   bool uns_p = TYPE_UNSIGNED (type);
    1898        16702 :   if (loc == UNKNOWN_LOCATION)
    1899         5222 :     loc = input_location;
    1900              : 
    1901              :   /* Float to integer conversion first truncates toward zero, so
    1902              :      even signed char c = 127.875f; is not problematic.
    1903              :      Therefore, we should complain only if EXPR is unordered or smaller
    1904              :      or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
    1905              :      TYPE_MAX_VALUE + 1.0.  */
    1906        16702 :   if (REAL_MODE_FORMAT (mode)->b == 2)
    1907              :     {
    1908              :       /* For maximum, TYPE_MAX_VALUE might not be representable
    1909              :          in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
    1910              :          EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
    1911              :          either representable or infinity.  */
    1912        16504 :       REAL_VALUE_TYPE maxval = dconst1;
    1913        16504 :       SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
    1914        16504 :       real_convert (&maxval, mode, &maxval);
    1915        16504 :       max = build_real (expr_type, maxval);
    1916              : 
    1917              :       /* For unsigned, assume -1.0 is always representable.  */
    1918        16504 :       if (uns_p)
    1919         7050 :         min = build_minus_one_cst (expr_type);
    1920              :       else
    1921              :         {
    1922              :           /* TYPE_MIN_VALUE is generally representable (or -inf),
    1923              :              but TYPE_MIN_VALUE - 1.0 might not be.  */
    1924         9454 :           REAL_VALUE_TYPE minval = dconstm1, minval2;
    1925         9454 :           SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
    1926         9454 :           real_convert (&minval, mode, &minval);
    1927         9454 :           real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
    1928         9454 :           real_convert (&minval2, mode, &minval2);
    1929         9454 :           if (real_compare (EQ_EXPR, &minval, &minval2)
    1930         9454 :               && !real_isinf (&minval))
    1931              :             {
    1932              :               /* If TYPE_MIN_VALUE - 1.0 is not representable and
    1933              :                  rounds to TYPE_MIN_VALUE, we need to subtract
    1934              :                  more.  As REAL_MODE_FORMAT (mode)->p is the number
    1935              :                  of base digits, we want to subtract a number that
    1936              :                  will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
    1937              :                  times smaller than minval.  */
    1938         2553 :               minval2 = dconst1;
    1939         2553 :               gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
    1940         2553 :               SET_REAL_EXP (&minval2,
    1941              :                             REAL_EXP (&minval2) + prec - 1
    1942              :                             - REAL_MODE_FORMAT (mode)->p + 1);
    1943         2553 :               real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
    1944         2553 :               real_convert (&minval2, mode, &minval2);
    1945              :             }
    1946         9454 :           min = build_real (expr_type, minval2);
    1947              :         }
    1948              :     }
    1949          198 :   else if (REAL_MODE_FORMAT (mode)->b == 10)
    1950              :     {
    1951              :       /* For _Decimal128 up to 34 decimal digits, - sign,
    1952              :          dot, e, exponent.  */
    1953          198 :       char buf[64];
    1954          198 :       int p = REAL_MODE_FORMAT (mode)->p;
    1955          198 :       REAL_VALUE_TYPE maxval, minval;
    1956              : 
    1957              :       /* Use mpfr_snprintf rounding to compute the smallest
    1958              :          representable decimal number greater or equal than
    1959              :          1 << (prec - !uns_p).  */
    1960          198 :       auto_mpfr m (prec + 2);
    1961          198 :       mpfr_set_ui_2exp (m, 1, prec - !uns_p, MPFR_RNDN);
    1962          198 :       mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, (mpfr_srcptr) m);
    1963          198 :       decimal_real_from_string (&maxval, buf);
    1964          198 :       max = build_real (expr_type, maxval);
    1965              : 
    1966              :       /* For unsigned, assume -1.0 is always representable.  */
    1967          198 :       if (uns_p)
    1968           90 :         min = build_minus_one_cst (expr_type);
    1969              :       else
    1970              :         {
    1971              :           /* Use mpfr_snprintf rounding to compute the largest
    1972              :              representable decimal number less or equal than
    1973              :              (-1 << (prec - 1)) - 1.  */
    1974          108 :           mpfr_set_si_2exp (m, -1, prec - 1, MPFR_RNDN);
    1975          108 :           mpfr_sub_ui (m, m, 1, MPFR_RNDN);
    1976          108 :           mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, (mpfr_srcptr) m);
    1977          108 :           decimal_real_from_string (&minval, buf);
    1978          108 :           min = build_real (expr_type, minval);
    1979              :         }
    1980          198 :     }
    1981              :   else
    1982              :     return NULL_TREE;
    1983              : 
    1984        16702 :   if (HONOR_NANS (mode))
    1985              :     {
    1986        16688 :       t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
    1987        16688 :       tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
    1988              :     }
    1989              :   else
    1990              :     {
    1991           14 :       t = fold_build2 (LE_EXPR, boolean_type_node, expr, min);
    1992           14 :       tt = fold_build2 (GE_EXPR, boolean_type_node, expr, max);
    1993              :     }
    1994        16702 :   t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
    1995        16702 :   if (integer_zerop (t))
    1996              :     return NULL_TREE;
    1997              : 
    1998        12097 :   if (flag_sanitize_trap & SANITIZE_FLOAT_CAST)
    1999            0 :     fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
    2000              :   else
    2001              :     {
    2002        12097 :       location_t *loc_ptr = NULL;
    2003        12097 :       unsigned num_locations = 0;
    2004              :       /* Figure out if we can propagate location to ubsan_data and use new
    2005              :          style handlers in libubsan.  */
    2006        12097 :       if (ubsan_use_new_style_p (loc))
    2007              :         {
    2008        12097 :           loc_ptr = &loc;
    2009        12097 :           num_locations = 1;
    2010              :         }
    2011              :       /* Create the __ubsan_handle_float_cast_overflow fn call.  */
    2012        12097 :       tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data",
    2013              :                                      num_locations, loc_ptr,
    2014              :                                      ubsan_type_descriptor (expr_type),
    2015              :                                      ubsan_type_descriptor (type), NULL_TREE,
    2016              :                                      NULL_TREE);
    2017          294 :       enum built_in_function bcode
    2018        12097 :         = (flag_sanitize_recover & SANITIZE_FLOAT_CAST)
    2019        12097 :           ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
    2020              :           : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
    2021        12097 :       fn = builtin_decl_explicit (bcode);
    2022        12097 :       fn = build_call_expr_loc (loc, fn, 2,
    2023              :                                 build_fold_addr_expr_loc (loc, data),
    2024              :                                 ubsan_encode_value (expr));
    2025              :     }
    2026              : 
    2027        12097 :   return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node);
    2028              : }
    2029              : 
    2030              : /* Instrument values passed to function arguments with nonnull attribute.  */
    2031              : 
    2032              : static void
    2033         4670 : instrument_nonnull_arg (gimple_stmt_iterator *gsi)
    2034              : {
    2035         4670 :   gimple *stmt = gsi_stmt (*gsi);
    2036         4670 :   location_t loc[2];
    2037              :   /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
    2038              :      while for nonnull sanitization it is clear.  */
    2039         4670 :   int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
    2040         4670 :   flag_delete_null_pointer_checks = 1;
    2041         4670 :   loc[0] = gimple_location (stmt);
    2042         4670 :   loc[1] = UNKNOWN_LOCATION;
    2043        13720 :   for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++)
    2044              :     {
    2045         9050 :       tree arg = gimple_call_arg (stmt, i);
    2046         9050 :       tree arg2, arg3;
    2047        14336 :       if (POINTER_TYPE_P (TREE_TYPE (arg))
    2048         9224 :           && infer_nonnull_range_by_attribute (stmt, arg, &arg2, &arg3))
    2049              :         {
    2050          968 :           gimple *g;
    2051          968 :           if (!is_gimple_val (arg))
    2052              :             {
    2053            0 :               g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
    2054            0 :               gimple_set_location (g, loc[0]);
    2055            0 :               gsi_safe_insert_before (gsi, g);
    2056            0 :               arg = gimple_assign_lhs (g);
    2057              :             }
    2058          968 :           if (arg2 == arg3)
    2059          928 :             arg3 = NULL_TREE;
    2060          968 :           if (arg2 && !is_gimple_val (arg2))
    2061              :             {
    2062            0 :               g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg2)), arg2);
    2063            0 :               gimple_set_location (g, loc[0]);
    2064            0 :               gsi_safe_insert_before (gsi, g);
    2065            0 :               arg2 = gimple_assign_lhs (g);
    2066              :             }
    2067          968 :           if (arg3 && !is_gimple_val (arg3))
    2068              :             {
    2069            0 :               g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg3)), arg3);
    2070            0 :               gimple_set_location (g, loc[0]);
    2071            0 :               gsi_safe_insert_before (gsi, g);
    2072            0 :               arg3 = gimple_assign_lhs (g);
    2073              :             }
    2074              : 
    2075          968 :           basic_block then_bb, fallthru_bb;
    2076          968 :           *gsi = create_cond_insert_point (gsi, true, false, true,
    2077              :                                            &then_bb, &fallthru_bb);
    2078          968 :           g = gimple_build_cond (EQ_EXPR, arg,
    2079          968 :                                  build_zero_cst (TREE_TYPE (arg)),
    2080              :                                  NULL_TREE, NULL_TREE);
    2081          968 :           gimple_set_location (g, loc[0]);
    2082          968 :           gsi_insert_after (gsi, g, GSI_NEW_STMT);
    2083              : 
    2084          968 :           *gsi = gsi_after_labels (then_bb);
    2085          968 :           if (arg2)
    2086              :             {
    2087          132 :               *gsi = create_cond_insert_point (gsi, true, false, true,
    2088              :                                                &then_bb, &fallthru_bb);
    2089          132 :               g = gimple_build_cond (NE_EXPR, arg2,
    2090          132 :                                      build_zero_cst (TREE_TYPE (arg2)),
    2091              :                                      NULL_TREE, NULL_TREE);
    2092          132 :               gimple_set_location (g, loc[0]);
    2093          132 :               gsi_insert_after (gsi, g, GSI_NEW_STMT);
    2094              : 
    2095          132 :               *gsi = gsi_after_labels (then_bb);
    2096              :             }
    2097          968 :           if (arg3)
    2098              :             {
    2099           40 :               *gsi = create_cond_insert_point (gsi, true, false, true,
    2100              :                                                &then_bb, &fallthru_bb);
    2101           40 :               g = gimple_build_cond (NE_EXPR, arg3,
    2102           40 :                                      build_zero_cst (TREE_TYPE (arg3)),
    2103              :                                      NULL_TREE, NULL_TREE);
    2104           40 :               gimple_set_location (g, loc[0]);
    2105           40 :               gsi_insert_after (gsi, g, GSI_NEW_STMT);
    2106              : 
    2107           40 :               *gsi = gsi_after_labels (then_bb);
    2108              :             }
    2109          968 :           if (flag_sanitize_trap & SANITIZE_NONNULL_ATTRIBUTE)
    2110          140 :             g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
    2111              :           else
    2112              :             {
    2113          828 :               tree data = ubsan_create_data ("__ubsan_nonnull_arg_data",
    2114              :                                              2, loc, NULL_TREE,
    2115              :                                              build_int_cst (integer_type_node,
    2116          828 :                                                             i + 1),
    2117              :                                              NULL_TREE);
    2118          828 :               data = build_fold_addr_expr_loc (loc[0], data);
    2119          210 :               enum built_in_function bcode
    2120          828 :                 = (flag_sanitize_recover & SANITIZE_NONNULL_ATTRIBUTE)
    2121          828 :                   ? BUILT_IN_UBSAN_HANDLE_NONNULL_ARG
    2122              :                   : BUILT_IN_UBSAN_HANDLE_NONNULL_ARG_ABORT;
    2123          828 :               tree fn = builtin_decl_explicit (bcode);
    2124              : 
    2125          828 :               g = gimple_build_call (fn, 1, data);
    2126              :             }
    2127          968 :           gimple_set_location (g, loc[0]);
    2128          968 :           gsi_safe_insert_before (gsi, g);
    2129          968 :           ubsan_create_edge (g);
    2130              :         }
    2131         9050 :       *gsi = gsi_for_stmt (stmt);
    2132              :     }
    2133         4670 :   flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
    2134         4670 : }
    2135              : 
    2136              : /* Instrument returns in functions with returns_nonnull attribute.  */
    2137              : 
    2138              : static void
    2139         2682 : instrument_nonnull_return (gimple_stmt_iterator *gsi)
    2140              : {
    2141         2682 :   greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
    2142         2682 :   location_t loc[2];
    2143         2682 :   tree arg = gimple_return_retval (stmt);
    2144              :   /* infer_nonnull_range needs flag_delete_null_pointer_checks set,
    2145              :      while for nonnull return sanitization it is clear.  */
    2146         2682 :   int save_flag_delete_null_pointer_checks = flag_delete_null_pointer_checks;
    2147         2682 :   flag_delete_null_pointer_checks = 1;
    2148         2682 :   loc[0] = gimple_location (stmt);
    2149         2682 :   loc[1] = UNKNOWN_LOCATION;
    2150         2682 :   if (arg
    2151         1855 :       && POINTER_TYPE_P (TREE_TYPE (arg))
    2152          108 :       && is_gimple_val (arg)
    2153         2790 :       && infer_nonnull_range_by_attribute (stmt, arg))
    2154              :     {
    2155           50 :       basic_block then_bb, fallthru_bb;
    2156           50 :       *gsi = create_cond_insert_point (gsi, true, false, true,
    2157              :                                        &then_bb, &fallthru_bb);
    2158           50 :       gimple *g = gimple_build_cond (EQ_EXPR, arg,
    2159           50 :                                     build_zero_cst (TREE_TYPE (arg)),
    2160              :                                     NULL_TREE, NULL_TREE);
    2161           50 :       gimple_set_location (g, loc[0]);
    2162           50 :       gsi_insert_after (gsi, g, GSI_NEW_STMT);
    2163              : 
    2164           50 :       *gsi = gsi_after_labels (then_bb);
    2165           50 :       if (flag_sanitize_trap & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
    2166           20 :         g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
    2167              :       else
    2168              :         {
    2169           30 :           tree data = ubsan_create_data ("__ubsan_nonnull_return_data",
    2170              :                                          1, &loc[1], NULL_TREE, NULL_TREE);
    2171           30 :           data = build_fold_addr_expr_loc (loc[0], data);
    2172           30 :           tree data2 = ubsan_create_data ("__ubsan_nonnull_return_data",
    2173              :                                           1, &loc[0], NULL_TREE, NULL_TREE);
    2174           30 :           data2 = build_fold_addr_expr_loc (loc[0], data2);
    2175           20 :           enum built_in_function bcode
    2176           30 :             = (flag_sanitize_recover & SANITIZE_RETURNS_NONNULL_ATTRIBUTE)
    2177           30 :               ? BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1
    2178              :               : BUILT_IN_UBSAN_HANDLE_NONNULL_RETURN_V1_ABORT;
    2179           30 :           tree fn = builtin_decl_explicit (bcode);
    2180              : 
    2181           30 :           g = gimple_build_call (fn, 2, data, data2);
    2182              :         }
    2183           50 :       gimple_set_location (g, loc[0]);
    2184           50 :       gsi_safe_insert_before (gsi, g);
    2185           50 :       ubsan_create_edge (g);
    2186           50 :       *gsi = gsi_for_stmt (stmt);
    2187              :     }
    2188         2682 :   flag_delete_null_pointer_checks = save_flag_delete_null_pointer_checks;
    2189         2682 : }
    2190              : 
    2191              : /* Instrument memory references.  Here we check whether the pointer
    2192              :    points to an out-of-bounds location.  */
    2193              : 
    2194              : static void
    2195         9116 : instrument_object_size (gimple_stmt_iterator *gsi, tree t, bool is_lhs)
    2196              : {
    2197         9116 :   gimple *stmt = gsi_stmt (*gsi);
    2198         9116 :   location_t loc = gimple_location (stmt);
    2199         9116 :   tree type;
    2200         9116 :   tree index = NULL_TREE;
    2201         9116 :   HOST_WIDE_INT size_in_bytes;
    2202              : 
    2203         9116 :   type = TREE_TYPE (t);
    2204         9116 :   if (VOID_TYPE_P (type))
    2205         6696 :     return;
    2206              : 
    2207         9116 :   switch (TREE_CODE (t))
    2208              :     {
    2209         4211 :     case COMPONENT_REF:
    2210         4211 :       if (TREE_CODE (t) == COMPONENT_REF
    2211         4211 :           && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
    2212              :         {
    2213           73 :           tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
    2214           73 :           t = build3 (COMPONENT_REF, TREE_TYPE (repr), TREE_OPERAND (t, 0),
    2215           73 :                       repr, TREE_OPERAND (t, 2));
    2216              :         }
    2217              :       break;
    2218          336 :     case ARRAY_REF:
    2219          336 :       index = TREE_OPERAND (t, 1);
    2220          336 :       break;
    2221              :     case INDIRECT_REF:
    2222              :     case MEM_REF:
    2223              :     case VAR_DECL:
    2224              :     case PARM_DECL:
    2225              :     case RESULT_DECL:
    2226              :       break;
    2227              :     default:
    2228              :       return;
    2229              :     }
    2230              : 
    2231         9098 :   size_in_bytes = int_size_in_bytes (type);
    2232         9098 :   if (size_in_bytes <= 0)
    2233              :     return;
    2234              : 
    2235         9092 :   poly_int64 bitsize, bitpos;
    2236         9092 :   tree offset;
    2237         9092 :   machine_mode mode;
    2238         9092 :   int volatilep = 0, reversep, unsignedp = 0;
    2239         9092 :   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset, &mode,
    2240              :                                     &unsignedp, &reversep, &volatilep);
    2241              : 
    2242         9092 :   if (!multiple_p (bitpos, BITS_PER_UNIT)
    2243         9092 :       || maybe_ne (bitsize, size_in_bytes * BITS_PER_UNIT))
    2244              :     return;
    2245              : 
    2246         9068 :   bool decl_p = DECL_P (inner);
    2247         9068 :   tree base;
    2248         9068 :   if (decl_p)
    2249              :     {
    2250         6194 :       if ((VAR_P (inner)
    2251              :            || TREE_CODE (inner) == PARM_DECL
    2252              :            || TREE_CODE (inner) == RESULT_DECL)
    2253         6194 :           && DECL_REGISTER (inner))
    2254              :         return;
    2255         6187 :       if (t == inner && !is_global_var (t))
    2256              :         return;
    2257              :       base = inner;
    2258              :     }
    2259         2874 :   else if (TREE_CODE (inner) == MEM_REF)
    2260         2867 :     base = TREE_OPERAND (inner, 0);
    2261              :   else
    2262              :     return;
    2263         8143 :   tree ptr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
    2264              : 
    2265        16793 :   while (TREE_CODE (base) == SSA_NAME)
    2266              :     {
    2267         3368 :       gimple *def_stmt = SSA_NAME_DEF_STMT (base);
    2268         3368 :       if (gimple_assign_ssa_name_copy_p (def_stmt)
    2269         3134 :           || (gimple_assign_cast_p (def_stmt)
    2270            3 :               && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
    2271         6502 :           || (is_gimple_assign (def_stmt)
    2272          737 :               && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR))
    2273              :         {
    2274          517 :           tree rhs1 = gimple_assign_rhs1 (def_stmt);
    2275          517 :           if (TREE_CODE (rhs1) == SSA_NAME
    2276          517 :               && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
    2277              :             break;
    2278              :           else
    2279              :             base = rhs1;
    2280              :         }
    2281              :       else
    2282              :         break;
    2283              :     }
    2284              : 
    2285         8143 :   if (!POINTER_TYPE_P (TREE_TYPE (base)) && !DECL_P (base))
    2286              :     return;
    2287              : 
    2288         8143 :   tree sizet;
    2289         8143 :   tree base_addr = base;
    2290         8143 :   gimple *bos_stmt = NULL;
    2291         8143 :   gimple_seq seq = NULL;
    2292         8143 :   if (decl_p)
    2293         5276 :     base_addr = build1 (ADDR_EXPR,
    2294         5276 :                         build_pointer_type (TREE_TYPE (base)), base);
    2295         8143 :   if (compute_builtin_object_size (base_addr, OST_DYNAMIC, &sizet))
    2296              :     ;
    2297         2861 :   else if (optimize)
    2298              :     {
    2299         2115 :       if (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION)
    2300            0 :         loc = input_location;
    2301              :       /* Generate __builtin_dynamic_object_size call.  */
    2302         2115 :       sizet = builtin_decl_explicit (BUILT_IN_DYNAMIC_OBJECT_SIZE);
    2303         2115 :       sizet = build_call_expr_loc (loc, sizet, 2, base_addr,
    2304              :                                    integer_zero_node);
    2305         2115 :       sizet = force_gimple_operand (sizet, &seq, false, NULL_TREE);
    2306              :       /* If the call above didn't end up being an integer constant, go one
    2307              :          statement back and get the __builtin_object_size stmt.  Save it,
    2308              :          we might need it later.  */
    2309         2115 :       if (SSA_VAR_P (sizet))
    2310         4230 :         bos_stmt = gsi_stmt (gsi_last (seq));
    2311              :     }
    2312              :   else
    2313              :     return;
    2314              : 
    2315              :   /* Generate UBSAN_OBJECT_SIZE (ptr, ptr+sizeof(*ptr)-base, objsize, ckind)
    2316              :      call.  */
    2317              :   /* ptr + sizeof (*ptr) - base */
    2318         7397 :   t = fold_build2 (MINUS_EXPR, sizetype,
    2319              :                    fold_convert (pointer_sized_int_node, ptr),
    2320              :                    fold_convert (pointer_sized_int_node, base_addr));
    2321         7397 :   t = fold_build2 (PLUS_EXPR, sizetype, t, TYPE_SIZE_UNIT (type));
    2322              : 
    2323              :   /* Perhaps we can omit the check.  */
    2324         7397 :   if (TREE_CODE (t) == INTEGER_CST
    2325         6337 :       && TREE_CODE (sizet) == INTEGER_CST
    2326        12361 :       && tree_int_cst_le (t, sizet))
    2327              :     return;
    2328              : 
    2329         2440 :   if (index != NULL_TREE
    2330          134 :       && TREE_CODE (index) == SSA_NAME
    2331           94 :       && TREE_CODE (sizet) == INTEGER_CST)
    2332              :     {
    2333           80 :       gimple *def = SSA_NAME_DEF_STMT (index);
    2334           80 :       if (is_gimple_assign (def)
    2335           73 :           && gimple_assign_rhs_code (def) == BIT_AND_EXPR
    2336          109 :           && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
    2337              :         {
    2338           26 :           tree cst = gimple_assign_rhs2 (def);
    2339           26 :           tree sz = fold_build2 (EXACT_DIV_EXPR, sizetype, sizet,
    2340              :                                  TYPE_SIZE_UNIT (type));
    2341           26 :           if (tree_int_cst_sgn (cst) >= 0
    2342           26 :               && tree_int_cst_lt (cst, sz))
    2343              :             return;
    2344              :         }
    2345              :     }
    2346              : 
    2347         2420 :   if (DECL_P (base)
    2348          299 :       && decl_function_context (base) == current_function_decl
    2349         2677 :       && !TREE_ADDRESSABLE (base))
    2350           61 :     mark_addressable (base);
    2351              : 
    2352              :   /* We have to emit the check.  */
    2353         2420 :   gimple_seq this_seq;
    2354         2420 :   t = force_gimple_operand (t, &this_seq, true, NULL_TREE);
    2355         2420 :   gimple_seq_add_seq_without_update (&seq, this_seq);
    2356         2420 :   ptr = force_gimple_operand (ptr, &this_seq, true, NULL_TREE);
    2357         2420 :   gimple_seq_add_seq_without_update (&seq, this_seq);
    2358         2420 :   gsi_safe_insert_seq_before (gsi, seq);
    2359              : 
    2360         2420 :   if (bos_stmt
    2361         2420 :       && gimple_call_builtin_p (bos_stmt, BUILT_IN_DYNAMIC_OBJECT_SIZE))
    2362         2115 :     ubsan_create_edge (bos_stmt);
    2363              : 
    2364         2420 :   tree ckind = build_int_cst (unsigned_char_type_node,
    2365         3952 :                               is_lhs ? UBSAN_STORE_OF : UBSAN_LOAD_OF);
    2366         2420 :   gimple *g = gimple_build_call_internal (IFN_UBSAN_OBJECT_SIZE, 4,
    2367              :                                          ptr, t, sizet, ckind);
    2368         2420 :   gimple_set_location (g, loc);
    2369         2420 :   gsi_safe_insert_before (gsi, g);
    2370              : }
    2371              : 
    2372              : /* Instrument values passed to builtin functions.  */
    2373              : 
    2374              : static void
    2375         1342 : instrument_builtin (gimple_stmt_iterator *gsi)
    2376              : {
    2377         1342 :   gimple *stmt = gsi_stmt (*gsi);
    2378         1342 :   location_t loc = gimple_location (stmt);
    2379         1342 :   tree arg;
    2380         1342 :   enum built_in_function fcode
    2381         1342 :     = DECL_FUNCTION_CODE (gimple_call_fndecl (stmt));
    2382         1342 :   int kind = 0;
    2383         1342 :   switch (fcode)
    2384              :     {
    2385           80 :     CASE_INT_FN (BUILT_IN_CLZ):
    2386           80 :       kind = 1;
    2387          180 :       gcc_fallthrough ();
    2388          180 :     CASE_INT_FN (BUILT_IN_CTZ):
    2389          180 :       arg = gimple_call_arg (stmt, 0);
    2390          180 :       if (!integer_nonzerop (arg))
    2391              :         {
    2392          180 :           gimple *g;
    2393          180 :           if (!is_gimple_val (arg))
    2394              :             {
    2395            0 :               g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
    2396            0 :               gimple_set_location (g, loc);
    2397            0 :               gsi_insert_before (gsi, g, GSI_SAME_STMT);
    2398            0 :               arg = gimple_assign_lhs (g);
    2399              :             }
    2400              : 
    2401          180 :           basic_block then_bb, fallthru_bb;
    2402          180 :           *gsi = create_cond_insert_point (gsi, true, false, true,
    2403              :                                            &then_bb, &fallthru_bb);
    2404          180 :           g = gimple_build_cond (EQ_EXPR, arg,
    2405          180 :                                  build_zero_cst (TREE_TYPE (arg)),
    2406              :                                  NULL_TREE, NULL_TREE);
    2407          180 :           gimple_set_location (g, loc);
    2408          180 :           gsi_insert_after (gsi, g, GSI_NEW_STMT);
    2409              : 
    2410          180 :           *gsi = gsi_after_labels (then_bb);
    2411          180 :           if (flag_sanitize_trap & SANITIZE_BUILTIN)
    2412            0 :             g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
    2413              :           else
    2414              :             {
    2415          180 :               tree t = build_int_cst (unsigned_char_type_node, kind);
    2416          180 :               tree data = ubsan_create_data ("__ubsan_builtin_data",
    2417              :                                              1, &loc, NULL_TREE, t, NULL_TREE);
    2418          180 :               data = build_fold_addr_expr_loc (loc, data);
    2419            0 :               enum built_in_function bcode
    2420          180 :                 = (flag_sanitize_recover & SANITIZE_BUILTIN)
    2421          180 :                   ? BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN
    2422              :                   : BUILT_IN_UBSAN_HANDLE_INVALID_BUILTIN_ABORT;
    2423          180 :               tree fn = builtin_decl_explicit (bcode);
    2424              : 
    2425          180 :               g = gimple_build_call (fn, 1, data);
    2426              :             }
    2427          180 :           gimple_set_location (g, loc);
    2428          180 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
    2429          180 :           ubsan_create_edge (g);
    2430              :         }
    2431          180 :       *gsi = gsi_for_stmt (stmt);
    2432          180 :       break;
    2433              :     default:
    2434              :       break;
    2435              :     }
    2436         1342 : }
    2437              : 
    2438              : namespace {
    2439              : 
    2440              : const pass_data pass_data_ubsan =
    2441              : {
    2442              :   GIMPLE_PASS, /* type */
    2443              :   "ubsan", /* name */
    2444              :   OPTGROUP_NONE, /* optinfo_flags */
    2445              :   TV_TREE_UBSAN, /* tv_id */
    2446              :   ( PROP_cfg | PROP_ssa ), /* properties_required */
    2447              :   0, /* properties_provided */
    2448              :   0, /* properties_destroyed */
    2449              :   0, /* todo_flags_start */
    2450              :   TODO_update_ssa, /* todo_flags_finish */
    2451              : };
    2452              : 
    2453              : class pass_ubsan : public gimple_opt_pass
    2454              : {
    2455              : public:
    2456       288767 :   pass_ubsan (gcc::context *ctxt)
    2457       577534 :     : gimple_opt_pass (pass_data_ubsan, ctxt)
    2458              :   {}
    2459              : 
    2460              :   /* opt_pass methods: */
    2461      2879401 :   bool gate (function *) final override
    2462              :     {
    2463      2879401 :       return sanitize_flags_p ((SANITIZE_NULL | SANITIZE_SI_OVERFLOW
    2464              :                                 | SANITIZE_BOOL | SANITIZE_ENUM
    2465              :                                 | SANITIZE_ALIGNMENT
    2466              :                                 | SANITIZE_NONNULL_ATTRIBUTE
    2467              :                                 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE
    2468              :                                 | SANITIZE_OBJECT_SIZE
    2469              :                                 | SANITIZE_POINTER_OVERFLOW
    2470      2879401 :                                 | SANITIZE_BUILTIN));
    2471              :     }
    2472              : 
    2473              :   unsigned int execute (function *) final override;
    2474              : 
    2475              : }; // class pass_ubsan
    2476              : 
    2477              : unsigned int
    2478         4714 : pass_ubsan::execute (function *fun)
    2479              : {
    2480         4714 :   basic_block bb;
    2481         4714 :   gimple_stmt_iterator gsi;
    2482         4714 :   unsigned int ret = 0;
    2483              : 
    2484         4714 :   initialize_sanitizer_builtins ();
    2485              : 
    2486        27465 :   FOR_EACH_BB_FN (bb, fun)
    2487              :     {
    2488       143464 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
    2489              :         {
    2490        97962 :           gimple *stmt = gsi_stmt (gsi);
    2491        97962 :           if (is_gimple_debug (stmt) || gimple_clobber_p (stmt))
    2492              :             {
    2493         7431 :               gsi_next (&gsi);
    2494         7431 :               continue;
    2495              :             }
    2496              : 
    2497        90531 :           if ((sanitize_flags_p (SANITIZE_SI_OVERFLOW, fun->decl))
    2498        90531 :               && is_gimple_assign (stmt))
    2499        53722 :             instrument_si_overflow (gsi);
    2500              : 
    2501        90531 :           if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT, fun->decl))
    2502              :             {
    2503        40285 :               if (gimple_store_p (stmt))
    2504         4669 :                 instrument_null (gsi, gimple_get_lhs (stmt), true);
    2505        40285 :               if (gimple_assign_single_p (stmt))
    2506        14998 :                 instrument_null (gsi, gimple_assign_rhs1 (stmt), false);
    2507        40285 :               if (is_gimple_call (stmt))
    2508              :                 {
    2509         6252 :                   unsigned args_num = gimple_call_num_args (stmt);
    2510        18634 :                   for (unsigned i = 0; i < args_num; ++i)
    2511              :                     {
    2512        12382 :                       tree arg = gimple_call_arg (stmt, i);
    2513        12382 :                       if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
    2514        11984 :                         continue;
    2515          398 :                       instrument_null (gsi, arg, false);
    2516              :                     }
    2517              :                 }
    2518              :             }
    2519              : 
    2520        90531 :           if (sanitize_flags_p (SANITIZE_BOOL | SANITIZE_ENUM, fun->decl)
    2521        90531 :               && gimple_assign_load_p (stmt))
    2522              :             {
    2523         4619 :               instrument_bool_enum_load (&gsi);
    2524         4619 :               bb = gimple_bb (stmt);
    2525              :             }
    2526              : 
    2527        90531 :           if (sanitize_flags_p (SANITIZE_NONNULL_ATTRIBUTE, fun->decl)
    2528        35947 :               && is_gimple_call (stmt)
    2529        96035 :               && !gimple_call_internal_p (stmt))
    2530              :             {
    2531         4670 :               instrument_nonnull_arg (&gsi);
    2532         4670 :               bb = gimple_bb (stmt);
    2533              :             }
    2534              : 
    2535        90531 :           if (sanitize_flags_p (SANITIZE_BUILTIN, fun->decl)
    2536        90531 :               && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    2537              :             {
    2538         1342 :               instrument_builtin (&gsi);
    2539         1342 :               bb = gimple_bb (stmt);
    2540              :             }
    2541              : 
    2542        90531 :           if (sanitize_flags_p (SANITIZE_RETURNS_NONNULL_ATTRIBUTE, fun->decl)
    2543        90531 :               && gimple_code (stmt) == GIMPLE_RETURN)
    2544              :             {
    2545         2682 :               instrument_nonnull_return (&gsi);
    2546         2682 :               bb = gimple_bb (stmt);
    2547              :             }
    2548              : 
    2549        90531 :           if (sanitize_flags_p (SANITIZE_OBJECT_SIZE, fun->decl))
    2550              :             {
    2551        36081 :               if (gimple_store_p (stmt))
    2552         4436 :                 instrument_object_size (&gsi, gimple_get_lhs (stmt), true);
    2553        36081 :               if (gimple_assign_load_p (stmt))
    2554         4610 :                 instrument_object_size (&gsi, gimple_assign_rhs1 (stmt),
    2555              :                                         false);
    2556        36081 :               if (is_gimple_call (stmt))
    2557              :                 {
    2558         5444 :                   unsigned args_num = gimple_call_num_args (stmt);
    2559        16371 :                   for (unsigned i = 0; i < args_num; ++i)
    2560              :                     {
    2561        10927 :                       tree arg = gimple_call_arg (stmt, i);
    2562        10927 :                       if (is_gimple_reg (arg) || is_gimple_min_invariant (arg))
    2563        10857 :                         continue;
    2564           70 :                       instrument_object_size (&gsi, arg, false);
    2565              :                     }
    2566              :                 }
    2567              :             }
    2568              : 
    2569        90531 :           if (sanitize_flags_p (SANITIZE_POINTER_OVERFLOW, fun->decl))
    2570              :             {
    2571        38988 :               if (is_gimple_assign (stmt)
    2572        38988 :                   && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
    2573          805 :                 instrument_pointer_overflow (&gsi,
    2574              :                                              gimple_assign_rhs1 (stmt),
    2575              :                                              gimple_assign_rhs2 (stmt));
    2576        38988 :               if (gimple_store_p (stmt))
    2577         5230 :                 maybe_instrument_pointer_overflow (&gsi,
    2578              :                                                    gimple_get_lhs (stmt));
    2579        38988 :               if (gimple_assign_single_p (stmt))
    2580        15076 :                 maybe_instrument_pointer_overflow (&gsi,
    2581              :                                                    gimple_assign_rhs1 (stmt));
    2582        38988 :               if (is_gimple_call (stmt))
    2583              :                 {
    2584         5887 :                   unsigned args_num = gimple_call_num_args (stmt);
    2585        17571 :                   for (unsigned i = 0; i < args_num; ++i)
    2586              :                     {
    2587        11684 :                       tree arg = gimple_call_arg (stmt, i);
    2588        11684 :                       if (is_gimple_reg (arg))
    2589         5175 :                         continue;
    2590         6509 :                       maybe_instrument_pointer_overflow (&gsi, arg);
    2591              :                     }
    2592              :                 }
    2593              :             }
    2594              : 
    2595        90531 :           gsi_next (&gsi);
    2596              :         }
    2597        22751 :       if (gimple_purge_dead_eh_edges (bb))
    2598           52 :         ret = TODO_cleanup_cfg;
    2599              :     }
    2600         4714 :   return ret;
    2601              : }
    2602              : 
    2603              : } // anon namespace
    2604              : 
    2605              : gimple_opt_pass *
    2606       288767 : make_pass_ubsan (gcc::context *ctxt)
    2607              : {
    2608       288767 :   return new pass_ubsan (ctxt);
    2609              : }
    2610              : 
    2611              : #include "gt-ubsan.h"
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.