Re: C++ PATCH for c++/89852 - ICE with C++11 functional cast with { }

2019-03-30 Thread Jason Merrill

On 3/29/19 5:37 PM, Marek Polacek wrote:

On Fri, Mar 29, 2019 at 05:29:27PM -0400, Jason Merrill wrote:

On 3/29/19 4:25 PM, Marek Polacek wrote:

On Thu, Mar 28, 2019 at 02:55:55PM -0400, Jason Merrill wrote:

On 3/27/19 5:45 PM, Marek Polacek wrote:

Here we have a non-dependent constructor in a template:

 { VIEW_CONVERT_EXPR(j) }

In digest_init we call massage_init_elt, which calls digest_init_r on the
element.  We convert the element, but we're in a template, so
perform_implicit_conversion added an IMPLICIT_CONV_EXPR around it.  And then
massage_init_elt calls maybe_constant_init on the element and the usual sadness
ensues.


Only after fold_non_dependent_expr.  Perhaps we want a
fold_non_dependent_init?


Yeah, I recall we talked about adding fold_non_dependent_init a year ago.

Using it here works -- in a template, we won't call maybe_constant_*, so
there's no crash.

Bootstrapped/regtested on x86_64-linux, ok for trunk?



2019-03-29  Marek Polacek  

PR c++/89852 - ICE with C++11 functional cast with { }.
* constexpr.c (fold_non_dependent_expr_template): New static function
broken out of...
(fold_non_dependent_expr): ...here.
(fold_non_dependent_init): New function.
* cp-tree.h (fold_non_dependent_init): Declare.
* typeck2.c (massage_init_elt): Call fold_non_dependent_init instead
of fold_non_dependent_expr.  Don't call maybe_constant_init.

@@ -5604,51 +5656,29 @@ fold_non_dependent_expr (tree t,
 if (t == NULL_TREE)
   return NULL_TREE;
+  if (processing_template_decl)
+return fold_non_dependent_expr_template (t, complain,
+manifestly_const_eval);
+  return maybe_constant_value (t, NULL_TREE, manifestly_const_eval);
+}
+tree
+fold_non_dependent_init (tree t,
+tsubst_flags_t complain /*=tf_warning_or_error*/,
+bool manifestly_const_eval /*=false*/)
+{
+  if (t == NULL_TREE)
+return NULL_TREE;
+  if (processing_template_decl)
+return fold_non_dependent_expr_template (t, complain,
+manifestly_const_eval);


Don't we still need the maybe_constant_init TARGET_EXPR stripping behavior
in a template?


It would seem that we don't need it, since nothing broke.  But this patch
includes the stripping.

Bootstrap/regtest running on x86_64-linux, ok for trunk?

2019-03-29  Marek Polacek  

PR c++/89852 - ICE with C++11 functional cast with { }.
* constexpr.c (fold_non_dependent_expr_template): New static function
broken out of...
(fold_non_dependent_expr): ...here.
(fold_non_dependent_init): New function.
* cp-tree.h (fold_non_dependent_init): Declare.
* typeck2.c (massage_init_elt): Call fold_non_dependent_init instead
of fold_non_dependent_expr.  Don't call maybe_constant_init.


OK.


* g++.dg/cpp0x/initlist115.C: New test.

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index daf34e10784..53854a8acd4 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -5581,6 +5581,58 @@ clear_cv_and_fold_caches (void)
clear_fold_cache ();
  }
  
