LCOV - code coverage report
Current view: top level - gcc - ubsan.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 1278 1314 97.3 %
Date: 2020-04-04 11:58:09 Functions: 33 33 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.