On Thu, Apr 26, 2012 at 3:12 PM, Georg-Johann Lay <a...@gjlay.de> wrote: > Richard Guenther wrote: >> Georg-Johann Lay wrote: >>> Georg-Johann Lay wrote: >>>> Richard Guenther wrote: >>>>> Georg-Johann Lay wrote: >>>>>> [...] >>>>>> >>>>>> http://gcc.gnu.org/PR51527 >>>>>> >>>>>> It works with 4.8 trunk but crashes with 4.7. >>>>>> Did not yet track what changes made it work with 4.8, though. >>>>>> Unfortunately, noone remembers :-( >>>>>> >>>>>> http://gcc.gnu.org/ml/gcc/2012-03/msg00440.html >>>>> I have done changes in this area, trying to remove the type_for_size >>>>> langhook. >>>>> >>>>> Richard. >>>> One apparent change is tree.c:signed_or_unsigned_type_for >>>> >>>> that changed [...] at 2012-03-12 >>>> >>>> http://gcc.gnu.org/viewcvs?view=revision&revision=185226 >>>> >>>> Is this appropriate to backport? >> >> No, it's not. >> >>>> Or is the preferred solution to override lang_hooks.types.type_for_size in >>>> the >>>> backend, if applicable? >> >> Neither. It is a "lang"-hook, not a target-hook after all. >> >> I already told you what the right fix is - the callers of >> type_for_size have to cater >> for the returned type to be of different precision. Btw, I already see it >> does >> >> /* But now perhaps TYPEX is as wide as INPREC. >> In that case, do nothing special here. >> (Otherwise would recurse infinitely in convert. */ >> if (TYPE_PRECISION (typex) != inprec) >> >> Richard > > Would you help me with the code? It's almost impossible to understand the > convert stuff for a noob. I tried TARGET_CONVERT_TO_TYPE > > static tree > avr_convert_to_type (tree type, tree expr) > { > tree xtype = TREE_TYPE (expr); > > /* convert enters infinite recursion for __int24 -> unsigned long > convertsions. */ > > if (/* From __int24 ... */ > TREE_CODE (xtype) == INTEGER_TYPE > && TYPE_PRECISION (xtype) == 24 > && !TYPE_UNSIGNED (xtype) > /* ... to unsigned long. */ > && TREE_CODE (type) == INTEGER_TYPE > && TYPE_PRECISION (type) > 24 > && TYPE_UNSIGNED (type)) > { > /* Perform an intermediate conversion: > __int24 -> long -> unsigned long */ > > /* Signed variant of type */ > tree stype = lang_hooks.types.type_for_mode (TYPE_MODE (type), 0); > > expr = convert (stype, expr); > // expr = build1 (CONVERT_EXPR, stype, expr); > expr = build1 (NOP_EXPR, type, expr); > > return expr; > } > > return NULL_TREE; > } > > #undef TARGET_CONVERT_TO_TYPE > #define TARGET_CONVERT_TO_TYPE avr_convert_to_type > > > but with no avail. The explicit, intermediate conversion from __int24 to long > does not prevent the infinite recursion.
I think the fix would be sth like Index: gcc/convert.c =================================================================== --- gcc/convert.c (revision 186871) +++ gcc/convert.c (working copy) @@ -769,6 +769,7 @@ convert_to_integer (tree type, tree expr (Otherwise would recurse infinitely in convert. */ if (TYPE_PRECISION (typex) != inprec) { + tree otypex = typex; /* Don't do unsigned arithmetic where signed was wanted, or vice versa. Exception: if both of the original operands were @@ -806,10 +807,11 @@ convert_to_integer (tree type, tree expr typex = unsigned_type_for (typex); else typex = signed_type_for (typex); - return convert (type, - fold_build2 (ex_form, typex, - convert (typex, arg0), - convert (typex, arg1))); + if (TYPE_PRECISION (otypex) == TYPE_PRECISION (typex)) + return convert (type, + fold_build2 (ex_form, typex, + convert (typex, arg0), + convert (typex, arg1))); } } } > Johann >