+/* Internal function handling expressions in templates for

+   fold_non_dependent_expr and fold_non_dependent_init.
+
+   If we're in a template, but T isn't value dependent, simplify
+   it.  We're supposed to treat:
+
+ template  void f(T[1 + 1]);
+ template  void f(T[2]);
+
+   as two declarations of the same function, for example.  */
+
+static tree
+fold_non_dependent_expr_template (tree t, tsubst_flags_t complain,
+ bool manifestly_const_eval)
+{
+  gcc_assert (processing_template_decl);
+
+  if (is_nondependent_constant_expression (t))
+{
+  processing_template_decl_sentinel s;
+  t = instantiate_non_dependent_expr_internal (t, complain);
+
+  if (type_unknown_p (t) || BRACE_ENCLOSED_INITIALIZER_P (t))
+   {
+ if (TREE_OVERFLOW_P (t))
+   {
+ t = build_nop (TREE_TYPE (t), t);
+ TREE_CONSTANT (t) = false;
+   }
+ return t;
+   }
+
+  tree r = cxx_eval_outermost_constant_expr (t, true, true,
+manifestly_const_eval,
+NULL_TREE);
+  /* cp_tree_equal looks through NOPs, so allow them.  */
+  gcc_checking_assert (r == t
+  || CONVERT_EXPR_P (t)
+  || TREE_CODE (t) == VIEW_CONVERT_EXPR
+  || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
+  || !cp_tree_equal (r, t));
+  return r;
+}
+  else if (TREE_OVERFLOW_P (t))
+{
+  t = build_nop (TREE_TYPE (t), t);
+  TREE_CONSTANT (t) = false;
+}
+
+  return t;
+}
+
  /* Like maybe_constant_value but first fully instantiate the argument.
  
 Note: this is equivalent to 

[PATCH, d] Committed merge with upstream dmd

2019-03-30 Thread Iain Buclaw
Hi,

The patch merges the D front-end implementation with dmd upstream 5dd3eccc3.

Aligns the test flags between gcc and upstream, after adding support
to gdc-test.exp to handle extra source and file settings being passed
multiple times.

Regression tested on x86_64-linux-gnu.

Committed to trunk as r270038.

-- 
Iain
---
gcc/testsuite/ChangeLog:

2019-03-30  Iain Buclaw  

* gdc.test/gdc-test.exp (gdc-copy-extra): Append copied files to
cleanup_extra_files.
(dmd2dg): Copy additional files after test is translated.
(gdc-do-test): Remove all copied files after test.

---
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index ffad6cb524d..31ea106965b 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-ab702e73e56aefb3b77b8f8f42da94bc22143eeb
+5dd3eccc3b0758346f77bee3cdc3f6bd15de339b
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/testsuite/gdc.test/compilable/test6395.d b/gcc/testsuite/gdc.test/compilable/test6395.d
index 95f1a7eae6e..a1bac8e48f1 100644
--- a/gcc/testsuite/gdc.test/compilable/test6395.d
+++ b/gcc/testsuite/gdc.test/compilable/test6395.d
@@ -1,5 +1,6 @@
-// REQUIRED_ARGS: -c -Icompilable/extra-files
+// REQUIRED_ARGS: -Icompilable/extra-files
 // EXTRA_SOURCES: b6395.d
+// EXTRA_FILES: extra-files/c6395.d
 
 // 6395
 
diff --git a/gcc/testsuite/gdc.test/compilable/test7190.d b/gcc/testsuite/gdc.test/compilable/test7190.d
index 5143f55e772..45344f13b8f 100644
--- a/gcc/testsuite/gdc.test/compilable/test7190.d
+++ b/gcc/testsuite/gdc.test/compilable/test7190.d
@@ -1,6 +1,9 @@
 // PERMUTE_ARGS:
 // REQUIRED_ARGS: -Icompilable/extra-files
-// EXTRA_FILES: extra-files/example7190/controllers/HomeController.d extra-files/example7190/models/HomeModel.d extra-files/serenity7190/core/Controller.d  extra-files/serenity7190/core/Model.d
+// EXTRA_FILES: extra-files/example7190/controllers/HomeController.d
+// EXTRA_FILES: extra-files/example7190/models/HomeModel.d
+// EXTRA_FILES: extra-files/serenity7190/core/Controller.d
+// EXTRA_FILES: extra-files/serenity7190/core/Model.d
 
 import example7190.controllers.HomeController;
 import example7190.models.HomeModel;
diff --git a/gcc/testsuite/gdc.test/compilable/test9436.d b/gcc/testsuite/gdc.test/compilable/test9436.d
index c80bdc59e82..2baee7c216b 100644
--- a/gcc/testsuite/gdc.test/compilable/test9436.d
+++ b/gcc/testsuite/gdc.test/compilable/test9436.d
@@ -1,4 +1,3 @@
-// REQUIRED_ARGS: -c
 // EXTRA_SOURCES: imports/test9436interp.d
 
 // this is a dummy module for test 9436.
diff --git a/gcc/testsuite/gdc.test/compilable/testDIP37.d b/gcc/testsuite/gdc.test/compilable/testDIP37.d
index a612365eaf4..7188758414c 100644
--- a/gcc/testsuite/gdc.test/compilable/testDIP37.d
+++ b/gcc/testsuite/gdc.test/compilable/testDIP37.d
@@ -1,6 +1,9 @@
 // PERMUTE_ARGS:
 // REQUIRED_ARGS: -Icompilable/extra-files
-// EXTRA_FILES: extra-files/pkgDIP37/datetime/package.d extra-files/pkgDIP37/datetime/common.d extra-files/pkgDIP37/test17629/package.di extra-files/pkgDIP37/test17629/common.di
+// EXTRA_FILES: extra-files/pkgDIP37/datetime/package.d
+// EXTRA_FILES: extra-files/pkgDIP37/datetime/common.d
+// EXTRA_FILES: extra-files/pkgDIP37/test17629/package.di
+// EXTRA_FILES: extra-files/pkgDIP37/test17629/common.di
 
 void test1()
 {
diff --git a/gcc/testsuite/gdc.test/compilable/testDIP37_10302.d b/gcc/testsuite/gdc.test/compilable/testDIP37_10302.d
index 7e76595f06f..3c4a409b709 100644
--- a/gcc/testsuite/gdc.test/compilable/testDIP37_10302.d
+++ b/gcc/testsuite/gdc.test/compilable/testDIP37_10302.d
@@ -1,6 +1,7 @@
 // PERMUTE_ARGS:
-// REQUIRED_ARGS: -c -Icompilable/extra-files
-// EXTRA_SOURCES: extra-files/pkgDIP37_10302/liba.d extra-files/pkgDIP37_10302/libb.d
+// REQUIRED_ARGS: -Icompilable/extra-files
+// COMPILED_IMPORTS: extra-files/pkgDIP37_10302/liba.d
+// COMPILED_IMPORTS: extra-files/pkgDIP37_10302/libb.d
 // EXTRA_FILES: extra-files/pkgDIP37_10302/package.d
 
 module test;
diff --git a/gcc/testsuite/gdc.test/compilable/testDIP37_10354.d b/gcc/testsuite/gdc.test/compilable/testDIP37_10354.d
index 2993fa94d39..f9adf86307c 100644
--- a/gcc/testsuite/gdc.test/compilable/testDIP37_10354.d
+++ b/gcc/testsuite/gdc.test/compilable/testDIP37_10354.d
@@ -1,6 +1,8 @@
 // PERMUTE_ARGS:
 // REQUIRED_ARGS: -o- -Icompilable/extra-files
-// EXTRA_FILES: extra-files/pkgDIP37_10354/mbar.d extra-files/pkgDIP37_10354/mfoo.d extra-files/pkgDIP37_10354/package.d
+// EXTRA_FILES: extra-files/pkgDIP37_10354/mbar.d
+// EXTRA_FILES: extra-files/pkgDIP37_10354/mfoo.d
+// EXTRA_FILES: extra-files/pkgDIP37_10354/package.d
 
 module testDIP37_10354;
 import pkgDIP37_10354.mfoo;
diff --git a/gcc/testsuite/gdc.test/compilable/testDIP37_10421.d b/gcc/testsuite/gdc.test/compilable/testDIP37_10421.d
index 859347331b1..7da5bcf2d08 100644
--- a/gcc/testsuite/gdc.test/compilable/testDIP37_10421.d
+++ b/gcc/testsuite/gdc.test/compilable/testDIP37_10421.d
@@ -1,6 

[PATCH] Fix function, tsubst_requires_expr for callers to tsubst_constraint_variables

2019-03-30 Thread Nicholas Krause
This fixes both callers in tsubst_requires_expr to
tsubst_constraint_variables to wrap their respective
trees in PARM_CONSTR_PARMS. This is to get the correct
parmeter constraints from the tree before calling
tsubst_constraint_variables like other callers
in constraint.cc and to avoid subtle bugs in the
future.

Signed-off-by: Nicholas Krause 
---
 gcc/cp/constraint.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 9884eb0db50..cb06d0ec6e2 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1882,13 +1882,13 @@ tsubst_requires_expr (tree t, tree args,
   tree parms = TREE_OPERAND (t, 0);
   if (parms)
 {
-  parms = tsubst_constraint_variables (parms, args, complain, in_decl);
+  parms = tsubst_constraint_variables (PARM_CONSTR_PARMS (parms), args, 
complain, in_decl);
   if (parms == error_mark_node)
 return error_mark_node;
 }
 
   tree reqs = TREE_OPERAND (t, 1);
-  reqs = tsubst_requirement_body (reqs, args, complain, in_decl);
+  reqs = tsubst_requirement_body (PARM_CONSTR_PARMS (reqs), args, complain, 
in_decl);
   if (reqs == error_mark_node)
 return error_mark_node;
 
-- 
2.17.1



Re: [Patch, fortran] PR89841 - improper descriptor information passed to C

2019-03-30 Thread Dominique d'Humières
Hi Paul,

> While I was about it, I committed the fix for PR89841 with the fix for
> PR89842. The latter is even safer than the former.

This also fixes PR89844.

Thanks,

Dominique


[v3 PATCH] Use single-visitation in variant assignment and swap.

2019-03-30 Thread Ville Voutilainen
This patch makes assignments correct, because they need to
match indices instead of types. In addition, we cut down the
codegen size. The symbols are longer than before, the the amount
of them is roughly the same, so there's no longer an explosion
in their amount.

Relops are the last bit in these fixes, I'll fix them during the weekend.

2019-03-30  Ville Voutilainen  

Use single-visitation in variant assignment and swap.
Also use indices instead of types when checking whether
variants hold the same thing.
* include/std/variant (__do_visit): Add a template parameter
for index visitation, invoke with indices if index visitation
is used.
(__variant_idx_cookie): New.
(_Copy_assign_base::operator=): Do single-visitation with
an index visitor.
(_Move_assign_base::operator=): Likewise.
(_Extra_visit_slot_needed): Adjust.
(__visit_invoke): Call with indices if it's an index visitor.
(swap): Do single-visitation with an index visitor.
(__visitor_result_type): New.
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 7fd6947..3ee1cbd 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -138,7 +138,7 @@ namespace __variant
 constexpr variant_alternative_t<_Np, variant<_Types...>> const&&
 get(const variant<_Types...>&&);
 
-  template
+  template
 constexpr decltype(auto)
 __do_visit(_Visitor&& __visitor, _Variants&&... __variants);
 
@@ -175,6 +175,10 @@ namespace __variant
 
   // used for raw visitation
   struct __variant_cookie {};
+  // used for raw visitation with indices passed in
+  struct __variant_idx_cookie {};
+  // a more explanatory name than 'true'
+  inline constexpr auto __visit_with_index = bool_constant{};
 
   // _Uninitialized is guaranteed to be a literal type, even if T is not.
   // We have to do this, because [basic.types]p10.5.3 (n4606) is not implemented
@@ -570,45 +574,44 @@ namespace __variant
   operator=(const _Copy_assign_base& __rhs)
 	  noexcept(_Traits<_Types...>::_S_nothrow_copy_assign)
   {
-	__do_visit([this, &__rhs](auto&& __this_mem, auto&& __rhs_mem) mutable
-		   -> __detail::__variant::__variant_cookie
+	__do_visit<__visit_with_index>([this](auto&& __rhs_mem,
+	  auto __rhs_index) mutable
+	-> __detail::__variant::__variant_idx_cookie
 	  {
-	if constexpr (is_same_v<
-			remove_reference_t,
-			remove_reference_t>)
+	if constexpr (__rhs_index != variant_npos)
 	  {
-		if constexpr (!is_same_v<
-			remove_reference_t,
-			__variant_cookie>)
-		  __this_mem = __rhs_mem;
-	  }
-	else
-	  {
-		if constexpr (!is_same_v<
-			remove_reference_t,
-			__variant_cookie>)
+		if (this->_M_index == __rhs_index)
 		  {
-		using __rhs_type =
-		  remove_reference_t;
-		if constexpr (is_nothrow_copy_constructible_v<__rhs_type>
-		  || !is_nothrow_move_constructible_v<__rhs_type>)
+		if constexpr (__rhs_index != variant_npos)
 		  {
-			this->_M_destructive_copy(__rhs._M_index, __rhs_mem);
+			auto& __this_mem =
+			  __get<__rhs_index>(*this);
+			if constexpr (is_same_v<
+  remove_reference_t,
+  remove_reference_t>)
+			  __this_mem = __rhs_mem;
 		  }
+		  }
+		else
+		  {
+		using __rhs_type =
+		  remove_reference_t;
+		if constexpr
+		  (is_nothrow_copy_constructible_v<__rhs_type>
+		   || !is_nothrow_move_constructible_v<__rhs_type>)
+			this->_M_destructive_copy(__rhs_index, __rhs_mem);
 		else
 		  {
 			auto __tmp(__rhs_mem);
-			this->_M_destructive_move(__rhs._M_index,
+			this->_M_destructive_move(__rhs_index,
 		  std::move(__tmp));
 		  }
 		  }
-		else
-		  {
-		this->_M_reset();
-		  }
 	  }
-	  return {};
-	}, __variant_cast<_Types...>(*this), __variant_cast<_Types...>(__rhs));
+	else
+	  this->_M_reset();
+	return {};
+	  }, __variant_cast<_Types...>(__rhs));
 	__glibcxx_assert(this->_M_index == __rhs._M_index);
 	return *this;
   }
@@ -641,25 +644,32 @@ namespace __variant
   operator=(_Move_assign_base&& __rhs)
 	  noexcept(_Traits<_Types...>::_S_nothrow_move_assign)
   {
-	__do_visit([this, &__rhs](auto&& __this_mem, auto&& __rhs_mem) mutable
-		   -> __detail::__variant::__variant_cookie
+	__do_visit<__visit_with_index>([this](auto&& __rhs_mem,
+	  auto __rhs_index) mutable
+	-> __detail::__variant::__variant_idx_cookie
 	  {
-	if constexpr (is_same_v<
-			remove_reference_t,
-			remove_reference_t>)
+	if constexpr (__rhs_index != variant_npos)
 	  {
-		if constexpr (!is_same_v<
-			remove_reference_t,
-			__variant_cookie>)
-		  __this_mem = std::move(__rhs_mem);
+		if (this->_M_index == __rhs_index)
+		  {
+		if constexpr (__rhs_index != variant_npos)
+		  {
+			auto& __this_mem =
+			  __get<__rhs_index>(*this);
+			if constexpr (is_same_v<
+  remove_reference_t,
+			

Re: [Patch, fortran] PR89841 - improper descriptor information passed to C

2019-03-30 Thread Paul Richard Thomas
Hi Steve,

Sorry about the delay. Daytime stuff caught up with me.

While I was about it, I committed the fix for PR89841 with the fix for
PR89842. The latter is even safer than the former.

Committed as revision 270037.

Thanks

Paul

2019-03-30  Paul Thomas  

PR fortran/89841
* trans-expr.c (gfc_conv_gfc_desc_to_cfi_desc): Use the formal
argument attributes rather than those of the actual argument.

PR fortran/89842
* trans-expr.c (gfc_conv_gfc_desc_to_cfi_desc): Call
'set_dtype_for_unallocated' for any type of arrayspec.

2019-03-30  Paul Thomas  

PR fortran/89841
* gfortran.dg/ISO_Fortran_binding_1.f90: Change the interfaces
for c_deallocate, c_allocate and c_assumed_size so that the
attributes of the array arguments are correct and are typed.
* gfortran.dg/ISO_Fortran_binding_7.f90: New test.
* gfortran.dg/ISO_Fortran_binding_7.c: Additional source.

PR fortran/89842
* gfortran.dg/ISO_Fortran_binding_8.f90: New test.
* gfortran.dg/ISO_Fortran_binding_8.c: Additional source.

On Wed, 27 Mar 2019 at 18:55, Steve Kargl
 wrote:
>
> On Wed, Mar 27, 2019 at 06:50:41PM +, Paul Richard Thomas wrote:
> > This corrects a screw-up on my part. The attribute field of the CFI
> > descriptor must be set by the formal argument in the interface and not
> > the actual argument.
> >
> > Most of the work was in correcting
> >
> > Bootstrapped and regtested on FC29/x86_64 - OK for trunk?
> >
>
> OK.
>
> --
> Steve



-- 
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein


[C++ PATCH] PR c++/89744 - ICE with specialization of member class template.

2019-03-30 Thread Jason Merrill
My fix five years ago for PR 60241 was incomplete: when we reassign implicit
instances of a partial instantiation of a member template to the explicit
specialization of that partial instantiation, we also need to adjust the
CLASSTYPE_TI_ARGS to match what we'd get when looking up that instance after
the explicit specialization.  We also need to do this when we later look up
the instance in a way that only finds the explicit specialization halfway
through lookup_template_class_1.

Tested x86_64-pc-linux-gnu, applying to trunk.

* pt.c (lookup_template_class_1): If the partial instantiation is
explicitly specialized, adjust.
(maybe_process_partial_specialization): Also adjust
CLASSTYPE_TI_ARGS.
---
 gcc/cp/cp-tree.h  | 10 +++-
 gcc/cp/pt.c   | 14 -
 gcc/testsuite/g++.dg/template/mem-spec1.C | 68 +++
 gcc/cp/ChangeLog  |  8 +++
 4 files changed, 98 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/mem-spec1.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fd612b0dbb1..59152753825 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3534,7 +3534,15 @@ struct GTY(()) lang_decl {
   template  struct S {};
   template  struct S {};
   
-   the CLASSTPYE_TI_TEMPLATE for S will be S, not the S.  */
+   the CLASSTPYE_TI_TEMPLATE for S will be S, not the S.
+
+   For a member class template, CLASSTYPE_TI_TEMPLATE always refers to the
+   partial instantiation rather than the primary template.  CLASSTYPE_TI_ARGS
+   are for the primary template if the partial instantiation isn't
+   specialized, or for the explicit specialization if it is, e.g.
+
+  template  class C { template  class D; }
+  template <> template  class C::D;  */
 #define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO 
