From 3f85558f2472d16219674988f4bd850bc285911b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 15 Sep 2001 17:48:52 -0700 Subject: [PATCH] * c-typeck.c (comptypes): Handle zero-length arrays properly. From-SVN: r45641 --- gcc/ChangeLog | 4 ++++ gcc/c-typeck.c | 25 +++++++++++++++----- gcc/testsuite/gcc.dg/array-5.c | 42 ++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/array-5.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d30dcddafa..e36dcc210a3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2001-09-15 Richard Henderson + + * c-typeck.c (comptypes): Handle zero-length arrays properly. + 2001-09-15 Roman Lechtchinsky * c-common.c (c_promoting_integer_type_p): Handle ?Imode types. diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 9d2c8f4d1f8..3298062e8d7 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -505,6 +505,8 @@ comptypes (type1, type2) { tree d1 = TYPE_DOMAIN (t1); tree d2 = TYPE_DOMAIN (t2); + bool d1_variable, d2_variable; + bool d1_zero, d2_zero; val = 1; /* Target types must match incl. qualifiers. */ @@ -513,14 +515,25 @@ comptypes (type1, type2) return 0; /* Sizes must match unless one is missing or variable. */ - if (d1 == 0 || d2 == 0 || d1 == d2 - || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST - || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST - || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST - || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST) + if (d1 == 0 || d2 == 0 || d1 == d2) break; - if (! tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)) + d1_zero = ! TYPE_MAX_VALUE (d1); + d2_zero = ! TYPE_MAX_VALUE (d2); + + d1_variable = (! d1_zero + && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST + || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST)); + d2_variable = (! d2_zero + && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST + || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)); + + if (d1_variable || d2_variable) + break; + if (d1_zero && d2_zero) + break; + if (d1_zero || d2_zero + || ! tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)) || ! tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2))) val = 0; diff --git a/gcc/testsuite/gcc.dg/array-5.c b/gcc/testsuite/gcc.dg/array-5.c new file mode 100644 index 00000000000..f5321e45238 --- /dev/null +++ b/gcc/testsuite/gcc.dg/array-5.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +/* Check compatibility of array declarations. */ + +/* Incomplete decl matches. */ +extern char arr0[]; +char arr0[1]; + +/* Two integral expressions must be the same. Note that 0 is + a gcc extension, but it should work like any other constant. */ +extern char arr1[1]; +char arr1[1]; +extern char arr2[0]; +char arr2[0]; +extern char arr3[0]; /* { dg-error "previous declaration" } */ +char arr3[1]; /* { dg-error "conflicting types" } */ + +/* Variable size matches. */ +void func(int n, int m) +{ + /* The next two are from the example in c99 6.7.5.2/9. */ + { + /* Invalid: not compatible because 4 != 6. */ + int a[n][6][m]; + int (*p)[4][n+1]; + p = a; /* { dg-error "incompatible" } */ + } + { + /* Compatible, but defined behavior only if n == 6 and m == n+1. */ + int c[n][n][6][m]; + int (*r)[n][n][n+1]; + r = c; + } + { + /* Compatible, but undefined behavior; (2, 2) is not a constant + expression, and thus A is a VLA. */ + int a[(2, 2)]; + int (*p)[3]; + p = a; /* { dg-bogus "incompatible" "bad vla handling" { xfail *-*-* } } */ + } +} -- 2.30.2