Re: Committed: fix CRIS build errors with --enable-build-with-cxx.

2012-06-09 Thread Gabriel Dos Reis
On Sat, Jun 9, 2012 at 3:56 PM, Hans-Peter Nilsson
 wrote:
> Trying --enable-build-with-cxx revealed a build regression for
> cris-elf from the recent atomic support bits.  Tested the same,
> no regressions.
>
> Casting those INTVAL's would've been a tiny bit uglier than
> using a temp, thus.  Hey, those were stashed there as ints
> so what's wrong with passing them as that!  And making "and" a
> reserved word, what's up with that?

In fact, even within C standards, "and" is reserved -- just the same way
"bool", with the proper includes.

> Is that supposed to be easier on the eye or to write than "&"?

Some people find it easier to read than "&&" :-)

-- Gaby


Committed: fix CRIS build errors with --enable-build-with-cxx.

2012-06-09 Thread Hans-Peter Nilsson
Trying --enable-build-with-cxx revealed a build regression for
cris-elf from the recent atomic support bits.  Tested the same,
no regressions.

Casting those INTVAL's would've been a tiny bit uglier than
using a temp, thus.  Hey, those were stashed there as ints
so what's wrong with passing them as that!  And making "and" a
reserved word, what's up with that?  Is that supposed to be
easier on the eye or to write than "&"?  Stupid C++.. ;)
Actually, I'm on the fence FWIW, as long as you don't try to
reindent or force a new formatting standard.

Committed.

gcc:
Fix CRIS build errors with --enable-build-with-cxx.
* config/cris/cris.c (cris_emit_trap_for_misalignment): Rename
variable "and" to "andop".
* config/cris/sync.md ("atomic_fetch_"): Use
temporary variable for memory model, passing C++-type-correct
parameter type to expand_mem_thread_fence.
("atomic_compare_and_swap"): Ditto.

Index: gcc/config/cris/sync.md
===
--- gcc/config/cris/sync.md (revision 188355)
+++ gcc/config/cris/sync.md (working copy)
@@ -88,14 +88,16 @@ (define_expand "atomic_fetch_mode != QImode && TARGET_TRAP_UNALIGNED_ATOMIC)
 cris_emit_trap_for_misalignment (operands[1]);
 
-  expand_mem_thread_fence (INTVAL (operands[3]));
+  expand_mem_thread_fence (mmodel);
   emit_insn (gen_cris_atomic_fetch__1 (operands[0],
 operands[1],
 operands[2]));
-  expand_mem_thread_fence (INTVAL (operands[3]));
+  expand_mem_thread_fence (mmodel);
   DONE;
 })
 
@@ -189,16 +191,18 @@ (define_expand "atomic_compare_and_swap<
(match_operand 7)]
   ""
 {
+  enum memmodel mmodel = (enum memmodel) INTVAL (operands[6]);
+
   if (mode != QImode && TARGET_TRAP_UNALIGNED_ATOMIC)
 cris_emit_trap_for_misalignment (operands[2]);
 
-  expand_mem_thread_fence (INTVAL (operands[6]));
+  expand_mem_thread_fence (mmodel);
   emit_insn (gen_cris_atomic_compare_and_swap_1 (operands[0],
   operands[1],
   operands[2],
   operands[3],
   operands[4]));
-  expand_mem_thread_fence (INTVAL (operands[6]));
+  expand_mem_thread_fence (mmodel);
   DONE;
 })
 