(NODE))
 #define CLASSTYPE_TI_ARGS(NODE) TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE))
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 91c341589be..f3faa89f671 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1090,7 +1090,8 @@ maybe_process_partial_specialization (tree type)
  type_specializations->remove_elt ();
 
  elt.tmpl = tmpl;
- elt.args = INNERMOST_TEMPLATE_ARGS (elt.args);
+ CLASSTYPE_TI_ARGS (inst)
+   = elt.args = INNERMOST_TEMPLATE_ARGS (elt.args);
 
  spec_entry **slot
= type_specializations->find_slot (, INSERT);
@@ -9662,6 +9663,16 @@ lookup_template_class_1 (tree d1, tree arglist, tree 
in_decl, tree context,
   : (TREE_CODE (found) == TYPE_DECL
  ? DECL_TI_TEMPLATE (found)
  : CLASSTYPE_TI_TEMPLATE (found)));
+
+ if (DECL_CLASS_TEMPLATE_P (found)
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (found)))
+   {
+ /* If this partial instantiation is specialized, we want to
+use it for hash table lookup.  */
+ elt.tmpl = found;
+ elt.args = arglist = INNERMOST_TEMPLATE_ARGS (arglist);
+ hash = spec_hasher::hash ();
+   }
}
 
   // Build template info for the new specialization.
