Commit 4f4e722e by Richard Guenther Committed by Richard Biener

re PR middle-end/41006 (verify_stmts failed: error: non-trivial conversion at assignment)

2009-08-10  Richard Guenther  <rguenther@suse.de>

	PR middle-end/41006
	* tree-ssa.c (useless_type_conversion_p_1): Fold into ...
	(useless_type_conversion_p): ... here.  Require pointer targets
	to be compatible.

	* gcc.c-torture/compile/pr41006-1.c: New testcase.
	* gcc.c-torture/compile/pr41006-2.c: Likewise.

From-SVN: r150621
parent 727e8544
2009-08-10 Richard Guenther <rguenther@suse.de>
PR middle-end/41006
* tree-ssa.c (useless_type_conversion_p_1): Fold into ...
(useless_type_conversion_p): ... here. Require pointer targets
to be compatible.
2009-08-10 Dodji Seketeli <dodji@redhat.com>
PR c++/40866
......
2009-08-10 Richard Guenther <rguenther@suse.de>
PR middle-end/41006
* gcc.c-torture/compile/pr41006-1.c: New testcase.
* gcc.c-torture/compile/pr41006-2.c: Likewise.
2009-08-10 Janus Weil <janus@gcc.gnu.org>
PR fortran/40940
......
typedef int (*FARPROC)();
typedef int (*LPFN_ACCEPTEX)(void*);
static LPFN_ACCEPTEX acceptex_fn;
int xWSAIoctl(void*);
static void get_fn(FARPROC* fn)
{
FARPROC func;
if (!xWSAIoctl( &func))
*fn = func;
}
void get_fn_pointers()
{
get_fn((FARPROC*)&acceptex_fn);
}
typedef int *FARPROC;
static int * __restrict__ acceptex_fn;
int xWSAIoctl(void*);
static void get_fn(FARPROC* fn)
{
FARPROC func;
if (!xWSAIoctl( &func))
*fn = func;
}
void get_fn_pointers()
{
get_fn((FARPROC*)&acceptex_fn);
}
......@@ -844,10 +844,31 @@ delete_tree_ssa (void)
redirect_edge_var_map_destroy ();
}
/* Helper function for useless_type_conversion_p. */
/* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a
useless type conversion, otherwise return false.
static bool
useless_type_conversion_p_1 (tree outer_type, tree inner_type)
This function implicitly defines the middle-end type system. With
the notion of 'a < b' meaning that useless_type_conversion_p (a, b)
holds and 'a > b' meaning that useless_type_conversion_p (b, a) holds,
the following invariants shall be fulfilled:
1) useless_type_conversion_p is transitive.
If a < b and b < c then a < c.
2) useless_type_conversion_p is not symmetric.
From a < b does not follow a > b.
3) Types define the available set of operations applicable to values.
A type conversion is useless if the operations for the target type
is a subset of the operations for the source type. For example
casts to void* are useless, casts from void* are not (void* can't
be dereferenced or offsetted, but copied, hence its set of operations
is a strict subset of that of all other data pointer types). Casts
to const T* are useless (can't be written to), casts from const T*
to T* are not. */
bool
useless_type_conversion_p (tree outer_type, tree inner_type)
{
/* Do the following before stripping toplevel qualifiers. */
if (POINTER_TYPE_P (inner_type)
......@@ -909,6 +930,16 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type)
else if (POINTER_TYPE_P (inner_type)
&& POINTER_TYPE_P (outer_type))
{
/* If the outer type is (void *) or a pointer to an incomplete
record type, then the conversion is not necessary. */
if (VOID_TYPE_P (TREE_TYPE (outer_type))
|| (AGGREGATE_TYPE_P (TREE_TYPE (outer_type))
&& TREE_CODE (TREE_TYPE (outer_type)) != ARRAY_TYPE
&& (TREE_CODE (TREE_TYPE (outer_type))
== TREE_CODE (TREE_TYPE (inner_type)))
&& !COMPLETE_TYPE_P (TREE_TYPE (outer_type))))
return true;
/* Don't lose casts between pointers to volatile and non-volatile
qualified types. Doing so would result in changing the semantics
of later accesses. For function types the volatile qualifier
......@@ -938,9 +969,12 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type)
/* Otherwise pointers/references are equivalent if their pointed
to types are effectively the same. We can strip qualifiers
on pointed-to types for further comparison, which is done in
the callee. */
return useless_type_conversion_p_1 (TREE_TYPE (outer_type),
TREE_TYPE (inner_type));
the callee. Note we have to use true compatibility here
because addresses are subject to propagation into dereferences
and thus might get the original type exposed which is equivalent
to a reverse conversion. */
return types_compatible_p (TREE_TYPE (outer_type),
TREE_TYPE (inner_type));
}
/* Recurse for complex types. */
......@@ -1083,48 +1117,6 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type)
return false;
}
/* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a
useless type conversion, otherwise return false.
This function implicitly defines the middle-end type system. With
the notion of 'a < b' meaning that useless_type_conversion_p (a, b)
holds and 'a > b' meaning that useless_type_conversion_p (b, a) holds,
the following invariants shall be fulfilled:
1) useless_type_conversion_p is transitive.
If a < b and b < c then a < c.
2) useless_type_conversion_p is not symmetric.
From a < b does not follow a > b.
3) Types define the available set of operations applicable to values.
A type conversion is useless if the operations for the target type
is a subset of the operations for the source type. For example
casts to void* are useless, casts from void* are not (void* can't
be dereferenced or offsetted, but copied, hence its set of operations
is a strict subset of that of all other data pointer types). Casts
to const T* are useless (can't be written to), casts from const T*
to T* are not. */
bool
useless_type_conversion_p (tree outer_type, tree inner_type)
{
/* If the outer type is (void *) or a pointer to an incomplete record type,
then the conversion is not necessary.
We have to make sure to not apply this while recursing though. */
if (POINTER_TYPE_P (inner_type)
&& POINTER_TYPE_P (outer_type)
&& (VOID_TYPE_P (TREE_TYPE (outer_type))
|| (AGGREGATE_TYPE_P (TREE_TYPE (outer_type))
&& TREE_CODE (TREE_TYPE (outer_type)) != ARRAY_TYPE
&& (TREE_CODE (TREE_TYPE (outer_type))
== TREE_CODE (TREE_TYPE (inner_type)))
&& !COMPLETE_TYPE_P (TREE_TYPE (outer_type)))))
return true;
return useless_type_conversion_p_1 (outer_type, inner_type);
}
/* Return true if a conversion from either type of TYPE1 and TYPE2
to the other is not required. Otherwise return false. */
......
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