summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Khalikov <d.khalikov@partner.samsung.com>2017-10-28 17:39:01 +0300
committerDenis Khalikov <d.khalikov@partner.samsung.com>2017-10-28 18:41:11 +0300
commit02b62443516966cb329722fa2ad217a384a95cd9 (patch)
tree120fae60a95c7141cd71c3308320f39ad64aff5d
parentda1dbde9cfceed248de0b28a0ef7a0f2a54ba5bd (diff)
downloadlinaro-gcc-sandbox/denis13/isan_fix.tar.gz
linaro-gcc-sandbox/denis13/isan_fix.tar.bz2
linaro-gcc-sandbox/denis13/isan_fix.zip
[ISan] Workaround for SAVE_EXPRsandbox/denis13/isan_fix
Change-Id: Iac55ab97fae23b9046bb40b4556cb85b24c278bf
-rw-r--r--gcc/cp/tree.c11
-rw-r--r--gcc/cp/typeck.c5
-rw-r--r--gcc/tree.c39
3 files changed, 53 insertions, 2 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 5e8bb742bf4..e6daeac26a8 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify.h"
#include "attribs.h"
+extern tree isan_expr (tree expr);
static tree bot_manip (tree *, int *, void *);
static tree bot_replace (tree *, int *, void *);
static hashval_t list_hash_pieces (tree, tree, tree);
@@ -4057,6 +4058,16 @@ cp_save_expr (tree expr)
return save_expr (expr);
}
+/* Workaround for isan and save_expr. */
+
+tree
+cp_isan_expr (tree expr)
+{
+ if (processing_template_decl)
+ return expr;
+ return isan_expr (expr);
+}
+
/* Initialize tree.c. */
void
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 458baa70539..5e5cd6407e7 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-ubsan.h"
#include "params.h"
+extern tree cp_isan_expr (tree expr);
static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
static tree cp_build_function_call (tree, tree, tsubst_flags_t);
static tree pfn_from_ptrmemfunc (tree);
@@ -5173,9 +5174,9 @@ cp_build_binary_op (location_t location,
How to get actual value from SAVE_EXPR ?
FIXME: use SAVE_EXPR. */
+ op0 = cp_isan_expr (op0);
+ op1 = cp_isan_expr (op1);
/*
- op0 = cp_save_expr (op0);
- op1 = cp_save_expr (op1);
op0 = fold_non_dependent_expr (op0);
op1 = fold_non_dependent_expr (op1);
*/
diff --git a/gcc/tree.c b/gcc/tree.c
index 7ce14c93663..64327099909 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -3375,6 +3375,45 @@ save_expr (tree expr)
return t;
}
+/* Workaround for isan and save_expr. */
+
+tree
+isan_expr (tree expr)
+{
+ tree t = fold (expr);
+ tree inner;
+
+ /* If the tree evaluates to a constant, then we don't want to hide that
+ fact (i.e. this allows further folding, and direct checks for constants).
+ However, a read-only object that has side effects cannot be bypassed.
+ Since it is no problem to reevaluate literals, we just return the
+ literal node. */
+ inner = skip_simple_arithmetic (t);
+ if (TREE_CODE (inner) == ERROR_MARK)
+ return inner;
+
+ if (tree_invariant_p_1 (inner))
+ return t;
+
+ /* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
+ it means that the size or offset of some field of an object depends on
+ the value within another field.
+
+ Note that it must not be the case that T contains both a PLACEHOLDER_EXPR
+ and some variable since it would then need to be both evaluated once and
+ evaluated more than once. Front-ends must assure this case cannot
+ happen by surrounding any such subexpressions in their own SAVE_EXPR
+ and forcing evaluation at the proper time. */
+ if (contains_placeholder_p (inner))
+ return t;
+
+ /* This expression might be placed ahead of a jump to ensure that the
+ value was computed on both sides of the jump. So make sure it isn't
+ eliminated as dead. */
+ TREE_SIDE_EFFECTS (t) = 1;
+ return t;
+}
+
/* Look inside EXPR into any simple arithmetic operations. Return the
outermost non-arithmetic or non-invariant node. */