@@ -9669,6 +9680,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree 
in_decl, tree context,
 
   elt.spec = t;
   slot = type_specializations->find_slot_with_hash (, hash, INSERT);
+  gcc_checking_assert (*slot == NULL);
   entry = ggc_alloc ();
   *entry = elt;
   *slot = entry;
diff --git a/gcc/testsuite/g++.dg/template/mem-spec1.C 
b/gcc/testsuite/g++.dg/template/mem-spec1.C
new file mode 100644
index 000..b06df0aa84e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/mem-spec1.C
@@ -0,0 +1,68 @@
+// PR c++/89744
+
+namespace N1 {
+  template struct A
+  {
+template struct B {};
+A() { B b; }
+  };
+
+  template<> template
+  struct A::B
+  {
+virtual void foo() {}
+  };
+
+  A a;
+}
+
+namespace N2 {
+  template struct A
+  {
+template struct B {};
+A() { B b; }
+  };
+
+  template<> template
+  struct A::B
+  {
+virtual void foo() {}
+void bar() {}
+  };
+
+  A a;
+}
+
+namespace N3 {
+  template struct A
+  {
+template struct B {};
+A() { B b; }
+  };
+
+  template<> template
+  struct A::B
+  {
+~B() {}
+  };
+
+  A a;
+}
+
+#if __cpp_variadic_templates
+namespace N4 {
+  template struct A
+  {
+template struct B {};
+typedef B X;
+  };
+
+  template<> template
+  struct A::B
+  {
+typedef int Y;
+  };
+
+  A::B b;
+}
+#endif
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a31e4391e21..8a5e9209b34 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2019-03-30  Jason Merrill  
+
+   PR c++/89744 - ICE with specialization of member class template.
+   * pt.c (lookup_template_class_1): If the partial instantiation is
+   explicitly 

