https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99122

--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #2)
> Another, still undefined, but perhaps slightly less so, testcase is:
> static int foo ();
> 
> int
> bar (int n)
> {
>   struct S { char a[n]; } x;
>   __builtin_memset (x.a, 0, n);
>   return foo (n, x);
> }
> 
> static inline int
> foo (int n, struct T { char a[n]; } b)
> {
>   int r = 0, i;
>   for (i = 0; i < n; i++)
>     r += b.a[i];
>   return r;
> }
> 
> I wonder if the easiest fix isn't just to disable inlining if any of the
> arguments has variable length.  The inliner seems to be clearly unprepared
> to handle that.  VLAs when passed are passed as pointers to the elements, so
> it is only about variable length structures or if some front-end would pass
> arrays as arrays and not as pointers.

So with fixing the original and this case by simply not trying to be clever
when setting up the parameter on mismatches like with

@@ -3418,7 +3421,9 @@ force_value_to_type (tree type, tree value)
      Still if we end up with truly mismatched types here, fall back
      to using a VIEW_CONVERT_EXPR or a literal zero to not leak invalid
      GIMPLE to the following passes.  */
-  if (!is_gimple_reg_type (TREE_TYPE (value))
+  if (TREE_CODE (value) == WITH_SIZE_EXPR)
+    return error_mark_node;
+  else if (!is_gimple_reg_type (TREE_TYPE (value))
           || TYPE_SIZE (type) == TYPE_SIZE (TREE_TYPE (value)))
     return fold_build1 (VIEW_CONVERT_EXPR, type, value);
   else

the ICEs are gone but the comment#2 testcase has a local var added
which cannot be assembled because we do

  /* Make an equivalent VAR_DECL.  Note that we must NOT remap the type
     here since the type of this decl must be visible to the calling
     function.  */
  var = copy_decl_to_var (p, id);

and obviously the sizes are not set up correctly for the caller.  That's
one complication - we have to massage the WITH_SIZE_EXPR size back to
the TYPE because the VLA bounds are not passed explicitely.  In a nested
function context those are transfered via the static chain so it should
work there but there the C FE marks the functions as not inlineable
(but IIRC for the unsupported return value handling).

Which makes me go back to IPA summary analysis, looking for the place
we can disable inlining of a certain cgraph edge based on call stmts
using WITH_SIZE_EXPR arguments.

Reply via email to