Index: gcc/config/cris/cris.c
===
--- gcc/config/cris/cris.c  (revision 188355)
+++ gcc/config/cris/cris.c  (working copy)
@@ -1929,7 +1929,7 @@ cris_simple_epilogue (void)
 void
 cris_emit_trap_for_misalignment (rtx mem)
 {
-  rtx addr, reg, ok_label, and, jmp;
+  rtx addr, reg, ok_label, andop, jmp;
   int natural_alignment;
   gcc_assert (MEM_P (mem));
 
@@ -1941,8 +1941,8 @@ cris_emit_trap_for_misalignment (rtx mem
   /* This will yield a btstq without a separate register used, usually -
  with the exception for PRE hoisting the "and" but not the branch
  around the trap: see gcc.dg/target/cris/sync-3s.c.  */
-  and = gen_rtx_AND (Pmode, reg, GEN_INT (natural_alignment - 1));
-  emit_cmp_and_jump_insns (force_reg (SImode, and), const0_rtx, EQ,
+  andop = gen_rtx_AND (Pmode, reg, GEN_INT (natural_alignment - 1));
+  emit_cmp_and_jump_insns (force_reg (SImode, andop), const0_rtx, EQ,
   NULL_RTX, Pmode, 1, ok_label);
   jmp = get_last_insn ();
   gcc_assert (JUMP_P (jmp));

brgds, H-P


Re: [PATCH, libgcc]: Put soft-FP exception handler out-of-line for x86

2012-06-09 Thread Uros Bizjak
On Thu, Jun 7, 2012 at 9:58 PM, Uros Bizjak  wrote:

> Attached patch rewrites x86 soft-FP as an out-of-line function that
> gets conditionally called when exception occurs. This rewrite removes
> 17 instances of the same code from libgcc. In addition, the patch
> unifies a lot of code between 32bit and 64bit x86 target, and also
> introduces SSE instructions for 32bit targets. There is no other
> functional changes, although the change to real SSE FP ops is
> tempting. ;)
>
> 2012-06-07  Uros Bizjak  
>
>        * config/i386/32/sfp-machine.h (__gcc_CMPtype, CMPtype,
>        _FP_KEEPNANFRACP, _FP_CHOOSENAN, FP_EX_INVALID, FP_EX_DENORM,
>        FP_EX_DIVZERO, FP_EX_OVERFLOW, FP_EX_UNDERFLOW, FP_EX_INEXACT,
>        FP_HANDLE_EXCEPTIONS, FP_RND_NEAREST, FP_RND_ZERO, FP_RND_PINF,
>        FP_RND_MINF, _FP_DEXL_EX, FP_INIT_ROUNDMODE, FP_ROUNDMODE,
>        __LITTLE_ENDIAN, __BIG_ENDIAN, strong_alias): Move ...
>        * config/i386/64/sfp-machine: ... (delete here) ...
>        * config/i386/sfp-machine.h: ... to here.
>        (FP_EX_MASK): New.
>        (__sfp_handle_exceptions): New function declaration.
>        (FP_HANDLE_EXCEPTIONS): Use __sfp_handle_exceptions.
>        * config/i386/sfp-exceptions.c: New.
>        * config/i386/t-softfp: New.
>        * config.host (i[34567]86-*-* and x86_64-*-* soft-fp targets): Add
>        i386/t-softfp to tmake_file.
>
> Patch was tested on x86_64-pc-linux-gnu {,-m32}.

I have committed attached, slightly changed patch (asm patterns in
__sfp_handle_exceptions) to the mainline SVN.

Uros.
Index: config/i386/sfp-machine.h
===
--- config/i386/sfp-machine.h   (revision 188333)
+++ config/i386/sfp-machine.h   (working copy)
@@ -3,8 +3,83 @@
 #define _FP_STRUCT_LAYOUT  __attribute__ ((gcc_struct))
 #endif
 
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
 #ifdef __x86_64__
 #include "config/i386/64/sfp-machine.h"
 #else
 #include "config/i386/32/sfp-machine.h"
 #endif
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+  do { \
+if (_FP_FRAC_GT_##wc(X, Y) \
+   || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
+  {\
+   R##_s = X##_s;  \
+_FP_FRAC_COPY_##wc(R,X);   \
+  }\
+else   \
+  {\
+   R##_s = Y##_s;  \
+_FP_FRAC_COPY_##wc(R,Y);   \
+  }\
+R##_c = FP_CLS_NAN;\
+  } while (0)
+
+#define FP_EX_INVALID  0x01
+#define FP_EX_DENORM   0x02
+#define FP_EX_DIVZERO  0x04
+#define FP_EX_OVERFLOW 0x08
+#define FP_EX_UNDERFLOW0x10
+#define FP_EX_INEXACT  0x20
+
+#define FP_EX_MASK 0x3f
+
+void __sfp_handle_exceptions (int);
+
+#define FP_HANDLE_EXCEPTIONS   \
+  do { \
+if (_fex & FP_EX_MASK) \
+  __sfp_handle_exceptions (_fex);  \
+  } while (0);
+
+#define FP_RND_NEAREST 0
+#define FP_RND_ZERO0xc00
+#define FP_RND_PINF0x800
+#define FP_RND_MINF0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE  \
+  do { \
+__asm__ ("fnstcw %0" : "=m" (_fcw));   \
+  } while (0)
+
+#define FP_ROUNDMODE   (_fcw & 0xc00)
+
+#define__LITTLE_ENDIAN 1234
+#define__BIG_ENDIAN4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+

Fix c++/53602, part 2

2012-06-09 Thread Richard Henderson
The second patch that would have hidden the ICE rather than truly fixing it.

At first I was simply annoyed that I didn't have a dump file to look at that 
matched up with the actual input to the CSA pass.  That alone warranted 
splitting out the CLEANUP_CROSSJUMP call to its own pass.

However, I got to thinking about it more and its right for even more reasons:

 * -fno-combine-stack-adjustments overrides -fcrossjumping

 * The CSA pass is a block-local optimization that works better when it can
   see more code.  Indeed, with this particular test case the reason that we
   don't ICE with this patch is that CSA was able to propagate the ARGS_SIZE
   note onto a following stack push insn (which post cross-jumping is split
   into a new block), obviating the need for the clobber insn that the Part1
   patch introduces.

 * The crossjumping pass works better with fewer insns to compare.  Therefore
   let the CSA pass run first and have it delete what it can.

Note that I renamed the old jump2 pass.  I felt silly adding a jump3 pass when
the original jump1 pass no longer exists.

Committed only to mainline after testing on x86_64 and i686.


r~
PR c++/53602
* cfgcleanup.c (execute_jump): Rename from rest_of_handle_jump2.
(pass_jump): Rename from pass_jump2.
(execute_jump2, pass_jump2): New.
* combine-stack-adj.c (rest_of_handle_stack_adjustments): Don't
perform cfg cleanup here.  Move the test of PUSH_ROUNDING
and ACCUMULATE_OUTGOING_ARGS test...
(gate_handle_stack_adjustments): ... here.
* passes.c (init_optimization_passes): Update for pass_jump2 rename.
Place new pass_jump2 after pass_stack_adjustments.
* tree-pass.h (pass_jump): Declare.


diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 619b274..1aa4cbb 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -2990,7 +2990,7 @@ cleanup_cfg (int mode)
 }
 
 static unsigned int
-rest_of_handle_jump2 (void)
+execute_jump (void)
 {
   delete_trivially_dead_insns (get_insns (), max_reg_num ());
   if (dump_file)
@@ -3000,22 +3000,47 @@ rest_of_handle_jump2 (void)
   return 0;
 }
 
+struct rtl_opt_pass pass_jump =
+{
+ {
+  RTL_PASS,
+  "jump",  /* name */
+  NULL,/* gate */
+  execute_jump,/* execute */
+  NULL,/* sub */
+  NULL,/* next */
+  0,   /* static_pass_number */
+  TV_JUMP, /* tv_id */
+  0,   /* properties_required */
+  0,   /* properties_provided */
+  0,   /* properties_destroyed */
+  TODO_ggc_collect,/* todo_flags_start */
+  TODO_verify_rtl_sharing, /* todo_flags_finish */
+ }
+};
+
+static unsigned int
+execute_jump2 (void)
+{
+  cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0);
+  return 0;
+}
 
 struct rtl_opt_pass pass_jump2 =
 {
  {
   RTL_PASS,
-  "jump",   /* name */
-  NULL, /* gate */
-  rest_of_handle_jump2,/* execute */
-  NULL, /* sub */
-  NULL, /* next */
-  0,/* static_pass_number */
-  TV_JUMP,  /* tv_id */
-  0,/* properties_required */
-  0,/* properties_provided */
-  0,/* properties_destroyed */
-  TODO_ggc_collect, /* todo_flags_start */
-  TODO_verify_rtl_sharing,  /* todo_flags_finish */
+  "jump2", /* name */
+  NULL,/* gate */
+  execute_jump2,   /* execute */
+  NULL,/* sub */
+  NULL,/* next */
+  0,   /* static_pass_number */
+  TV_JUMP, /* tv_id */
+  0,   /* properties_required */
+  0,   /* properties_provided */
+  0,   /* properties_destroyed */
+  TODO_ggc_collect,/* todo_flags_start */
+  TODO_verify_rtl_sharing, /* todo_flags_finish */
  }
 };
diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
index b46fe3b..65e8f04 100644
--- a/gcc/combine-stack-adj.c
+++ b/gcc/combine-stack-adj.c
@@ -626,26 +626,23 @@ combine_stack_adjustments_for_block (basic_block bb)
 static bool
 gate_handle_stack_adjustments (void)
 {
-  return flag_combine_stack_adjustments;
-}
-
-static unsigned int
-rest_of_handle_stack_adjustm

Re: [PATCH 3/3] rs6000: Rewrite sync patterns for atomic; expand early.

2012-06-09 Thread Richard Henderson
On 2012-06-09 03:39, Eric Botcazou wrote:
> the 4.7 compiler generates at -O:
> 
> load:
> sync
> lwz 10,0(3)
> lwz 11,4(3)
> cmpw 7,10,10
> bne- 7,$+4
> isync
> mr 3,10
> mr 4,11
> blr
> 
> Is that really an atomic load?

Nope.  I do see the obvious mistake in the atomic_load pattern though:
The mode iterator should have been INT1 not INT.

... and for extra credit we ought to implement DImode atomic load/store
via the FPU, like we do for i386.


r~


Fix c++/53602, part 1

2012-06-09 Thread Richard Henderson
One of two patches that make the testcase ICE go away, both
of which make sense, but our release manager thought that 
only this simple one was appropriate for the 4.7 branch.

Committed to 4.7 and mainline after testing on i686 with
BOOT_CFLAGS -Os, and x86_64 (for sanity).


r~
PR c++/53602
* combine-stack-adj.c (force_move_args_size_note): Add ARGS_SIZE
note to a clobber insn when no other insn is available.


diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
index 6b6f74b..273252e 100644
--- a/gcc/combine-stack-adj.c
+++ b/gcc/combine-stack-adj.c
@@ -1,7 +1,7 @@
 /* Combine stack adjustments.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010 Free Software Foundation, Inc.
+   2010, 2012 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -414,9 +414,10 @@ force_move_args_size_note (basic_block bb, rtx prev, rtx 
insn)
 {
   /* ??? We *must* have a place, lest we ICE on the lost adjustment.
 Options are: dummy clobber insn, nop, or prevent the removal of
-the sp += 0 insn.  Defer that decision until we can prove this
-can actually happen.  */
-  gcc_unreachable ();
+the sp += 0 insn.  */
+  /* TODO: Find another way to indicate to the dwarf2 code that we
+have not in fact lost an adjustment.  */
+  test = emit_insn_before (gen_rtx_CLOBBER (VOIDmode, const0_rtx), insn);
 }
   add_reg_note (test, REG_ARGS_SIZE, XEXP (note, 0));
 }