Re: [Patch, fortran] PR87127 - External function not recognised from within an associate block

2019-03-30 Thread Thomas Koenig

Hi Paul,


Bootstrapped and regtested on FC29/x86_64 - OK for trunk?


OK - looks obvious enough, and, IMO, is quite unlikely to cause
a regressions.

Thanks for the patch!

Regards

Thomas


Re: [patch] Fix build failure with MinGW

2019-03-30 Thread Jonathan Wakely
On Sat, 30 Mar 2019 at 11:56, Eric Botcazou wrote:
>
> Tested on x86_64-pc-mingw32, OK for the mainline?

OK, thanks.


[Patch, fortran] PR87127 - External function not recognised from within an associate block

2019-03-30 Thread Paul Richard Thomas
This patch is pretty self-explanatory. I have checked that a sensible
errors are given if 'exfunc' in the testcase is referenced if it is a
variable.

Bootstrapped and regtested on FC29/x86_64 - OK for trunk?

Paul

2019-03-30  Paul Thomas  

PR fortran/87127
* resolve.c (check_host_association): If an external function
is typed but not declared explicitly to be external, change the
old symbol from a variable to an external function.

2019-03-30  Paul Thomas  

PR fortran/87127
* gfortran.dg/external_procedures_4.f90: New test.
Index: gcc/fortran/resolve.c
===
*** gcc/fortran/resolve.c	(revision 269160)
--- gcc/fortran/resolve.c	(working copy)
*** resolve_procedure:
*** 5615,5625 


  /* Checks to see that the correct symbol has been host associated.
!The only situation where this arises is that in which a twice
!contained function is parsed after the host association is made.
!Therefore, on detecting this, change the symbol in the expression
!and convert the array reference into an actual arglist if the old
!symbol is a variable.  */
  static bool
  check_host_association (gfc_expr *e)
  {
--- 5615,5628 


  /* Checks to see that the correct symbol has been host associated.
!The only situations where this arises are:
! 	(i)  That in which a twice contained function is parsed after
! 	 the host association is made. On detecting this, change
! 	 the symbol in the expression and convert the array reference
! 	 into an actual arglist if the old symbol is a variable; or
! 	(ii) That in which an external function is typed but not declared
! 	 explicitly to be external. Here, the old symbol is changed
! 	 from a variable to an external function.  */
  static bool
  check_host_association (gfc_expr *e)
  {
*** check_host_association (gfc_expr *e)
*** 5709,5714 
--- 5712,5737 
  	  gfc_resolve_expr (e);
  	  sym->refs++;
  	}
+   /* This case corresponds to a call, from a block or a contained
+ 	 procedure, to an external function, which has not been declared
+ 	 as being external in the main program but has been typed.  */
+   else if (sym && old_sym != sym
+ 	   && !e->ref
+ 	   && sym->ts.type == BT_UNKNOWN
+ 	   && old_sym->ts.type != BT_UNKNOWN
+ 	   && sym->attr.flavor == FL_PROCEDURE
+ 	   && old_sym->attr.flavor == FL_VARIABLE
+ 	   && sym->ns->parent == old_sym->ns
+ 	   && sym->ns->proc_name
+ 	   && (sym->ns->proc_name->attr.flavor == FL_LABEL
+ 		   || sym->ns->proc_name->attr.flavor == FL_PROCEDURE))
+ 	{
+ 	  old_sym->attr.flavor = FL_PROCEDURE;
+ 	  old_sym->attr.external = 1;
+ 	  old_sym->attr.function = 1;
+ 	  old_sym->result = old_sym;
+ 	  gfc_resolve_expr (e);
+ 	}
  }
