- Return to old hash table.
- Define missing void_zero_node macro.
- Add missing tree_int_cst_le function.
- Add missing gcc/signop.h header.
- Add missing macro.
- Add missing specialization stuff for double_int class.
- Add missing wi::clz and wi::clrsb functions. Add new file wide-int.cc.
- Remove include of double-int.h from gcc/gengtype.c and gcc/gengtype-state.c.
- Small fix for hash table. Change operator '->' to '.' because we have
a reference to hash table, not a pointer.
- Change varpool_node::finalize_decl (var) back to varpool_finalize_decl (var).
- Fix sanopt.c optimizing part to fit old style pointer map.
- Fix for CHECK_TYPE_SIZE(__kernel_old_uid_t) and CHECK_TYPE_SIZE(__kernel_old_gid_t)
fails on Aarch64.
- Replace gcall back to gimple_statement_call.
- Use old cgraph interface.
- Define missing void_node macro.
- Add missing SUBREG_PROMOTED_SIGN macro.
- Fix ICE in ubsan_type_descriptor due to overflow in tree_fits_uhwi_p.
Change-Id: I9741e28505c96c37fb1ff89f4721725c1a5a5eaf
Signed-off-by: Maxim Ostapenko <m.ostapenko@samsung.com>
varasm.o \
varpool.o \
vmsdbgout.o \
+ wide-int.o \
vtable-verify.o \
web.o \
xcoffout.o \
asan_mem_ref r;
asan_mem_ref_init (&r, ref, access_size);
- asan_mem_ref *saved_ref = get_mem_ref_hash_table ()->find (&r);
+ asan_mem_ref *saved_ref = get_mem_ref_hash_table ().find (&r);
return saved_ref && saved_ref->access_size >= access_size;
}
asan_mem_ref r;
asan_mem_ref_init (&r, ref, access_size);
- asan_mem_ref **slot = ht->find_slot (&r, INSERT);
+ asan_mem_ref **slot = ht.find_slot (&r, INSERT);
if (*slot == NULL || (*slot)->access_size < access_size)
*slot = asan_mem_ref_new (ref, access_size);
}
TREE_CONSTANT (ctor) = 1;
TREE_STATIC (ctor) = 1;
DECL_INITIAL (var) = ctor;
- varpool_node::finalize_decl (var);
+ varpool_finalize_decl (var);
locptr = fold_convert (uptr, build_fold_addr_expr (var));
}
else
as the index might be constant or masked, so ensure it is not
walked again and walk its subtrees manually. */
tree aref = TREE_OPERAND (*tp, 0);
- pset->add (aref);
+ pointer_set_insert (pset, aref);
*walk_subtrees = 0;
walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
walk_tree (&TREE_OPERAND (aref, 1), ubsan_walk_array_refs_r, pset, pset);
#include "builtins.h"
#include "gimplify.h"
+#define void_node void_zero_node
+
/* Instrument division by zero and INT_MIN / -1. If not instrumenting,
return NULL_TREE. */
#ifndef DOUBLE_INT_H
#define DOUBLE_INT_H
+#include "wide-int.h"
+
/* A large integer is currently represented as a pair of HOST_WIDE_INTs.
It therefore represents a number with precision of
2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the
double_int mpz_get_double_int (const_tree, mpz_t, bool);
#endif
+namespace wi
+{
+ template <>
+ struct int_traits <double_int>
+ {
+ static const enum precision_type precision_type = CONST_PRECISION;
+ static const bool host_dependent_precision = true;
+ static const unsigned int precision = HOST_BITS_PER_DOUBLE_INT;
+ static unsigned int get_precision (const double_int &);
+ static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int,
+ const double_int &);
+ };
+}
+
+inline unsigned int
+wi::int_traits <double_int>::get_precision (const double_int &)
+{
+ return precision;
+}
+
+inline wi::storage_ref
+wi::int_traits <double_int>::decompose (HOST_WIDE_INT *scratch, unsigned int p,
+ const double_int &x)
+{
+ gcc_checking_assert (precision == p);
+ scratch[0] = x.low;
+ if ((x.high == 0 && scratch[0] >= 0) || (x.high == -1 && scratch[0] < 0))
+ return wi::storage_ref (scratch, 1, precision);
+ scratch[1] = x.high;
+ return wi::storage_ref (scratch, 2, precision);
+}
+
#endif /* DOUBLE_INT_H */
#endif
#include "system.h"
#include "errors.h" /* For fatal. */
-#include "double-int.h"
#include "hashtab.h"
#include "version.h" /* For version_string & pkgversion_string. */
#include "obstack.h"
#include "system.h"
#include "errors.h" /* for fatal */
#include "getopt.h"
-#include "double-int.h"
#include "version.h" /* for version_string & pkgversion_string. */
#include "hashtab.h"
#include "xregex.h"
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "wide-int.h"
#include "tree.h"
#include "internal-fn.h"
#include "stor-layout.h"
extension, except for generating instructions where we need to
emit special code (ptr_extend insns) on some architectures. */
+/* Returns sign of promoted mode for SUBREG_PROMOTED_VAR_P(). */
+#define SUBREG_PROMOTED_SIGN(RTX) \
+ ((RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_SIGN", (RTX), SUBREG)->volatil) ? 1\
+ : (RTX)->unchanging - 1)
+
#define SUBREG_PROMOTED_UNSIGNED_P(RTX) \
((RTL_FLAG_CHECK1 ("SUBREG_PROMOTED_UNSIGNED_P", (RTX), SUBREG)->volatil) \
? -1 : (int) (RTX)->unchanging)
#include "predict.h"
#include "vec.h"
#include "hashtab.h"
-#include "hash-set.h"
+#include "pointer-set.h"
#include "tm.h"
#include "hard-reg-set.h"
#include "function.h"
-#include "dominance.h"
-#include "cfg.h"
#include "basic-block.h"
#include "tree-ssa-alias.h"
#include "internal-fn.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
-#include "hash-map.h"
#include "plugin-api.h"
#include "tree-pass.h"
#include "asan.h"
#include "ubsan.h"
#include "params.h"
#include "tree-ssa-operands.h"
+#include <new>
/* This is used to carry information about basic blocks. It is
{
/* This map maps a pointer (the first argument of UBSAN_NULL) to
a vector of UBSAN_NULL call statements that check this pointer. */
- hash_map<tree, auto_vec<gimple> > null_check_map;
+ pointer_map<auto_vec<gimple> > null_check_map;
/* This map maps a pointer (the second argument of ASAN_CHECK) to
a vector of ASAN_CHECK call statements that check the access. */
- hash_map<tree, auto_vec<gimple> > asan_check_map;
+ pointer_map< auto_vec<gimple> > asan_check_map;
/* Number of IFN_ASAN_CHECK statements. */
int asan_num_accesses;
gcc_assert (TREE_CODE (cur_align) == INTEGER_CST);
bool remove = false;
- auto_vec<gimple> &v = ctx->null_check_map.get_or_insert (ptr);
- if (v.is_empty ())
+ bool exists = true;
+ void **slot =
+ pointer_map_contains ((const pointer_map_t *)&ctx->null_check_map, ptr);
+ if (!slot)
+ {
+ slot = pointer_map_insert ((pointer_map_t *)&ctx->null_check_map, ptr);
+ exists = false;
+ }
+ auto_vec<gimple> &v
+ = exists ? *(auto_vec<gimple> *) slot : *new(slot) auto_vec<gimple> ();
+
+ if (!exists)
{
/* For this PTR we don't have any UBSAN_NULL stmts recorded, so there's
nothing to optimize yet. */
gimple_set_uid (stmt, info->freeing_call_events);
- auto_vec<gimple> &v = ctx->asan_check_map.get_or_insert (ptr);
- if (v.is_empty ())
+ bool exists = true;
+ void **slot =
+ pointer_map_contains ((const pointer_map_t *)&ctx->asan_check_map, ptr);
+ if (!slot)
+ {
+ slot = pointer_map_insert ((pointer_map_t *)&ctx->asan_check_map, ptr);
+ exists = false;
+ }
+ auto_vec<gimple> &v
+ = exists ? *(auto_vec<gimple> *) slot : *new(slot) auto_vec<gimple> ();
+
+ if (!exists)
{
/* For this PTR we don't have any ASAN_CHECK stmts recorded, so there's
nothing to optimize yet. */
if (optimize
&& (flag_sanitize
& (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_ADDRESS)))
- asan_num_accesses = sanopt_optimize (fun);
+ asan_num_accesses = sanopt_optimize (cfun);
else if (flag_sanitize & SANITIZE_ADDRESS)
{
gimple_stmt_iterator gsi;
--- /dev/null
+/* Operations with SIGNED and UNSIGNED. -*- C++ -*-
+ Copyright (C) 2012-2015 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef SIGNOP_H
+#define SIGNOP_H
+
+/* This type is used for the large number of functions that produce
+ different results depending on if the operands are signed types or
+ unsigned types. The signedness of a tree type can be found by
+ using the TYPE_SIGN macro. */
+
+enum signop_e {
+ SIGNED,
+ UNSIGNED
+};
+
+typedef enum signop_e signop;
+
+#endif
#define gcc_unreachable() (fancy_abort (__FILE__, __LINE__, __FUNCTION__))
#endif
+#if GCC_VERSION >= 3001
+#define STATIC_CONSTANT_P(X) (__builtin_constant_p (X) && (X))
+#else
+#define STATIC_CONSTANT_P(X) (false && (X))
+#endif
+
+/* Until we can use C++11's static_assert. */
+#define STATIC_ASSERT(X) \
+ typedef int assertion1[(X) ? 1 : -1] ATTRIBUTE_UNUSED
+
/* Provide a fake boolean type. We make no attempt to use the
C99 _Bool, as it may not be available in the bootstrap compiler,
and even if it is, it is liable to be buggy.
return INT_CST_LT_UNSIGNED (t1, t2);
}
+/* Nonzero if integer constants T1 and T2 represent values that satisfy <=.
+ The precise way of comparison depends on their data type. */
+
+int
+tree_int_cst_le (const_tree t1, const_tree t2)
+{
+ return tree_int_cst_lt (t1, t2) || tree_int_cst_equal (t1, t2);
+}
+
/* Returns -1 if T1 < T2, 0 if T1 == T2, and 1 if T1 > T2. */
int
#define complex_long_double_type_node global_trees[TI_COMPLEX_LONG_DOUBLE_TYPE]
#define void_type_node global_trees[TI_VOID_TYPE]
+#define void_node void_zero_node
/* The C type `void *'. */
#define ptr_type_node global_trees[TI_PTR_TYPE]
/* The C type `const void *'. */
extern int attribute_list_contained (const_tree, const_tree);
extern int tree_int_cst_equal (const_tree, const_tree);
extern int tree_int_cst_lt (const_tree, const_tree);
+extern int tree_int_cst_le (const_tree, const_tree);
extern int tree_int_cst_compare (const_tree, const_tree);
extern bool tree_fits_shwi_p (const_tree)
#ifndef ENABLE_TREE_CHECKING
{
pretty_name[pos++] = '[';
tree dom = TYPE_DOMAIN (t);
- if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
+ if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST
+ && (tree_fits_uhwi_p (TYPE_MAX_VALUE (dom))))
pos += sprintf (&pretty_name[pos], HOST_WIDE_INT_PRINT_DEC,
tree_to_uhwi (TYPE_MAX_VALUE (dom)) + 1);
else
static void
ubsan_create_edge (gimple stmt)
{
- gcall *call_stmt = dyn_cast <gcall *> (stmt);
+ gimple_statement_call *call_stmt = static_cast <gimple_statement_call *> (stmt);
basic_block bb = gimple_bb (stmt);
int freq = compute_call_stmt_bb_frequency (current_function_decl, bb);
- cgraph_node *node = cgraph_node::get (current_function_decl);
+ cgraph_node *node = cgraph_get_node (current_function_decl);
tree decl = gimple_call_fndecl (call_stmt);
if (decl)
- node->create_edge (cgraph_node::get_create (decl), call_stmt, bb->count,
+ cgraph_create_edge (node, cgraph_get_create_node (decl), call_stmt, bb->count,
freq);
}
--- /dev/null
+/* Operations with very long integers.
+ Copyright (C) 2012-2015 Free Software Foundation, Inc.
+ Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "hwint.h"
+#include "wide-int.h"
+#include "machmode.h"
+#include "vec.h"
+#include "double-int.h"
+#include "input.h"
+#include "alias.h"
+#include "symtab.h"
+#include "tree.h"
+#include "dumpfile.h"
+
+#if HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_HALF_WIDE_INT long
+#elif HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_INT
+# define HOST_HALF_WIDE_INT int
+#else
+#error Please add support for HOST_HALF_WIDE_INT
+#endif
+
+/* Return the number of leading (upper) zeros in X. */
+int
+wi::clz (const wide_int_ref &x)
+{
+ /* Calculate how many bits there above the highest represented block. */
+ int count = x.precision - x.len * HOST_BITS_PER_WIDE_INT;
+
+ unsigned HOST_WIDE_INT high = x.uhigh ();
+ if (count < 0)
+ /* The upper -COUNT bits of HIGH are not part of the value.
+ Clear them out. */
+ high = (high << -count) >> -count;
+ else if (x.sign_mask () < 0)
+ /* The upper bit is set, so there are no leading zeros. */
+ return 0;
+
+ /* We don't need to look below HIGH. Either HIGH is nonzero,
+ or the top bit of the block below is nonzero; clz_hwi is
+ HOST_BITS_PER_WIDE_INT in the latter case. */
+ return count + clz_hwi (high);
+}
+
+int
+wi::clrsb (const wide_int_ref &x)
+{
+ /* Calculate how many bits there above the highest represented block. */
+ int count = x.precision - x.len * HOST_BITS_PER_WIDE_INT;
+
+ unsigned HOST_WIDE_INT high = x.uhigh ();
+ unsigned HOST_WIDE_INT mask = -1;
+ if (count < 0)
+ {
+ /* The upper -COUNT bits of HIGH are not part of the value.
+ Clear them from both MASK and HIGH. */
+ mask >>= -count;
+ high &= mask;
+ }
+
+ /* If the top bit is 1, count the number of leading 1s. If the top
+ bit is zero, count the number of leading zeros. */
+ if (high > mask / 2)
+ high ^= mask;
+
+ /* There are no sign bits below the top block, so we don't need to look
+ beyond HIGH. Note that clz_hwi is HOST_BITS_PER_WIDE_INT when
+ HIGH is 0. */
+ return count + clz_hwi (high) - 1;
+}
+
+/* Return the number of trailing (lower) zeros in X. */
+int
+wi::ctz (const wide_int_ref &x)
+{
+ if (x.len == 1 && x.ulow () == 0)
+ return x.precision;
+
+ /* Having dealt with the zero case, there must be a block with a
+ nonzero bit. We don't care about the bits above the first 1. */
+ unsigned int i = 0;
+ while (x.val[i] == 0)
+ ++i;
+ return i * HOST_BITS_PER_WIDE_INT + ctz_hwi (x.val[i]);
+}
CHECK_TYPE_SIZE(__kernel_uid_t);
CHECK_TYPE_SIZE(__kernel_gid_t);
+#if !defined(__aarch64__)
CHECK_TYPE_SIZE(__kernel_old_uid_t);
CHECK_TYPE_SIZE(__kernel_old_gid_t);
+#endif
CHECK_TYPE_SIZE(__kernel_off_t);
CHECK_TYPE_SIZE(__kernel_loff_t);
CHECK_TYPE_SIZE(__kernel_fd_set);