diff --git a/gcc/testsuite/g++.dg/torture/pr53602.C 
b/gcc/testsuite/g++.dg/torture/pr53602.C
new file mode 100644
index 000..1bb9cf4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr53602.C
@@ -0,0 +1,365 @@
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+
+namespace std
+{
+  template 
+  struct pair
+  {
+  };
+  struct input_iterator_tag
+  {
+  };
+  struct forward_iterator_tag : public input_iterator_tag
+  {
+  };
+  template 
+  struct iterator
+  {
+  };
+}
+namespace __gnu_cxx
+{
+  template 
+  struct new_allocator
+  {
+typedef _Tp pointer;
+typedef _Tp value_type;
+template 
+struct rebind
+{
+  typedef new_allocator <_Tp1> other;
+};
+  };
+}
+namespace std
+{
+  template 
+  struct allocator : public __gnu_cxx::new_allocator <_Tp>
+  {
+  };
+}
+extern "C"
+{
+  struct rtl_String;
+  void rtl_string_release (rtl_String *) throw ();
+  void rtl_string_newFromStr (rtl_String * *, const char *) throw ();
+}
+namespace std
+{
+  template  struct binary_function;
+  template 
+  struct equal_to : public binary_function <_Tp, _Tp, bool>
+  {
+  };
+}
+namespace rtl
+{
+  struct OString
+  {
+rtl_String * pData;
+OString (const char *value)
+{
+  rtl_string_newFromStr (&pData, value);
+}
+ ~OString ()
+{
+  rtl_string_release (pData);
+}
+  };
+  struct OStringHash;
+}
+namespace boost
+{
+  template  struct hash;
+  namespace unordered
+  {
+template , class = std::equal_to , 
class = std::allocator >class unordered_set;
+  }
+  using boost::unordered::unordered_set;
+  namespace detail
+  {
+template 
+struct if_true
+{
+  template 
+  struct then
+  {
+   typedef F type;
+  };
+};
+  }
+  template  struct pointer_to_other;
+  template 
+  struct pointer_to_other 
+  {
+typedef U type;
+  };
+  namespace unordered
+  {
+namespace detail
+{
+  template  struct integral_constant
+  {
+  };
+  struct choice9
+  {
+   typedef char (&type)[9];
+  };
+  struct choice8:choice9
+  {
+  };
+  struct choice7:choice8
+  {
+  };
+  struct choice6:choice7
+  {
+  };
+  struct choice5:choice6
+  {
+  };
+  struct choice4:choice5
+  {
+  };
+  struct choice3:choice4
+  {
+  };
+  struct choice2:choice3
+  {
+  };
+  struct choice1:choice2
+  {
+  };
+  choice1 choose ();
+  template 
+  struct rebind_wrap
+  {
+   typedef typename Alloc::template rebind ::other type;
+  };
+  template 
+  struct sfinae:T2
+  {
+  };
+  template 
+  struct default_type_pointer
+  {
+   template 
+   static boost::unordered::detail::sfinae  
test (choice1);
+   struct DefaultWrap
+   {
+ typedef Default pointer;
+   };
+   enum { value = (1 == sizeof (test  (choose ( };
+   typedef typename boost::detail::if_true ::template then ::type::pointer type;
+  };
+  template 
+  struct default_type_const_pointer
+  {
+   template 
+   static choice2::type test (choice2);
+   struct DefaultWrap
+   {
+   };
+   enum { value = (1 == sizeof (test  (choose ( };
+   typedef typename boost::detail::if_true ::template then  type;
+  };
+  struct default_type_propagate_on_container_swap
+  {
+   str

obvious fix to simplify-rtx.c

2012-06-09 Thread Kenneth Zadeck
The shift count was being truncated by the wrong amount.It is now 
zero extended from log2 of the mode size rather than the mode size.
This is a (mostly) obvious fix - iant needed a hint to see what was 
wrong.   The location of this code meant that this would be a very rare 
bug:   only ti mode shifts on an llp64 platform.


bootstrapped and regression tested on x86-64.

committed as revision 188359.

Kenny



2012-06-09  Kenneth Zadeck 

* simplify-rtx.c (simplify_const_binary_operation): Fixed shift
count trucation.

Index: gcc/simplify-rtx.c
===
--- gcc/simplify-rtx.c(revision 188350)
+++ gcc/simplify-rtx.c(working copy)
@@ -3653,7 +3653,10 @@ simplify_const_binary_operation (enum rt
 unsigned HOST_WIDE_INT cnt;

 if (SHIFT_COUNT_TRUNCATED)
-  o1 = double_int_zext (o1, GET_MODE_PRECISION (mode));
+  {
+o1.high = 0;
+o1.low &= GET_MODE_PRECISION (mode) - 1;
+  }

 if (!double_int_fits_in_uhwi_p (o1)
 || double_int_to_uhwi (o1) >= GET_MODE_PRECISION (mode))



Re: [PATCH 3/3] rs6000: Rewrite sync patterns for atomic; expand early.

2012-06-09 Thread Eric Botcazou
> The conversion of the __sync post-reload splitters was half
> complete.  Since there are nearly no restrictions on what may
> appear between LL and SC, expand all the patterns immediatly.
> This allows significantly easier code generation for subword
> atomic operations.

On PowerPC/Linux, for:

typedef __UINT64_TYPE__ uint64_t;

uint64_t load (uint64_t *loc)
{
  return __atomic_load_8 (loc, __ATOMIC_SEQ_CST);
}

the 4.7 compiler generates at -O:

load:
sync
lwz 10,0(3)
lwz 11,4(3)
cmpw 7,10,10
bne- 7,$+4
isync
mr 3,10
mr 4,11
blr

Is that really an atomic load?

-- 
Eric Botcazou


[For..2-6]桹 [EndFor];

2012-06-09 Thread Brandon Hegyi
凜孔寊薋 炙 莥鑌噫擈堄 陔府秦 隋 滙冦 埒 憚煴芴犳 但 連僩?


Re: [Fortran, DRAFT patch] PR 46321 - [OOP] Polymorphic deallocation

2012-06-09 Thread Alessandro Fanfarillo
Hi all,
with the priceless support of Tobias I've almost realized the patch
for this PR. In attachment there's the second draft. During the
regression test I have only one error with select_type_4.f90. The
problem is in the destroy_list subroutine when it checks
associated(node) after the first deallocate(node).

2012/6/5 Paul Richard Thomas :
> Hi Alessandro,
>
> I am glad to see that Janus is giving you a helping hand, in addition
> to Tobias.  I am so tied up with every aspect of life that gfortran is
> not figuring much at all.
>
> When you clean up the patch, you might consider making this into a
> separate function:
>
> +         if (free_proc)
> +           {
> +             ppc = gfc_copy_expr(free_proc->initializer);
> +             ppc_code = gfc_get_code ();
> +             ppc_code->resolved_sym = ppc->symtree->n.sym;
> +             ppc_code->resolved_sym->attr.elemental = 1;
> +             ppc_code->ext.actual = actual;
> +             ppc_code->expr1 = ppc;
> +             ppc_code->op = EXEC_CALL;
> +             tmp = gfc_trans_call (ppc_code, true, NULL, NULL, false);
> +             gfc_free_statements (ppc_code);
> +             gfc_add_expr_to_block (&block, tmp);
> +           }
>
> ... and using the function call to replace the corresponding call to
> _copy in trans_allocate.
>
> I suspect that we are going to do this some more :-)
>
> Once we have the separate function, we could at later stage replace it
> by a TREE_SSA version.
>
> Cheers
>
> Paul
>
> On 3 June 2012 12:15, Alessandro Fanfarillo  wrote:
>>> Right, the problem is that the _free component is missing. Just as the
>>> _copy component, _free should be present for *every* vtype, no matter
>>> if there are allocatable components or not. If the _free component is
>>> not needed, it should be initialized to EXPR_NULL.
>>
>> With an "empty" _free function for every type which does not have
>> allocatable components the problem with dynamic_dispatch_4.f03
>> disappears :), thank you very much. In the afternoon I'll reorganize
>> the code.
>>
>> Bye.
>>
>> Alessandro
>
>
>
> --
> The knack of flying is learning how to throw yourself at the ground and miss.
>        --Hitchhikers Guide to the Galaxy
Index: gcc/testsuite/gfortran.dg/class_19.f03
===
--- gcc/testsuite/gfortran.dg/class_19.f03  (revisione 188002)
+++ gcc/testsuite/gfortran.dg/class_19.f03  (copia locale)
@@ -39,5 +39,5 @@ program main
 
 end program main
 
-! { dg-final { scan-tree-dump-times "__builtin_free" 11 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_free" 14 "original" } }
 ! { dg-final { cleanup-tree-dump "original" } }
Index: gcc/testsuite/gfortran.dg/auto_dealloc_2.f90
===
--- gcc/testsuite/gfortran.dg/auto_dealloc_2.f90(revisione 188002)
+++ gcc/testsuite/gfortran.dg/auto_dealloc_2.f90(copia locale)
@@ -25,5 +25,5 @@ contains
 
 end program 
 
-! { dg-final { scan-tree-dump-times "__builtin_free" 3 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_free" 4 "original" } }
 ! { dg-final { cleanup-tree-dump "original" } }
Index: gcc/fortran/trans-stmt.c
===
--- gcc/fortran/trans-stmt.c(revisione 188002)
+++ gcc/fortran/trans-stmt.c(copia locale)
@@ -5341,7 +5341,12 @@ gfc_trans_deallocate (gfc_code *code)
 
   for (al = code->ext.alloc.list; al != NULL; al = al->next)
 {
-  gfc_expr *expr = gfc_copy_expr (al->expr);
+  gfc_expr *expr;
+  gfc_expr *ppc;
+  gfc_code *ppc_code;
+  gfc_actual_arglist *actual;
+  expr = gfc_copy_expr (al->expr);
+  ppc = gfc_copy_expr (expr);
   gcc_assert (expr->expr_type == EXPR_VARIABLE);
 
   if (expr->ts.type == BT_CLASS)
@@ -5354,6 +5359,24 @@ gfc_trans_deallocate (gfc_code *code)
   se.descriptor_only = 1;
   gfc_conv_expr (&se, expr);
 
+  actual = gfc_get_actual_arglist ();
+  actual->expr = gfc_copy_expr (expr);
+
+  if (expr->symtree->n.sym->ts.type == BT_CLASS)
+   {
+ gfc_add_vptr_component (ppc);
+ gfc_add_component_ref (ppc, "_free");
+ ppc_code = gfc_get_code ();
+ ppc_code->resolved_sym = ppc->symtree->n.sym;
+ ppc_code->resolved_sym->attr.elemental = 1;
+ ppc_code->ext.actual = actual;
+ ppc_code->expr1 = ppc;
+ ppc_code->op = EXEC_CALL;
+ tmp = gfc_trans_call (ppc_code, true, NULL, NULL, false);
+ gfc_free_statements (ppc_code);
+ gfc_add_expr_to_block (&block, tmp);
+   }
+
   if (expr->rank || gfc_is_coarray (expr))
{
  if (expr->ts.type == BT_DERIVED && 
expr->ts.u.derived->attr.alloc_comp)
Index: gcc/fortran/class.c
===
--- gcc/fortran/class.c (revisione 188002)
+++ gcc/fortran/class.c (copia locale)
@@ -717,6 +717,9 @@