/* This might have changed!  */
return e->expr_type == EXPR_FUNCTION;
Index: gcc/testsuite/gfortran.dg/external_procedures_4.f90
===
*** gcc/testsuite/gfortran.dg/external_procedures_4.f90	(nonexistent)
--- gcc/testsuite/gfortran.dg/external_procedures_4.f90	(working copy)
***
*** 0 
--- 1,28 
+ ! { dg-do run }
+ !
+ ! Test the fix for PR87127 in which the references to exfunc cause
+ ! the error "‘exfunc’ at (1) is not a function".
+ !
+ ! Contributed by Gerhard Steinmetz  
+ !
+ function exfunc(i)
+   implicit none
+   integer :: exfunc,i
+   exfunc = 2*i
+ end function
+
+ ! contents of test.f90
+ program test
+   implicit none
+   integer :: exfunc,i
+   integer,parameter :: array(2)=[6,7]
+   associate(i=>array(2))! Original bug
+ if (exfunc(i) .ne. 2*i) stop 1
+   end associate
+   i = 99
+   call foo
+ contains
+   subroutine foo()  ! Comment #3
+ if (exfunc(i) .ne. 2*i) stop 2
+   end subroutine foo
+ end program


Re: [PATCH] Add peephole2s to improve pr49095.c f{char,short,int,long}minus on ia32 (PR rtl-optimization/89865)

