summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-18 22:15:42 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-18 22:15:42 +0000
commitf8fc8b8e787c4279c1f24c91459b6dbe481d7805 (patch)
tree3100f945556d63aeaa058af9f42a2c3172835edc
parentae371dcf05157f821e4542336745f64a7c638cf1 (diff)
downloadgcc-f8fc8b8e787c4279c1f24c91459b6dbe481d7805.tar.gz
PR sanitizer/63813
* c-ubsan.c (ubsan_maybe_instrument_reference_or_call): Change type argument to ptype, set type to TREE_TYPE (ptype). Don't call get_pointer_alignment for non-pointers. Use ptype, or if it is reference type, corresponding pointer type, as type of kind argument. (ubsan_maybe_instrument_reference, ubsan_maybe_instrument_member_call): Adjust callers. * g++.dg/ubsan/pr63813.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217741 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/c-family/ChangeLog11
-rw-r--r--gcc/c-family/c-ubsan.c28
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr63813.C12
4 files changed, 44 insertions, 10 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index fa0518a63eb..cc6771a1bf5 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,14 @@
+2014-11-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/63813
+ * c-ubsan.c (ubsan_maybe_instrument_reference_or_call): Change type
+ argument to ptype, set type to TREE_TYPE (ptype). Don't call
+ get_pointer_alignment for non-pointers. Use ptype, or if it is
+ reference type, corresponding pointer type, as type of kind
+ argument.
+ (ubsan_maybe_instrument_reference,
+ ubsan_maybe_instrument_member_call): Adjust callers.
+
2014-11-15 Marek Polacek <polacek@redhat.com>
PR middle-end/63884
diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c
index ab16799b0c9..90b03f23e73 100644
--- a/gcc/c-family/c-ubsan.c
+++ b/gcc/c-family/c-ubsan.c
@@ -383,18 +383,19 @@ ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one)
}
static tree
-ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree type,
+ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree ptype,
enum ubsan_null_ckind ckind)
{
- tree orig_op = op;
- bool instrument = false;
- unsigned int mina = 0;
-
if (current_function_decl == NULL_TREE
|| lookup_attribute ("no_sanitize_undefined",
DECL_ATTRIBUTES (current_function_decl)))
return NULL_TREE;
+ tree type = TREE_TYPE (ptype);
+ tree orig_op = op;
+ bool instrument = false;
+ unsigned int mina = 0;
+
if (flag_sanitize & SANITIZE_ALIGNMENT)
{
mina = min_align_of_type (type);
@@ -431,13 +432,20 @@ ubsan_maybe_instrument_reference_or_call (location_t loc, tree op, tree type,
}
else if (flag_sanitize & SANITIZE_NULL)
instrument = true;
- if (mina && mina > get_pointer_alignment (op) / BITS_PER_UNIT)
- instrument = true;
+ if (mina && mina > 1)
+ {
+ if (!POINTER_TYPE_P (TREE_TYPE (op))
+ || mina > get_pointer_alignment (op) / BITS_PER_UNIT)
+ instrument = true;
+ }
}
if (!instrument)
return NULL_TREE;
op = save_expr (orig_op);
- tree kind = build_int_cst (TREE_TYPE (op), ckind);
+ gcc_assert (POINTER_TYPE_P (ptype));
+ if (TREE_CODE (ptype) == REFERENCE_TYPE)
+ ptype = build_pointer_type (TREE_TYPE (ptype));
+ tree kind = build_int_cst (ptype, ckind);
tree align = build_int_cst (pointer_sized_int_node, mina);
tree call
= build_call_expr_internal_loc (loc, IFN_UBSAN_NULL, void_type_node,
@@ -453,7 +461,7 @@ ubsan_maybe_instrument_reference (tree stmt)
{
tree op = TREE_OPERAND (stmt, 0);
op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
- TREE_TYPE (TREE_TYPE (stmt)),
+ TREE_TYPE (stmt),
UBSAN_REF_BINDING);
if (op)
TREE_OPERAND (stmt, 0) = op;
@@ -471,7 +479,7 @@ ubsan_maybe_instrument_member_call (tree stmt, bool is_ctor)
|| !POINTER_TYPE_P (TREE_TYPE (op)))
return;
op = ubsan_maybe_instrument_reference_or_call (EXPR_LOCATION (stmt), op,
- TREE_TYPE (TREE_TYPE (op)),
+ TREE_TYPE (op),
is_ctor ? UBSAN_CTOR_CALL
: UBSAN_MEMBER_CALL);
if (op)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ad651fa7830..49f497396f7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2014-11-18 Jakub Jelinek <jakub@redhat.com>
+ PR sanitizer/63813
+ * g++.dg/ubsan/pr63813.C: New test.
+
PR tree-optimization/61042
* gcc.c-torture/compile/pr61042.c: New test.
diff --git a/gcc/testsuite/g++.dg/ubsan/pr63813.C b/gcc/testsuite/g++.dg/ubsan/pr63813.C
new file mode 100644
index 00000000000..6ca5b2d18c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/pr63813.C
@@ -0,0 +1,12 @@
+// PR sanitizer/63813
+// { dg-do compile }
+// { dg-options "-fsanitize=undefined -O1" }
+
+struct A {};
+struct B { long foo () const; A &bar () const; };
+
+A &
+B::bar () const
+{
+ return *reinterpret_cast <A *> (foo ());
+}