Restore functional DONT_USE_BUILTIN_SETJMP support

2017-10-07 Thread Eric Botcazou
DONT_USE_BUILTIN_SETJMP is an old configuration macro that instructs the 
compiler to use the usual setjmp/longjmp routines instead of their built-in 
variants to implement SJLJ exceptions.  It's less efficient but, sometimes, 
the setjmp/longjmp routines have specific features that cannot be easily 
implemented by the built-in.  Only IA-64 and Aarch64 define it.

The support is currently broken at compile time (because of a broken CFG) and 
at link time (an unresolved symbol).  The attached small patch restores it.

Bootstrapped & tested on Aarch64/Linux with --enable-sjlj-exceptions, applied 
on the mainline as obvious.


2017-10-07  Eric Botcazou  

* builtins.def (BUILT_IN_SETJMP): Declare as library builtin instead
of GCC builtin if DONT_USE_BUILTIN_SETJMP is defined.
* except.c (sjlj_emit_function_enter): If DONT_USE_BUILTIN_SETJMP is
defined, force the creation of a new block for a dispatch label.

-- 
Eric BotcazouIndex: builtins.def
===
--- builtins.def	(revision 253506)
+++ builtins.def	(working copy)
@@ -890,7 +890,11 @@ DEF_LIB_BUILTIN(BUILT_IN_REALLOC
 DEF_GCC_BUILTIN(BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN(BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_LEAF_LIST)
 DEF_GCC_BUILTIN(BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
+#ifdef DONT_USE_BUILTIN_SETJMP
+DEF_LIB_BUILTIN(BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_RT_NOTHROW_LEAF_LIST)
+#else
 DEF_GCC_BUILTIN(BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_RT_NOTHROW_LEAF_LIST)
+#endif
 DEF_EXT_LIB_BUILTIN(BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4)
 DEF_LIB_BUILTIN(BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_TM_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0)
 DEF_GCC_BUILTIN(BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_COLD_LIST)
Index: except.c
===
--- except.c	(revision 253506)
+++ except.c	(working copy)
@@ -1209,6 +1209,28 @@ sjlj_emit_function_enter (rtx_code_label
 	  fn_begin_outside_block = false;
   }
 
+#ifdef DONT_USE_BUILTIN_SETJMP
+  if (dispatch_label)
+{
+  /* The sequence contains a branch in the middle so we need to force
+	 the creation of a new basic block by means of BB_SUPERBLOCK.  */
+  if (fn_begin_outside_block)
+	{
+	  basic_block bb
+	= split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
+	  if (JUMP_P (BB_END (bb)))
+	emit_insn_before (seq, BB_END (bb));
+	  else
+	emit_insn_after (seq, BB_END (bb));
+	}
+  else
+	emit_insn_after (seq, fn_begin);
+
+  single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun))->flags |= BB_SUPERBLOCK;
+  return;
+}
+#endif
+
   if (fn_begin_outside_block)
 insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
   else


Re: [RFC] propagate malloc attribute in ipa-pure-const pass

2017-10-07 Thread Prathamesh Kulkarni
On 7 October 2017 at 11:23, Jan Hubicka  wrote:
>> On 6 October 2017 at 06:04, Jan Hubicka  wrote:
>> >> Hi Honza,
>> >> Thanks for the detailed suggestions, I have updated the patch accordingly.
>> >> I have following questions on call_summary:
>> >> 1] I added field bool is_return_callee in ipa_call_summary to track
>> >> whether the caller possibly returns value returned by callee, which
>> >> gets rid of return_callees_map. I assume ipa_call_summary_t::remove()
>> >> and ipa_call_summary_t::duplicate() will already take care of handling
>> >> late insertion/removal of cgraph nodes ? I just initialized
>> >> is_return_callee to false in ipa_call_summary::reset and that seems to
>> >> work. I am not sure though if I have handled it correctly. Could you
>> >> please check that ?
>> >
>> > I was actually thinking to introduce separate summary for ipa-pure-const 
>> > pass,
>> > but this seems fine to me too (for one bit definitly more effecient)
>> > ipa_call_summary_t::duplicate copies all the fields, so indeed you should 
>> > be
>> > safe here.
>> >
>> > Also it is possible for functions to be inserted late.  Updating of call 
>> > summaries
>> > is currently handled by ipa_fn_summary_t::insert
>> >>
>> >> 2] ipa_inline() called ipa_free_fn_summary, which made
>> >> ipa_call_summaries unavailable during ipa-pure-const pass. I removed
>> >> call to ipa_free_fn_summary from ipa_inline, and moved it to
>> >> ipa_pure_const::execute(). Is that OK ?
>> >
>> > Seems OK to me.
>> >>
>> >> Patch passes bootstrap+test and lto bootstrap+test on 
>> >> x86_64-unknown-linux-gnu.
>> >> Verfiied SPEC2k6 compiles and runs without miscompares with LTO
>> >> enabled on aarch64-linux-gnu.
>> >> Cross-tested on arm*-*-* and aarch64*-*-*. I will additionally test
>> >> the patch by building chromium or firefox.
>> >> Would it be OK to commit if it passes above validations ?
>> >>
>> >> Thanks,
>> >> Prathamesh
>> >> >
>> >> > Thanks,
>> >> > Honza
>> >
>> >> 2017-10-05  Prathamesh Kulkarni  
>> >>
>> >>   * cgraph.h (set_malloc_flag): Declare.
>> >>   * cgraph.c (set_malloc_flag_1): New function.
>> >>   (set_malloc_flag): Likewise.
>> >>   * ipa-fnsummary.h (ipa_call_summary): Add new field 
>> >> is_return_callee.
>> >>   * ipa-fnsummary.c (ipa_call_summary::reset): Set is_return_callee to
>> >>   false.
>> >>   (read_ipa_call_summary): Add support for reading is_return_callee.
>> >>   (write_ipa_call_summary): Stream is_return_callee.
>> >>   * ipa-inline.c (ipa_inline): Remove call to ipa_free_fn_summary.
>> >>   * ipa-pure-const.c: Add headers ssa.h, alloc-pool.h, 
>> >> symbol-summary.h,
>> >>   ipa-prop.h, ipa-fnsummary.h.
>> >>   (malloc_state_e): Define.
>> >>   (malloc_state_names): Define.
>> >>   (funct_state_d): Add field malloc_state.
>> >>   (varying_state): Set malloc_state to STATE_MALLOC_BOTTOM.
>> >>   (check_retval_uses): New function.
>> >>   (malloc_candidate_p): Likewise.
>> >>   (analyze_function): Add support for malloc attribute.
>> >>   (pure_const_write_summary): Stream malloc_state.
>> >>   (pure_const_read_summary): Add support for reading malloc_state.
>> >>   (dump_malloc_lattice): New function.
>> >>   (propagate_malloc): New function.
>> >>   (ipa_pure_const::execute): Call propagate_malloc and
>> >>   ipa_free_fn_summary.
>> >>   (pass_local_pure_const::execute): Add support for malloc attribute.
>> >>   * ssa-iterators.h (RETURN_FROM_IMM_USE_STMT): New macro.
>> >>
>> >> testsuite/
>> >>   * gcc.dg/ipa/propmalloc-1.c: New test-case.
>> >>   * gcc.dg/ipa/propmalloc-2.c: Likewise.
>> >>   * gcc.dg/ipa/propmalloc-3.c: Likewise.
>> >>
>> >> diff --git a/gcc/cgraph.c b/gcc/cgraph.c
>> >> index 3d0cefbd46b..0aad90d59ea 100644
>> >> --- a/gcc/cgraph.c
>> >> +++ b/gcc/cgraph.c
>> >> @@ -2530,6 +2530,53 @@ cgraph_node::set_nothrow_flag (bool nothrow)
>> >>return changed;
>> >>  }
>> >>
>> >> +/* Worker to set malloc flag.  */
>> > New line here I guess (it is below)
>> >> +static void
>> >> +set_malloc_flag_1 (cgraph_node *node, bool malloc_p, bool *changed)
>> >> +{
>> >> +  if (malloc_p && !DECL_IS_MALLOC (node->decl))
>> >> +{
>> >> +  DECL_IS_MALLOC (node->decl) = true;
>> >> +  *changed = true;
>> >> +}
>> >> +
>> >> +  ipa_ref *ref;
>> >> +  FOR_EACH_ALIAS (node, ref)
>> >> +{
>> >> +  cgraph_node *alias = dyn_cast (ref->referring);
>> >> +  if (!malloc_p || alias->get_availability () > AVAIL_INTERPOSABLE)
>> >> + set_malloc_flag_1 (alias, malloc_p, changed);
>> >> +}
>> >> +
>> >> +  for (cgraph_edge *e = node->callers; e; e = e->next_caller)
>> >> +if (e->caller->thunk.thunk_p
>> >> + && (!malloc_p || e->caller->get_availability () > 
>> >> AVAIL_INTERPOSABLE))
>> >> +  set_malloc_flag_1 (e->caller, malloc_p, changed);
>> >> +}
>> >> +
>> >> +/* Set 

Re: [RFC] propagate malloc attribute in ipa-pure-const pass

2017-10-07 Thread Jan Hubicka
> On 6 October 2017 at 06:04, Jan Hubicka  wrote:
> >> Hi Honza,
> >> Thanks for the detailed suggestions, I have updated the patch accordingly.
> >> I have following questions on call_summary:
> >> 1] I added field bool is_return_callee in ipa_call_summary to track
> >> whether the caller possibly returns value returned by callee, which
> >> gets rid of return_callees_map. I assume ipa_call_summary_t::remove()
> >> and ipa_call_summary_t::duplicate() will already take care of handling
> >> late insertion/removal of cgraph nodes ? I just initialized
> >> is_return_callee to false in ipa_call_summary::reset and that seems to
> >> work. I am not sure though if I have handled it correctly. Could you
> >> please check that ?
> >
> > I was actually thinking to introduce separate summary for ipa-pure-const 
> > pass,
> > but this seems fine to me too (for one bit definitly more effecient)
> > ipa_call_summary_t::duplicate copies all the fields, so indeed you should be
> > safe here.
> >
> > Also it is possible for functions to be inserted late.  Updating of call 
> > summaries
> > is currently handled by ipa_fn_summary_t::insert
> >>
> >> 2] ipa_inline() called ipa_free_fn_summary, which made
> >> ipa_call_summaries unavailable during ipa-pure-const pass. I removed
> >> call to ipa_free_fn_summary from ipa_inline, and moved it to
> >> ipa_pure_const::execute(). Is that OK ?
> >
> > Seems OK to me.
> >>
> >> Patch passes bootstrap+test and lto bootstrap+test on 
> >> x86_64-unknown-linux-gnu.
> >> Verfiied SPEC2k6 compiles and runs without miscompares with LTO
> >> enabled on aarch64-linux-gnu.
> >> Cross-tested on arm*-*-* and aarch64*-*-*. I will additionally test
> >> the patch by building chromium or firefox.
> >> Would it be OK to commit if it passes above validations ?
> >>
> >> Thanks,
> >> Prathamesh
> >> >
> >> > Thanks,
> >> > Honza
> >
> >> 2017-10-05  Prathamesh Kulkarni  
> >>
> >>   * cgraph.h (set_malloc_flag): Declare.
> >>   * cgraph.c (set_malloc_flag_1): New function.
> >>   (set_malloc_flag): Likewise.
> >>   * ipa-fnsummary.h (ipa_call_summary): Add new field is_return_callee.
> >>   * ipa-fnsummary.c (ipa_call_summary::reset): Set is_return_callee to
> >>   false.
> >>   (read_ipa_call_summary): Add support for reading is_return_callee.
> >>   (write_ipa_call_summary): Stream is_return_callee.
> >>   * ipa-inline.c (ipa_inline): Remove call to ipa_free_fn_summary.
> >>   * ipa-pure-const.c: Add headers ssa.h, alloc-pool.h, 
> >> symbol-summary.h,
> >>   ipa-prop.h, ipa-fnsummary.h.
> >>   (malloc_state_e): Define.
> >>   (malloc_state_names): Define.
> >>   (funct_state_d): Add field malloc_state.
> >>   (varying_state): Set malloc_state to STATE_MALLOC_BOTTOM.
> >>   (check_retval_uses): New function.
> >>   (malloc_candidate_p): Likewise.
> >>   (analyze_function): Add support for malloc attribute.
> >>   (pure_const_write_summary): Stream malloc_state.
> >>   (pure_const_read_summary): Add support for reading malloc_state.
> >>   (dump_malloc_lattice): New function.
> >>   (propagate_malloc): New function.
> >>   (ipa_pure_const::execute): Call propagate_malloc and
> >>   ipa_free_fn_summary.
> >>   (pass_local_pure_const::execute): Add support for malloc attribute.
> >>   * ssa-iterators.h (RETURN_FROM_IMM_USE_STMT): New macro.
> >>
> >> testsuite/
> >>   * gcc.dg/ipa/propmalloc-1.c: New test-case.
> >>   * gcc.dg/ipa/propmalloc-2.c: Likewise.
> >>   * gcc.dg/ipa/propmalloc-3.c: Likewise.
> >>
> >> diff --git a/gcc/cgraph.c b/gcc/cgraph.c
> >> index 3d0cefbd46b..0aad90d59ea 100644
> >> --- a/gcc/cgraph.c
> >> +++ b/gcc/cgraph.c
> >> @@ -2530,6 +2530,53 @@ cgraph_node::set_nothrow_flag (bool nothrow)
> >>return changed;
> >>  }
> >>
> >> +/* Worker to set malloc flag.  */
> > New line here I guess (it is below)
> >> +static void
> >> +set_malloc_flag_1 (cgraph_node *node, bool malloc_p, bool *changed)
> >> +{
> >> +  if (malloc_p && !DECL_IS_MALLOC (node->decl))
> >> +{
> >> +  DECL_IS_MALLOC (node->decl) = true;
> >> +  *changed = true;
> >> +}
> >> +
> >> +  ipa_ref *ref;
> >> +  FOR_EACH_ALIAS (node, ref)
> >> +{
> >> +  cgraph_node *alias = dyn_cast (ref->referring);
> >> +  if (!malloc_p || alias->get_availability () > AVAIL_INTERPOSABLE)
> >> + set_malloc_flag_1 (alias, malloc_p, changed);
> >> +}
> >> +
> >> +  for (cgraph_edge *e = node->callers; e; e = e->next_caller)
> >> +if (e->caller->thunk.thunk_p
> >> + && (!malloc_p || e->caller->get_availability () > 
> >> AVAIL_INTERPOSABLE))
> >> +  set_malloc_flag_1 (e->caller, malloc_p, changed);
> >> +}
> >> +
> >> +/* Set DECL_IS_MALLOC on NODE's decl and on NODE's aliases if any.  */
> >> +
> >> +bool
> >> +cgraph_node::set_malloc_flag (bool malloc_p)
> >> +{
> >> +  bool changed = false;
> >> +
> >> +  if (!malloc_p 

[PATCH] Add a warning for invalid function casts

2017-10-07 Thread Bernd Edlinger
Hi!

I think I have now something useful, it has a few more heuristics
added, to reduce the number of false-positives so that it
is able to find real bugs, for instance in openssl it triggers
at a function cast which has already a TODO on it.

The heuristics are:
- handle void (*)(void) as a wild-card function type.
- ignore volatile, const qualifiers on parameters/return.
- handle any pointers as equivalent.
- handle integral types, enums, and booleans of same precision
   and signedness as equivalent.
- stop parameter validation at the first "...".

I cannot convince myself to handle uintptr_t and pointers as
equivalent.  It is possible that targets like m68k have
an ABI where uintptr_t and void* are different as return values
but are identical as parameter values.

IMHO adding an exception for uintptr_t vs. pointer as parameters
could easily prevent detection of real bugs.  Even if it is safe
for all targets.

However it happens: Examples are the libiberty splay-tree functions,
and also one single place in linux, where an argument of type
"long int" is used to call a timer function with a pointer
argument.  Note, linux does not enable -Wextra.


Patch was bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?


Thanks
Bernd.
gcc:
2017-10-06  Bernd Edlinger  

* doc/invoke.texi: Document -Wcast-function-type.
* recog.h (stored_funcptr): Change signature.
* tree-dump.c (dump_node): Avoid warning.
* typed-splay-tree.h (typed_splay_tree): Avoid warning.

libcpp:
2017-10-06  Bernd Edlinger  

* internal.h (maybe_print_line): Change signature.

c-family:
2017-10-06  Bernd Edlinger  

* c.opt (Wcast-function-type): New warning option.
* c-lex.c (get_fileinfo): Avoid warning.
* c-ppoutput.c (scan_translation_unit_directives_only): Remove cast.

c:
2017-10-06  Bernd Edlinger  

* c-typeck.c (c_abi_equiv_type_p, c_safe_function_type_cast_p): New.
(build_c_cast): Implement -Wcast_function_type.

cp:
2017-10-06  Bernd Edlinger  

* decl2.c (start_static_storage_duration_function): Avoid warning.
* typeck.c (cxx_abi_equiv_type_p, cxx_safe_function_type_cast_p): New.
(build_reinterpret_cast_1): Implement -Wcast_function_type.

testsuite:
2017-10-06  Bernd Edlinger  

* c-c++-common/Wcast-function-type.c: New test.
Index: gcc/c/c-typeck.c
===
--- gcc/c/c-typeck.c	(revision 253493)
+++ gcc/c/c-typeck.c	(working copy)
@@ -5474,6 +5474,52 @@ handle_warn_cast_qual (location_t loc, tree type,
   while (TREE_CODE (in_type) == POINTER_TYPE);
 }
 
+/* Heuristic check if two parameter types can be considered ABI-equivalent.  */
+
+static bool
+c_abi_equiv_type_p (tree t1, tree t2)
+{
+  t1 = TYPE_MAIN_VARIANT (t1);
+  t2 = TYPE_MAIN_VARIANT (t2);
+
+  if (TREE_CODE (t1) == POINTER_TYPE
+  && TREE_CODE (t2) == POINTER_TYPE)
+return true;
+
+  if (INTEGRAL_TYPE_P (t1)
+  && INTEGRAL_TYPE_P (t2)
+  && TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
+  && TYPE_UNSIGNED (t1) == TYPE_UNSIGNED (t2))
+return true;
+
+  return comptypes (t1, t2);
+}
+
+/* Check if a type cast between two function types can be considered safe.  */
+
+static bool
+c_safe_function_type_cast_p (tree t1, tree t2)
+{
+  if (TREE_TYPE (t1) == void_type_node &&
+  TYPE_ARG_TYPES (t1) == void_list_node)
+return true;
+
+  if (TREE_TYPE (t2) == void_type_node &&
+  TYPE_ARG_TYPES (t2) == void_list_node)
+return true;
+
+  if (!c_abi_equiv_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+return false;
+
+  for (t1 = TYPE_ARG_TYPES (t1), t2 = TYPE_ARG_TYPES (t2);
+   t1 && t2;
+   t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
+if (!c_abi_equiv_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
+  return false;
+
+  return true;
+}
+
 /* Build an expression representing a cast to type TYPE of expression EXPR.
LOC is the location of the cast-- typically the open paren of the cast.  */
 
@@ -5667,6 +5713,16 @@ build_c_cast (location_t loc, tree type, tree expr
 	pedwarn (loc, OPT_Wpedantic, "ISO C forbids "
 		 "conversion of object pointer to function pointer type");
 
+  if (TREE_CODE (type) == POINTER_TYPE
+	  && TREE_CODE (otype) == POINTER_TYPE
+	  && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
+	  && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
+	  && !c_safe_function_type_cast_p (TREE_TYPE (type),
+	   TREE_TYPE (otype)))
+	warning_at (loc, OPT_Wcast_function_type,
+		"cast between incompatible function types"
+		" from %qT to %qT", otype, type);
+
   ovalue = value;
   value = convert (type, value);
 
Index: gcc/c-family/c-lex.c
===
--- gcc/c-family/c-lex.c	(revision 

[Patch, fortran] PR82375 - PDT components in PDT declarations fail to compile

2017-10-07 Thread Paul Richard Thomas
Dear All,

I ran into Ian Chivers in last week's BCS meeting, who told me that he
had found a PDT bug. My response was to post it on Bugzilla, which he
did promptly :-) So promptly, in fact, that I felt honour bound to
respond in kind.

Please find attached a patch to fix his bug and the extension to
recursive allocatable instead of pointer components. The third
testcase checks some tidying up in trans-array.c to stop valgrind
complaining about jumps on uninitialized variables.

It turns out that the earlier PDT tests that had PDT components in
module declarations all made use of the default parameter expressions.
Ian's bug exposed this and required the handiwork in module.c. This is
straightforward and involves the hijacking of actual_arglist service
functions as elsewhere in the initial PDT patch.

Once recursive allocatable PDT components are added, the compiler
tries to generate vtables and the associated procedures for the
template types. This of course yields nonsense and so
gfc_find_derived_vtab simply returns null.

The rest of the patch is adequately explained apart from the seemingly
trivial change in trans-decl.c. This problem was characterised by
double freeing of a PDT type, as it goes out of scope, in the
'finally' block. Clearly somebody is using 'tmp' uninitialized but I
am blowed if I can find the culprit. I have fixed it by setting it to
NULL_TREE after the intended use. This is not very satisfactory since
there is clearly a buglet lurking in the woods somewhere. My first
thought was that, since this seems to be PDT related, it must be
associated with the earlier PDT chunks. They all look to be clean,
however. I have commented accordingly.

Bootstraps and regtests on FC23/x86_64 - OK for trunk?

Now to turn to Reinhold Bader's really nasty PDT bug

Cheers

Paul

2017-10-07  Paul Thomas  

PR fortran/82375
* class.c (gfc_find_derived_vtab): Return NULL for a passed
pdt template to prevent bad procedures from being written.
* decl.c (gfc_get_pdt_instance): Do not use the default
initializer for pointer and allocatable pdt type components. If
the component is allocatbale, set the 'alloc_comp' attribute of
'instance'.
* module.c : Add a prototype for 'mio_actual_arglist'. Add a
boolean argument 'pdt'.
(mio_component): Call it for the parameter list of pdt type
components with 'pdt' set to true.
(mio_actual_arg): Add the boolean 'pdt' and, if it is set, call
mio_integer for the 'spec_type'.
(mio_actual_arglist): Add the boolean 'pdt' and use it in the
call to mio_actual_arg.
(mio_expr, mio_omp_udr_expr): Call mio_actual_arglist with
'pdt' set false.
* resolve.c (get_pdt_spec_expr): Add the parameter name to the
KIND parameter error.
(get_pdt_constructor): Check that cons->expr is non-null.
* trans-array.c (structure_alloc_comps): For deallocation of
allocatable components, ensure that parameterized components
are deallocated first. Likewise, when parameterized components
are allocated, nullify allocatable components first. Do not
recurse into pointer or allocatable pdt components while
allocating or deallocating parameterized components. Test that
parameterized arrays or strings are allocated before freeing
them.
(gfc_trans_pointer_assignment): Call the new function. Tidy up
a minor whitespace issue.
trans-decl.c (gfc_trans_deferred_vars): Set 'tmp' to NULL_TREE
to prevent the expression from being used a second time.

2017-10-07  Paul Thomas  

PR fortran/82375
* gfortran.dg/pdt_13.f03 : New test.
* gfortran.dg/pdt_14.f03 : New test.
* gfortran.dg/pdt_15.f03 : New test.


-- 
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein
Index: gcc/fortran/class.c
===
*** gcc/fortran/class.c (revision 253399)
--- gcc/fortran/class.c (working copy)
*** gfc_find_derived_vtab (gfc_symbol *deriv
*** 2211,2216 
--- 2211,2219 
gfc_gsymbol *gsym = NULL;
gfc_symbol *dealloc = NULL, *arg = NULL;
  
+   if (derived->attr.pdt_template)
+ return NULL;
+ 
/* Find the top-level namespace.  */
for (ns = gfc_current_ns; ns; ns = ns->parent)
  if (!ns->parent)
Index: gcc/fortran/decl.c
===
*** gcc/fortran/decl.c  (revision 253399)
--- gcc/fortran/decl.c  (working copy)
*** gfc_get_pdt_instance (gfc_actual_arglist
*** 3570,3576 
  type_param_spec_list = old_param_spec_list;
  
  c2->param_list = params;
! c2->initializer = gfc_default_initializer (>ts);
}
  }
  
--- 3570,3580 
  type_param_spec_list = old_param_spec_list;
  
  c2->param_list = params;
! if (!(c2->attr.pointer || c2->attr.allocatable))
!   c2->initializer = 

Re: [PATCH] Fortran -- Handle BOZ in accordance with F2008/2015.

2017-10-07 Thread Steve Kargl
On Sat, Oct 07, 2017 at 12:37:03PM +0200, Dominique d'Humières wrote:
> (1) Typo in gcc/fortran/array.c
> 
> +  /* If an array contains a BT_BOZ, then array elements need to be converted
> + an INTEGER.  This is an GNU Fortran extension.  Mixing BOZ and non-BOZ
> missing ‘to’?

Thanks.  I'll fix this

> 
> (2) Compiling
> 
> integer :: i = 1, j = 2
> print *, ble(i,j), blt(z'ff',z'fa')
> end
> 
> gives an ICE
> 
> f951: internal compiler error: in compare_bitwise, at fortran/simplify.c:1516
> 
> which is
> 
>   gcc_assert (i->ts.type == BT_INTEGER);
>   gcc_assert (j->ts.type == BT_INTEGER);

Whoops.  Forgot to check the bge, blt, etc simplification routines.

> 
> (3) Compiling (variant of pr54072)
> 
> USE, INTRINSIC :: ISO_C_BINDING
> IMPLICIT NONE
> INTEGER, PARAMETER :: GLbitfield=C_INT
> INTEGER(GLbitfield), PARAMETER :: GL_CURRENT_BIT = INT(z'0001') ! 
> 0x0001
> INTEGER(GLbitfield), PARAMETER :: GL_CLIENT_ALL_ATTRIB_BITS = &
> transfer(z'',GL_CURRENT_BIT) ! 0x

This is nonconforming code.  A BOZ cannot appear as an arg to transfer.

> print *, GLbitfield, GL_CURRENT_BIT, GL_CLIENT_ALL_ATTRIB_BITS
> END
> 
> gives an ICE
> 
> f951: internal compiler error: Invalid expression in gfc_element_size.

I'll need to check how we get to gfc_element size from the BOZ
in transfer.

> 
> (4) Compiling
> 
> print *, INT(z'',4)
> end
> 
> gives
> 
>  print *, INT(z'',4)
>  1
> Error: Arithmetic overflow converting INTEGER(-1) to INTEGER(4)
> at (1). This check can be disabled with the option '-fno-range-check’
> 
> Should not it be -1?

Maybe. :-)

See my note to Jerry about needing to implement F2015 16.3.3 correctly.
Upon sleeping on this deficiency, I realized that 16.3.3 without stating
allows one to set the sign-bit.  We find in 16.3.1 the statement

   The interpretation of a negative integer as a sequence of bits
   is processor dependent.

There is the bit model and integer model numbers.  F2015 contrasts the
models and concludes with 

   In particular, whereas the models are identical for r = 2 and
   $w_{z-1}$ = 0, they do not correspond for r = 2 or $w_{z-1} = 1$
   and the interpretation of bits in such objects is processor dependent.

> 
> (5) Compiling
> 
> print *, real(z'',4)
> end
> 
> gives
> 
>  print *, real(z'',4)
>   1
> Error: Arithmetic NaN converting REAL(4) to REAL(4) at (1).i
> This check can be disabled with the option '-fno-range-check’
> 
> Why not a warning?

Ask Tobias.  I retained his gfc_convert_boz function.  He
calls range_check() at the end.  You get this error prior
to my patch.

> (6) Compiling
> 
> print *, storage_size(z'')
> end
> 
> gives an ICE
> 
> f951: internal compiler error: Invalid expression in gfc_element_size.
> 
> The code is probably invalid, but I don’t know how to parse

Nonconforming code.  A BOZ cannot be an actual arg to storage_size.
In F2008/2015, a BOZ is a typeless and kindless entity.


16.9.184 STORAGE_SIZE (A [, KIND])
   A shall be a data object of any type.

7.1.2 Type classification

A type is either an intrinsic type or a derived type.

This document defines five intrinsic types: integer, real, complex,
character, and logical.

A derived type is one that is defined by a derived-type definition
(7.5.2) or by an intrinsic module.

7.7 Binary, octal, and hexadecimal literal constants

A binary, octal, or hexadecimal constant (boz-literal-constant) is a
sequence of digits that represents an ordered sequence of bits. Such a
constant has no type.

> 
> Without the patch it returns 128 at run time.
> 

That's because 13 to 15 years, I made gfortran convert a BOZ
to INTEGER(gfc_max_integer_kind) when a BOZ was parsed.  The
internal representation a BOZ is INTEGER, so storage_size 
thinks it is an integer.

-- 
Steve
20170425 https://www.youtube.com/watch?v=VWUpyCsUKR4
20161221 https://www.youtube.com/watch?v=IbCHE-hONow


[PATCH]C++/PR80188: Add correct marco call to error_at call in maybe_complain_about_tail_call

2017-10-07 Thread Nicholas Krause
This fixes maybe_complain_about_tail_call to in correctly use the marco, _ 
around reason in the
call to error_at. This fixes the issue with only the first part of the function 
being
correctly translated to English when translation is done. Passes standard 
testing on 
x86_64_linux_gnu without any new regressions. Ok for trunk?

Signed-off-by: Nicholas Krause 
---
 gcc/calls.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/calls.c b/gcc/calls.c
index 72cf9e016c8..38b4dc7617b 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1515,7 +1515,7 @@ maybe_complain_about_tail_call (tree call_expr, const 
char *reason)
   if (!CALL_EXPR_MUST_TAIL_CALL (call_expr))
 return;
 
-  error_at (EXPR_LOCATION (call_expr), "cannot tail-call: %s", reason);
+  error_at (EXPR_LOCATION (call_expr), "cannot tail-call: %s", _(reason));
 }
 
 /* Fill in ARGS_SIZE and ARGS array based on the parameters found in
-- 
2.11.0



Re: [PATCH] Fix PR82397

2017-10-07 Thread Richard Sandiford
Richard Biener  writes:
> I am testing the following patch to fix the qsort intransitiveness
> of dr_group_sort_cmp.  The patch removes the overly powerful
> operand_equal_p checks (handling commutativity )
> because those do not mix well with the sorting constraints.
>
> I am also testing a followup to address the missed equalities by
> canonicalization -- the interesting trees happen to be all built
> by split_constant_offset where we can do some elaborate canonicalization
> in linear complexity (as opposed to operand_equal_p's exponential
> handling or trying to handle it in data_ref_compare_tree where it would
> be done at least multiple times during qsort invocation).
>
> Bootstrapped on x86_64-unknown-linux-gnu, testing still in progress
> (so is a quick SPEC 2k6 build where the issue showed up in multiple
> places).
>
> Richard.
>
> 2017-10-06  Richard Biener  
>
>   PR tree-optimization/82397
>   * tree-vect-data-refs.c (dr_group_sort_cmp): Do not use
>   operand_equal_p but rely on data_ref_compare_tree for detecting
>   equalities.
>   (vect_analyze_data_ref_accesses): Use data_ref_compare_tree
>   to match up with dr_group_sort_cmp.
>
>   * gfortran.dg/pr82397.f: New testcase.
>
> Index: gcc/tree-vect-data-refs.c
> ===
> --- gcc/tree-vect-data-refs.c (revision 253475)
> +++ gcc/tree-vect-data-refs.c (working copy)
> @@ -2727,43 +2727,30 @@ dr_group_sort_cmp (const void *dra_, con
>  return loopa->num < loopb->num ? -1 : 1;
>  
>/* Ordering of DRs according to base.  */
> -  if (!operand_equal_p (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb), 0))
> -{
> -  cmp = data_ref_compare_tree (DR_BASE_ADDRESS (dra),
> -DR_BASE_ADDRESS (drb));
> -  if (cmp != 0)
> -return cmp;
> -}
> +  cmp = data_ref_compare_tree (DR_BASE_ADDRESS (dra),
> +DR_BASE_ADDRESS (drb));
> +  if (cmp != 0)
> +return cmp;
>  
>/* And according to DR_OFFSET.  */
> -  if (!dr_equal_offsets_p (dra, drb))
> -{
> -  cmp = data_ref_compare_tree (DR_OFFSET (dra), DR_OFFSET (drb));
> -  if (cmp != 0)
> -return cmp;
> -}
> +  cmp = data_ref_compare_tree (DR_OFFSET (dra), DR_OFFSET (drb));
> +  if (cmp != 0)
> +return cmp;
>  
>/* Put reads before writes.  */
>if (DR_IS_READ (dra) != DR_IS_READ (drb))
>  return DR_IS_READ (dra) ? -1 : 1;
>  
>/* Then sort after access size.  */
> -  if (!operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))),
> - TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb))), 0))
> -{
> -  cmp = data_ref_compare_tree (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))),
> -TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb;
> -  if (cmp != 0)
> -return cmp;
> -}
> +  cmp = data_ref_compare_tree (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))),
> +TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb;
> +  if (cmp != 0)
> +return cmp;
>  
>/* And after step.  */
> -  if (!operand_equal_p (DR_STEP (dra), DR_STEP (drb), 0))
> -{
> -  cmp = data_ref_compare_tree (DR_STEP (dra), DR_STEP (drb));
> -  if (cmp != 0)
> -return cmp;
> -}
> +  cmp = data_ref_compare_tree (DR_STEP (dra), DR_STEP (drb));
> +  if (cmp != 0)
> +return cmp;
>  
>/* Then sort after DR_INIT.  In case of identical DRs sort after stmt UID. 
>  */
>cmp = tree_int_cst_compare (DR_INIT (dra), DR_INIT (drb));
> @@ -2835,9 +2822,9 @@ vect_analyze_data_ref_accesses (vec_info
>and they are both either store or load (not load and store,
>not masked loads or stores).  */
> if (DR_IS_READ (dra) != DR_IS_READ (drb)
> -   || !operand_equal_p (DR_BASE_ADDRESS (dra),
> -DR_BASE_ADDRESS (drb), 0)
> -   || !dr_equal_offsets_p (dra, drb)
> +   || data_ref_compare_tree (DR_BASE_ADDRESS (dra),
> + DR_BASE_ADDRESS (drb)) != 0
> +   || data_ref_compare_tree (DR_OFFSET (dra), DR_OFFSET (drb)) != 0
> || !gimple_assign_single_p (DR_STMT (dra))
> || !gimple_assign_single_p (DR_STMT (drb)))
>   break;
> @@ -2851,7 +2838,7 @@ vect_analyze_data_ref_accesses (vec_info
>   break;
>  
> /* Check that the data-refs have the same step.  */
> -   if (!operand_equal_p (DR_STEP (dra), DR_STEP (drb), 0))
> +   if (data_ref_compare_tree (DR_STEP (dra), DR_STEP (drb)) != 0)
>   break;
>  
> /* Do not place the same access in the interleaving chain twice.  */

I don't think data_ref_compare_tree is strong enough to replace
operand_equal_p when equality is needed for correctness.
A lot of data_ref_compare_tree just uses hash values and can
return 0 for things that aren't actually equal.  (Although maybe
that's the 

Re: [PATCH] Fortran -- Handle BOZ in accordance with F2008/2015.

2017-10-07 Thread Dominique d'Humières
Thanks for working on the issue. While testing your patch I have found the 
following problems:

(1) Typo in gcc/fortran/array.c

+  /* If an array contains a BT_BOZ, then array elements need to be converted
+ an INTEGER.  This is an GNU Fortran extension.  Mixing BOZ and non-BOZ
missing ‘to’?

(2) Compiling

integer :: i = 1, j = 2
print *, ble(i,j), blt(z'ff',z'fa')
end

gives an ICE

f951: internal compiler error: in compare_bitwise, at fortran/simplify.c:1516

which is

  gcc_assert (i->ts.type == BT_INTEGER);
  gcc_assert (j->ts.type == BT_INTEGER);

(3) Compiling (variant of pr54072)

USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
INTEGER, PARAMETER :: GLbitfield=C_INT
INTEGER(GLbitfield), PARAMETER :: GL_CURRENT_BIT = INT(z'0001') ! 0x0001
INTEGER(GLbitfield), PARAMETER :: GL_CLIENT_ALL_ATTRIB_BITS = &
transfer(z'',GL_CURRENT_BIT) ! 0x
print *, GLbitfield, GL_CURRENT_BIT, GL_CLIENT_ALL_ATTRIB_BITS
END

gives an ICE

f951: internal compiler error: Invalid expression in gfc_element_size.

(4) Compiling

print *, INT(z'',4)
end

gives

 print *, INT(z'',4)
 1
Error: Arithmetic overflow converting INTEGER(-1) to INTEGER(4) at (1). This 
check can be disabled with the option '-fno-range-check’

Should not it be -1?

(5) Compiling

print *, real(z'',4)
end

gives

 print *, real(z'',4)
  1
Error: Arithmetic NaN converting REAL(4) to REAL(4) at (1). This check can be 
disabled with the option '-fno-range-check’

Why not a warning?

(6) Compiling

print *, storage_size(z'')
end

gives an ICE

f951: internal compiler error: Invalid expression in gfc_element_size.

The code is probably invalid, but I don’t know how to parse

> The processor shall allow the position of the leftmost nonzero bit to be at 
> least z - 1,
> where z is the maximum value that could result from invoking the intrinsic 
> function
> STORAGE_SIZE (13.8.175) with an argument that is a real or integer scalar of 
> any kind
> supported by the processor.

Without the patch it returns 128 at run time.

Dominique



[openacc, testsuite, committed] Fix libgomp.oacc-fortran/{firstprivate-1,parallel-reduction}.f90 for non-nvidia devices

2017-10-07 Thread Tom de Vries
[ was: Re: [openacc, testsuite, committed] Fix 
libgomp.oacc-c-c++-common/parallel-reduction.c for non-nvidia devices ]

On 09/27/2017 02:39 PM, Tom de Vries wrote:

Hi,

this patch makes the test-case 
libgomp.oacc-c-c++-common/parallel-reduction.c work for non-nvidia devices.


Committed this similar patch.

Thanks,
- Tom
Fix libgomp.oacc-fortran/{firstprivate-1,parallel-reduction}.f90 for non-nvidia devices

2017-10-07  Tom de Vries  

	* testsuite/libgomp.oacc-fortran/firstprivate-1.f90 (firstprivate):
	Remove acc_device_nvidia references.
	* testsuite/libgomp.oacc-fortran/parallel-reduction.f90 (reduction):
	Same.

---
 libgomp/testsuite/libgomp.oacc-fortran/firstprivate-1.f90 | 2 +-
 libgomp/testsuite/libgomp.oacc-fortran/parallel-reduction.f90 | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-1.f90
index d3f9093..3866096 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/firstprivate-1.f90
@@ -5,7 +5,7 @@ program firstprivate
   integer :: a, b(Nupper), c, d, n
   include "openacc_lib.h"
 
-  if (acc_get_device_type () .eq. acc_device_nvidia) then
+  if (acc_get_device_type () .ne. acc_device_host) then
  n = Nupper
   else
  n = 1
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/parallel-reduction.f90 b/libgomp/testsuite/libgomp.oacc-fortran/parallel-reduction.f90
index 31db7e1..d0559a2 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/parallel-reduction.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/parallel-reduction.f90
@@ -15,7 +15,7 @@ program reduction
   s2 = s2 + 1
   !$acc end parallel
 
-  if (acc_get_device_type () .eq. acc_device_nvidia) then
+  if (acc_get_device_type () .ne. acc_device_host) then
  if (s1 .ne. n) call abort
  if (s2 .ne. n) call abort
   else
@@ -29,7 +29,7 @@ program reduction
   s2 = 0
   call redsub (s1, s2, n)
 
-  if (acc_get_device_type () .eq. acc_device_nvidia) then
+  if (acc_get_device_type () .ne. acc_device_host) then
  if (s1 .ne. n) call abort
   else
  if (s2 .ne. 1) call abort