diff options
author | Marek Polacek <polacek@redhat.com> | 2014-01-23 19:18:49 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2014-01-23 19:18:49 +0000 |
commit | f04dda3093541436d9ebd3194761ff8199c5ac79 (patch) | |
tree | 9a9f80e007c4a37b50f0d20171385546900224a6 | |
parent | 789eadcd54ffe62037461a4a22c2737ad9cbd01e (diff) | |
download | gcc-f04dda3093541436d9ebd3194761ff8199c5ac79.zip gcc-f04dda3093541436d9ebd3194761ff8199c5ac79.tar.gz gcc-f04dda3093541436d9ebd3194761ff8199c5ac79.tar.bz2 |
re PR c/58346 (ICE with SIGFPE at -O1 and above on x86_64-linux-gnu (affecting trunk, 4.8, 4.7, and 4.6))
PR c/58346
c-family/
* c-common.c (pointer_to_zero_sized_aggr_p): New function.
* c-common.h: Declare it.
cp/
* typeck.c (pointer_diff): Give an error on arithmetic on pointer to
an empty aggregate.
c/
* c-typeck.c (pointer_diff): Give an error on arithmetic on pointer to
an empty aggregate.
testsuite/
* c-c++-common/pr58346-1.c: New test.
* c-c++-common/pr58346-2.c: New test.
* c-c++-common/pr58346-3.c: New test.
From-SVN: r207004
-rw-r--r-- | gcc/c-family/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 11 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 1 | ||||
-rw-r--r-- | gcc/c/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 3 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr58346-1.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr58346-2.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr58346-3.c | 16 |
11 files changed, 96 insertions, 0 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 3198558..cba9f4e 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2014-01-23 Marek Polacek <polacek@redhat.com> + + PR c/58346 + * c-common.c (pointer_to_zero_sized_aggr_p): New function. + * c-common.h: Declare it. + 2014-01-20 Eric Botcazou <ebotcazou@adacore.com> * c-ada-spec.h (dump_ada_specs): Revert prototype change. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 35958ea..0912801 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -11823,4 +11823,15 @@ cxx_fundamental_alignment_p (unsigned align) TYPE_ALIGN (long_double_type_node))); } +/* Return true if T is a pointer to a zero-sized aggregate. */ + +bool +pointer_to_zero_sized_aggr_p (tree t) +{ + if (!POINTER_TYPE_P (t)) + return false; + t = TREE_TYPE (t); + return (TYPE_SIZE (t) && integer_zerop (TYPE_SIZE (t))); +} + #include "gt-c-family-c-common.h" diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 7e3ece6..dab0b8c 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -789,6 +789,7 @@ extern bool keyword_is_storage_class_specifier (enum rid); extern bool keyword_is_type_qualifier (enum rid); extern bool keyword_is_decl_specifier (enum rid); extern bool cxx_fundamental_alignment_p (unsigned); +extern bool pointer_to_zero_sized_aggr_p (tree); #define c_sizeof(LOC, T) c_sizeof_or_alignof_type (LOC, T, true, false, 1) #define c_alignof(LOC, T) c_sizeof_or_alignof_type (LOC, T, false, false, 1) diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 237ac1a..4088912 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,5 +1,11 @@ 2014-01-23 Marek Polacek <polacek@redhat.com> + PR c/58346 + * c-typeck.c (pointer_diff): Give an error on arithmetic on pointer to + an empty aggregate. + +2014-01-23 Marek Polacek <polacek@redhat.com> + PR c/59871 * c-typeck.c (build_compound_expr): Warn even for right-hand operand of a comma expression. diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 781d4df..77f3bdd 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -3536,6 +3536,9 @@ pointer_diff (location_t loc, tree op0, tree op1) /* This generates an error if op0 is pointer to incomplete type. */ op1 = c_size_in_bytes (target_type); + if (pointer_to_zero_sized_aggr_p (TREE_TYPE (orig_op1))) + error_at (loc, "arithmetic on pointer to an empty aggregate"); + /* Divide by the size, in easiest possible way. */ result = fold_build2_loc (loc, EXACT_DIV_EXPR, inttype, op0, convert (inttype, op1)); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2428204..aee3fcf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2014-01-23 Marek Polacek <polacek@redhat.com> + + PR c/58346 + * typeck.c (pointer_diff): Give an error on arithmetic on pointer to + an empty aggregate. + 2014-01-23 Jason Merrill <jason@redhat.com> PR c++/55189 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 84e287e..9cd6a95 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5043,6 +5043,14 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain) return error_mark_node; } + if (pointer_to_zero_sized_aggr_p (TREE_TYPE (op1))) + { + if (complain & tf_error) + error ("arithmetic on pointer to an empty aggregate"); + else + return error_mark_node; + } + op1 = (TYPE_PTROB_P (ptrtype) ? size_in_bytes (target_type) : integer_one_node); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3857078..f3d8d3a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2014-01-23 Marek Polacek <polacek@redhat.com> + PR c/58346 + * c-c++-common/pr58346-1.c: New test. + * c-c++-common/pr58346-2.c: New test. + * c-c++-common/pr58346-3.c: New test. + +2014-01-23 Marek Polacek <polacek@redhat.com> + PR c/59871 * gcc.dg/20020220-2.c: Adjust dg-warning message. * gcc.dg/pr59871.c: New test. diff --git a/gcc/testsuite/c-c++-common/pr58346-1.c b/gcc/testsuite/c-c++-common/pr58346-1.c new file mode 100644 index 0000000..371fcf4 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr58346-1.c @@ -0,0 +1,24 @@ +/* PR c/58346 */ +/* { dg-do compile } */ + +struct U { +#ifdef __cplusplus + char a[0]; +#endif +}; +static struct U b[6]; +static struct U *u1, *u2; + +int +foo (struct U *p, struct U *q) +{ + return q - p; /* { dg-error "arithmetic on pointer to an empty aggregate" } */ +} + +void +bar (void) +{ + __PTRDIFF_TYPE__ d = u1 - u2; /* { dg-error "arithmetic on pointer to an empty aggregate" } */ + __asm volatile ("" : "+g" (d)); + foo (&b[0], &b[4]); +} diff --git a/gcc/testsuite/c-c++-common/pr58346-2.c b/gcc/testsuite/c-c++-common/pr58346-2.c new file mode 100644 index 0000000..195060e --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr58346-2.c @@ -0,0 +1,8 @@ +/* PR c/58346 */ +/* { dg-do compile } */ + +__PTRDIFF_TYPE__ +foo (int p[3][0], int q[3][0]) +{ + return p - q; /* { dg-error "arithmetic on pointer to an empty aggregate" } */ +} diff --git a/gcc/testsuite/c-c++-common/pr58346-3.c b/gcc/testsuite/c-c++-common/pr58346-3.c new file mode 100644 index 0000000..41627ed --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr58346-3.c @@ -0,0 +1,16 @@ +/* PR c/58346 */ +/* { dg-do compile } */ + +void +foo (void) +{ + __PTRDIFF_TYPE__ d; + const int i = 0; + int a1[2][0], a2[2][0]; + int b1[3][i], b2[4][i]; + d = a1 - a2; /* { dg-error "arithmetic on pointer to an empty aggregate" } */ + __asm volatile ("" : "+g" (d)); + /* No error here for C. */ + d = b1 - b2; /* { dg-error "arithmetic on pointer to an empty aggregate" "" { target c++ } } */ + __asm volatile ("" : "+g" (d)); +} |