2019-03-30 Thread Jeff Law
On 3/30/19 4:21 AM, Uros Bizjak wrote:
> On 3/29/19, Jeff Law  wrote:
>> On 3/29/19 1:44 PM, Jakub Jelinek wrote:
>>> Hi!
>>>
>>> f{char,short,int,long}minus use a RMW instead of direct memory operation
>>> (regression from 8.3) on ia32.  The problem is an extra register copy,
>>> which
>>> regcprop would fix up, but unfortunately peephole2 runs before regcprop.
>>> Also, in one of the existing peephole2s I've renumbered the operands so
>>> that
>>> we don't overwrite existing operands.
>>>
>>> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>>>
>>> 2019-03-29  Jakub Jelinek  
>>>
>>> PR rtl-optimization/89865
>>> * config/i386/i386.md
>>> (SWI12 peephole for mem {+,-,&,|,^}= x; mem != 0): Fix up operand
>>> numbers not to clash with the additional operands[4].
>>> (peepholes for mem {+,-,&,|,^}= x; mem != 0): New peephole2s
>>> with extra register copy in the middle.
>>>
>>> * gcc.target/i386/pr49095.c: Adjust number of expected RMW spots
>>> on ia32.
>> OK.  One might ask if there's a way to share a bit of code here since
>> there's a fair amount of duplication.  But I'll trust that you've
>> pondered that and decided it wasn't really worth the effort.
> 
> I think that Vladimir n is looking into the PR. So, if RA can avoid
> register copies by itself, then these extra peepholes won't be needed.
> Let's ask Vladimir for his opinion.
I know, but based on my own experience in this space, I suspect it's
unlikely we'll have a clean solution for gcc-9 in the allocator.

