Re: Committed: fix CRIS build errors with --enable-build-with-cxx.
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.
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
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
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.
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
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
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.
> 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];
凜孔寊薋 炙 莥鑌噫擈堄 陔府秦 隋 滙冦 埒 憚煴芴犳 但 連僩?
Re: [Fortran, DRAFT patch] PR 46321 - [OOP] Polymorphic deallocation
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 @@