aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2009-11-03 10:44:36 +0000
committerDodji Seketeli <dodji@gcc.gnu.org>2009-11-03 11:44:36 +0100
commit61c3c49040b532d94e2371b0049447561ee00319 (patch)
treec87dd211761661c2a4d2e74640e5d6de9bb6613b /gcc/c-common.c
parent9d1a984546a59678be0a5196a87e649f5551dcc7 (diff)
downloadgcc-61c3c49040b532d94e2371b0049447561ee00319.zip
gcc-61c3c49040b532d94e2371b0049447561ee00319.tar.gz
gcc-61c3c49040b532d94e2371b0049447561ee00319.tar.bz2
re PR c++/38699 (ICE using offsetof with pointer and array accesses)
Fix PR c++/38699 gcc/ChangeLog: PR c++/38699 * c-common.c (fold_offsetof_1): Issue errors when the member designator of the offsetoff expression is not legitimate. gcc/testsuite/ChangeLog: * c-c++-common/dfp/builtin-offsetof.c: New test. * g++.dg/other/offsetof6.C: Likewise. From-SVN: r153843
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 8b85f66..91de41c 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -8356,15 +8356,14 @@ fold_offsetof_1 (tree expr, tree stop_ref)
error ("cannot apply %<offsetof%> when %<operator[]%> is overloaded");
return error_mark_node;
- case INTEGER_CST:
- gcc_assert (integer_zerop (expr));
- return size_zero_node;
-
case NOP_EXPR:
case INDIRECT_REF:
- base = fold_offsetof_1 (TREE_OPERAND (expr, 0), stop_ref);
- gcc_assert (base == error_mark_node || base == size_zero_node);
- return base;
+ if (!integer_zerop (TREE_OPERAND (expr, 0)))
+ {
+ error ("cannot apply %<offsetof%> to a non constant address");
+ return error_mark_node;
+ }
+ return size_zero_node;
case COMPONENT_REF:
base = fold_offsetof_1 (TREE_OPERAND (expr, 0), stop_ref);
@@ -8397,6 +8396,16 @@ fold_offsetof_1 (tree expr, tree stop_ref)
}
t = convert (sizetype, t);
off = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (TREE_TYPE (expr)), t);
+
+ /* Check if the offset goes beyond the upper bound of the array. */
+ {
+ tree nelts = array_type_nelts (TREE_TYPE (TREE_OPERAND (expr, 0)));
+ HOST_WIDE_INT index = int_cst_value (t);
+ if (index > int_cst_value (nelts))
+ warning (OPT_Warray_bounds,
+ "index %ld denotes an offset greater than size of %qT",
+ index, TREE_TYPE (TREE_OPERAND (expr, 0)));
+ }
break;
case COMPOUND_EXPR: