Commit 9560cbde by Mark Mitchell Committed by Mark Mitchell

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
parent bf95bc65
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> 2005-03-02 Hans-Peter Nilsson <hp@axis.com>
* config/cris/cris.md ("return"): Remove epilogue delay list * config/cris/cris.md ("return"): Remove epilogue delay list
......
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> 2005-03-02 Joseph S. Myers <joseph@codesourcery.com>
PR c/8927 PR c/8927
......
// PR c++/19916
// { dg-do run }
struct S {
char k;
};
char const volatile S::* const p01 = &S::k;
int main(void)
{
return 0;
}
...@@ -3523,63 +3523,61 @@ initializer_constant_valid_p (tree value, tree endtype) ...@@ -3523,63 +3523,61 @@ initializer_constant_valid_p (tree value, tree endtype)
case CONVERT_EXPR: case CONVERT_EXPR:
case NOP_EXPR: case NOP_EXPR:
/* Allow conversions between pointer types. */ {
if (POINTER_TYPE_P (TREE_TYPE (value)) tree src;
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) tree src_type;
return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); tree dest_type;
/* Allow conversions between real types. */ src = TREE_OPERAND (value, 0);
if (FLOAT_TYPE_P (TREE_TYPE (value)) src_type = TREE_TYPE (src);
&& FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) dest_type = TREE_TYPE (value);
return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
/* Allow conversions between pointer types, floating-point
/* Allow length-preserving conversions between integer types. */ types, and offset types. */
if (INTEGRAL_TYPE_P (TREE_TYPE (value)) if ((POINTER_TYPE_P (dest_type) && POINTER_TYPE_P (src_type))
&& INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))) || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type))
&& (TYPE_PRECISION (TREE_TYPE (value)) || (TREE_CODE (dest_type) == OFFSET_TYPE
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) && TREE_CODE (src_type) == OFFSET_TYPE))
return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); return initializer_constant_valid_p (src, endtype);
/* Allow conversions between other integer types only if /* Allow length-preserving conversions between integer types. */
explicit value. */ if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type)
if (INTEGRAL_TYPE_P (TREE_TYPE (value)) && (TYPE_PRECISION (dest_type) == TYPE_PRECISION (src_type)))
&& INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) return initializer_constant_valid_p (src, endtype);
{
tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0), /* Allow conversions between other integer types only if
endtype); explicit value. */
if (inner == null_pointer_node) if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type))
return null_pointer_node; {
break; 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. */ /* Allow (int) &foo provided int is as wide as a pointer. */
if (INTEGRAL_TYPE_P (TREE_TYPE (value)) if (INTEGRAL_TYPE_P (dest_type) && POINTER_TYPE_P (src_type)
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))) && (TYPE_PRECISION (dest_type) >= TYPE_PRECISION (src_type)))
&& (TYPE_PRECISION (TREE_TYPE (value)) return initializer_constant_valid_p (src, endtype);
>= 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 conversions to struct or union types if the value /* Likewise conversions from int to pointers, but also allow
inside is okay. */ conversions from 0. */
if (TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE if ((POINTER_TYPE_P (dest_type)
|| TREE_CODE (TREE_TYPE (value)) == UNION_TYPE) || TREE_CODE (dest_type) == OFFSET_TYPE)
return initializer_constant_valid_p (TREE_OPERAND (value, 0), && INTEGRAL_TYPE_P (src_type))
endtype); {
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; break;
case PLUS_EXPR: case PLUS_EXPR:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment