re PR c/70093 (Instancing function with VM return type cases internal compiler error...
authorMarek Polacek <polacek@redhat.com>
Wed, 16 Mar 2016 15:51:47 +0000 (15:51 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 16 Mar 2016 15:51:47 +0000 (15:51 +0000)
PR c/70093
* c-typeck.c (build_function_call_vec): Create a TARGET_EXPR for
nested functions returning VM types.

* cgraphunit.c (cgraph_node::expand_thunk): Also build call to the
function being thunked if the result type doesn't have fixed size.
* gimplify.c (gimplify_modify_expr): Also set LHS if the result type
doesn't have fixed size.

* gcc.dg/nested-func-10.c: New test.
* gcc.dg/nested-func-9.c: New test.

From-SVN: r234259

gcc/ChangeLog
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cgraphunit.c
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/nested-func-10.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/nested-func-9.c [new file with mode: 0644]

index d1dd80f1761268911aa588360140c774296e404e..0af222ed70f61577bd31fea0f23d29a0e92ef77d 100644 (file)
@@ -1,3 +1,11 @@
+2016-03-16  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70093
+       * cgraphunit.c (cgraph_node::expand_thunk): Also build call to the
+       function being thunked if the result type doesn't have fixed size.
+       * gimplify.c (gimplify_modify_expr): Also set LHS if the result type
+       doesn't have fixed size.
+
 2016-03-16  Bin Cheng  <bin.cheng@arm.com>
 
        * tree-vect-loop.c (vect_analyze_loop_2): Fix wrong dump info by
index 95fde9fb0575e9a0184818ea3611c72234c500ff..fa657e588c082cad2fcde7a1b5898aa9f6f25e64 100644 (file)
@@ -1,3 +1,9 @@
+2016-03-16  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70093
+       * c-typeck.c (build_function_call_vec): Create a TARGET_EXPR for
+       nested functions returning VM types.
+
 2016-03-09  Cesar Philippidis  <cesar@codesourcery.com>
 
        * c-parser.c (c_parser_oacc_loop): Update cclauses and clauses
index 6aa0f03dabe83c07c614d8c1ebe60fa4af1e8d7e..de9d4657799906a0b28ad8c48e106107584d4af5 100644 (file)
@@ -3068,6 +3068,16 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
     result = build_call_array_loc (loc, TREE_TYPE (fntype),
                                   function, nargs, argarray);
 
+  /* In this improbable scenario, a nested function returns a VM type.
+     Create a TARGET_EXPR so that the call always has a LHS, much as
+     what the C++ FE does for functions returning non-PODs.  */
+  if (variably_modified_type_p (TREE_TYPE (fntype), NULL_TREE))
+    {
+      tree tmp = create_tmp_var_raw (TREE_TYPE (fntype));
+      result = build4 (TARGET_EXPR, TREE_TYPE (fntype), tmp, result,
+                      NULL_TREE, NULL_TREE);
+    }
+
   if (VOID_TYPE_P (TREE_TYPE (result)))
     {
       if (TYPE_QUALS (TREE_TYPE (result)) != TYPE_UNQUALIFIED)
index 8b3fddc435ebb2b18306066ca88e718099f0cf76..4351ae49952207292f9a1b3b687b7302dabbf127 100644 (file)
@@ -1708,7 +1708,9 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
 
       /* Build call to the function being thunked.  */
       if (!VOID_TYPE_P (restype)
-         && (!alias_is_noreturn || TREE_ADDRESSABLE (restype)))
+         && (!alias_is_noreturn
+             || TREE_ADDRESSABLE (restype)
+             || TREE_CODE (TYPE_SIZE_UNIT (restype)) != INTEGER_CST))
        {
          if (DECL_BY_REFERENCE (resdecl))
            {
index b331e410a3c152a699a4a61d19feb6f97ba925c1..692d168c3b4e1f0c6c390010938097eb5dc839da 100644 (file)
@@ -4838,7 +4838,8 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
        }
       notice_special_calls (call_stmt);
       if (!gimple_call_noreturn_p (call_stmt)
-         || TREE_ADDRESSABLE (TREE_TYPE (*to_p)))
+         || TREE_ADDRESSABLE (TREE_TYPE (*to_p))
+         || TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST)
        gimple_call_set_lhs (call_stmt, *to_p);
       assign = call_stmt;
     }
index 0f61a7e65a43d66a2c07186978e7cd7463942510..5b469568e0e96dca89e6e4f1706fed8dbc15be0f 100644 (file)
@@ -1,3 +1,9 @@
+2016-03-16  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70093
+       * gcc.dg/nested-func-10.c: New test.
+       * gcc.dg/nested-func-9.c: New test.
+
 2016-03-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/68714
diff --git a/gcc/testsuite/gcc.dg/nested-func-10.c b/gcc/testsuite/gcc.dg/nested-func-10.c
new file mode 100644 (file)
index 0000000..ac6f76f
--- /dev/null
@@ -0,0 +1,56 @@
+/* PR c/70093 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void __attribute__((noinline, noclone))
+foo (int n)
+{
+  struct S { int a[n]; };
+
+  struct S __attribute__((noreturn))
+  fn (void)
+  {
+    __builtin_abort ();
+  }
+
+  auto struct S __attribute__((noreturn))
+  fn2 (void)
+  {
+    __builtin_abort ();
+  }
+
+  struct S x;
+  __typeof__ (fn ()) *p = &x;
+  switch (n)
+    {
+    case 1:
+      fn ();
+      break;
+    case 2:
+      fn2 ();
+      break;
+    case 3:
+      x = fn ();
+      if (x.a[0] != 42)
+       __builtin_abort ();
+      break;
+    case 4:
+      if (fn ().a[0] != 42)
+       __builtin_abort ();
+      break;
+    case 5:
+      if (p->a[0] != 42)
+       __builtin_abort ();
+      break;
+    case 6:
+      if (fn2 ().a[0] != 42)
+       __builtin_abort ();
+      break;
+    }
+}
+
+int
+main (void)
+{
+  foo (1);
+}
diff --git a/gcc/testsuite/gcc.dg/nested-func-9.c b/gcc/testsuite/gcc.dg/nested-func-9.c
new file mode 100644 (file)
index 0000000..902c258
--- /dev/null
@@ -0,0 +1,47 @@
+/* PR c/70093 */
+/* { dg-do run } */
+/* { dg-options "" } */
+
+void
+foo (int n)
+{
+  struct S { int a[n]; };
+
+  struct S
+  fn (void)
+  {
+    struct S s;
+    s.a[0] = 42;
+    return s;
+  }
+
+  auto struct S
+  fn2 (void)
+  {
+    return fn ();
+  }
+
+  struct S x;
+  fn ();
+  fn2 ();
+  x = fn ();
+
+  if (x.a[0] != 42)
+    __builtin_abort ();
+
+  if (fn ().a[0] != 42)
+    __builtin_abort ();
+
+  __typeof__ (fn ()) *p = &x;
+  if (p->a[0] != 42)
+    __builtin_abort ();
+
+  if (fn2 ().a[0] != 42)
+    __builtin_abort ();
+}
+
+int
+main (void)
+{
+  foo (1);
+}