diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-03-02 17:13:09 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-03-02 17:13:09 +0000 |
commit | 9560cbde527ea02aff5e5e8cb54bc605c000690e (patch) | |
tree | 80fbf71bf5886e6e3f2c8d0c427f13ed3863b027 | |
parent | bf95bc65e075027af69946f8536930132a8f7520 (diff) | |
download | gcc-9560cbde527ea02aff5e5e8cb54bc605c000690e.zip gcc-9560cbde527ea02aff5e5e8cb54bc605c000690e.tar.gz gcc-9560cbde527ea02aff5e5e8cb54bc605c000690e.tar.bz2 |
re PR c++/19916 (Segmentation fault in __static_initialization_and_destruction_0)
PR c++/19916
* varasm.c (initializer_constant_valid_p): Allow conversions
between OFFSET_TYPEs. Tidy.
PR c++/19916
* g++.dg/init/ptrmem2.C: New test.
From-SVN: r95787
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/ptrmem2.C | 12 | ||||
-rw-r--r-- | gcc/varasm.c | 108 |
4 files changed, 76 insertions, 55 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fc3b356..3f8b31e2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-03-02 Mark Mitchell <mark@codesourcery.com> + + PR c++/19916 + * varasm.c (initializer_constant_valid_p): Allow conversions + between OFFSET_TYPEs. Tidy. + 2005-03-02 Hans-Peter Nilsson <hp@axis.com> * config/cris/cris.md ("return"): Remove epilogue delay list diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d725343..5351064 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-03-02 Mark Mitchell <mark@codesourcery.com> + + PR c++/19916 + * g++.dg/init/ptrmem2.C: New test. + 2005-03-02 Joseph S. Myers <joseph@codesourcery.com> PR c/8927 diff --git a/gcc/testsuite/g++.dg/init/ptrmem2.C b/gcc/testsuite/g++.dg/init/ptrmem2.C new file mode 100644 index 0000000..54b6921 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/ptrmem2.C @@ -0,0 +1,12 @@ +// PR c++/19916 +// { dg-do run } + +struct S { + char k; +}; + +char const volatile S::* const p01 = &S::k; +int main(void) +{ + return 0; +} diff --git a/gcc/varasm.c b/gcc/varasm.c index 12ab1b7..29ce048 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -3523,63 +3523,61 @@ initializer_constant_valid_p (tree value, tree endtype) case CONVERT_EXPR: case NOP_EXPR: - /* Allow conversions between pointer types. */ - if (POINTER_TYPE_P (TREE_TYPE (value)) - && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow conversions between real types. */ - if (FLOAT_TYPE_P (TREE_TYPE (value)) - && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow length-preserving conversions between integer types. */ - if (INTEGRAL_TYPE_P (TREE_TYPE (value)) - && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))) - && (TYPE_PRECISION (TREE_TYPE (value)) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow conversions between other integer types only if - explicit value. */ - if (INTEGRAL_TYPE_P (TREE_TYPE (value)) - && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) - { - tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - if (inner == null_pointer_node) - return null_pointer_node; - break; - } + { + tree src; + tree src_type; + tree dest_type; + + src = TREE_OPERAND (value, 0); + src_type = TREE_TYPE (src); + dest_type = TREE_TYPE (value); + + /* Allow conversions between pointer types, floating-point + types, and offset types. */ + if ((POINTER_TYPE_P (dest_type) && POINTER_TYPE_P (src_type)) + || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type)) + || (TREE_CODE (dest_type) == OFFSET_TYPE + && TREE_CODE (src_type) == OFFSET_TYPE)) + return initializer_constant_valid_p (src, endtype); + + /* Allow length-preserving conversions between integer types. */ + if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type) + && (TYPE_PRECISION (dest_type) == TYPE_PRECISION (src_type))) + return initializer_constant_valid_p (src, endtype); + + /* Allow conversions between other integer types only if + explicit value. */ + if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type)) + { + tree inner = initializer_constant_valid_p (src, endtype); + if (inner == null_pointer_node) + return null_pointer_node; + break; + } - /* Allow (int) &foo provided int is as wide as a pointer. */ - if (INTEGRAL_TYPE_P (TREE_TYPE (value)) - && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))) - && (TYPE_PRECISION (TREE_TYPE (value)) - >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - - /* Likewise conversions from int to pointers, but also allow - conversions from 0. */ - if ((POINTER_TYPE_P (TREE_TYPE (value)) - || TREE_CODE (TREE_TYPE (value)) == OFFSET_TYPE) - && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) - { - if (integer_zerop (TREE_OPERAND (value, 0))) - return null_pointer_node; - else if (TYPE_PRECISION (TREE_TYPE (value)) - <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - } + /* Allow (int) &foo provided int is as wide as a pointer. */ + if (INTEGRAL_TYPE_P (dest_type) && POINTER_TYPE_P (src_type) + && (TYPE_PRECISION (dest_type) >= TYPE_PRECISION (src_type))) + return initializer_constant_valid_p (src, endtype); - /* Allow conversions to struct or union types if the value - inside is okay. */ - if (TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE - || TREE_CODE (TREE_TYPE (value)) == UNION_TYPE) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); + /* Likewise conversions from int to pointers, but also allow + conversions from 0. */ + if ((POINTER_TYPE_P (dest_type) + || TREE_CODE (dest_type) == OFFSET_TYPE) + && INTEGRAL_TYPE_P (src_type)) + { + if (integer_zerop (src)) + return null_pointer_node; + else if (TYPE_PRECISION (dest_type) <= TYPE_PRECISION (src_type)) + return initializer_constant_valid_p (src, endtype); + } + + /* Allow conversions to struct or union types if the value + inside is okay. */ + if (TREE_CODE (dest_type) == RECORD_TYPE + || TREE_CODE (dest_type) == UNION_TYPE) + return initializer_constant_valid_p (src, endtype); + } break; case PLUS_EXPR: |