If you'd prefer to wait on installing the peepholes to hear from Vlad,
just in case, that's fine with me.

jeff




[patch] Fix build failure with MinGW

2019-03-30 Thread Eric Botcazou
Tested on x86_64-pc-mingw32, OK for the mainline?


2019-03-30  Eric Botcazou  

* src/c++17/fs_ops.cc (fs::permissions): Use std::errc::not_supported.

-- 
Eric Botcazoudiff --git libstdc++-v3/src/c++17/fs_ops.cc libstdc++-v3/src/c++17/fs_ops.cc
index 3ff0ded1c66..5ca523826cb 100644
--- libstdc++-v3/src/c++17/fs_ops.cc
+++ libstdc++-v3/src/c++17/fs_ops.cc
@@ -1127,7 +1127,7 @@ fs::permissions(const path& p, perms prms, perm_options opts,
 err = errno;
 #else
   if (nofollow && is_symlink(st))
-ec = std::make_error_code(std::errc::operation_not_supported);
+ec = std::make_error_code(std::errc::not_supported);
   else if (posix::chmod(p.c_str(), static_cast(prms)))
 err = errno;
 #endif


Re: [PATCH] Add peephole2s to improve pr49095.c f{char,short,int,long}minus on ia32 (PR rtl-optimization/89865)

2019-03-30 Thread Uros Bizjak
On 3/29/19, Jeff Law  wrote:
> On 3/29/19 1:44 PM, Jakub Jelinek wrote:
>> Hi!
>>
>> f{char,short,int,long}minus use a RMW instead of direct memory operation
>> (regression from 8.3) on ia32.  The problem is an extra register copy,
>> which
>> regcprop would fix up, but unfortunately peephole2 runs before regcprop.
>> Also, in one of the existing peephole2s I've renumbered the operands so
>> that
>> we don't overwrite existing operands.
>>
>> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>>
>> 2019-03-29  Jakub Jelinek  
>>
>>  PR rtl-optimization/89865
>>  * config/i386/i386.md
>>  (SWI12 peephole for mem {+,-,&,|,^}= x; mem != 0): Fix up operand
>>  numbers not to clash with the additional operands[4].
>>  (peepholes for mem {+,-,&,|,^}= x; mem != 0): New peephole2s
>>  with extra register copy in the middle.
>>
>>  * gcc.target/i386/pr49095.c: Adjust number of expected RMW spots
>>  on ia32.
> OK.  One might ask if there's a way to share a bit of code here since
> there's a fair amount of duplication.  But I'll trust that you've
> pondered that and decided it wasn't really worth the effort.

I think that Vladimir n is looking into the PR. So, if RA can avoid
register copies by itself, then these extra peepholes won't be needed.
Let's ask Vladimir for his opinion.

Uros.