[C++ PATCH 3/4] PR c++/82165 - enum bitfields and operator overloading.

2019-09-15 Thread Jason Merrill
In this testcase, !f.b0 was failing to call the overloaded operator because
TREE_TYPE is the magic bitfield integer type, and we weren't using
unlowered_expr_type the way we do in other places.  It would be nice if we
could give bit-field COMPONENT_REFs their declared type until genericization
time...

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

* call.c (build_new_op_1): Use unlowered_expr_type.
---
 gcc/cp/call.c  | 31 --
 gcc/testsuite/g++.dg/expr/bitfield13.C | 36 ++
 gcc/cp/ChangeLog   |  3 +++
 3 files changed, 56 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/expr/bitfield13.C

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 457fa6605c2..b780b0af58e 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5815,6 +5815,9 @@ build_new_op_1 (const op_location_t , enum tree_code 
code, int flags,
 }
   tree fnname = ovl_op_identifier (ismodop, ismodop ? code2 : code);
 
+  tree arg1_type = unlowered_expr_type (arg1);
+  tree arg2_type = arg2 ? unlowered_expr_type (arg2) : NULL_TREE;
+
   arg1 = prep_operand (arg1);
 
   bool memonly = false;
@@ -5846,8 +5849,8 @@ build_new_op_1 (const op_location_t , enum tree_code 
code, int flags,
 case EQ_EXPR:
 case NE_EXPR:
   /* These are saved for the sake of maybe_warn_bool_compare.  */
-  code_orig_arg1 = TREE_CODE (TREE_TYPE (arg1));
-  code_orig_arg2 = TREE_CODE (TREE_TYPE (arg2));
+  code_orig_arg1 = TREE_CODE (arg1_type);
+  code_orig_arg2 = TREE_CODE (arg2_type);
   break;
 
   /* =, ->, [], () must be non-static member functions.  */
@@ -5870,8 +5873,8 @@ build_new_op_1 (const op_location_t , enum tree_code 
code, int flags,
   if (code == COND_EXPR)
 /* Use build_conditional_expr instead.  */
 gcc_unreachable ();
-  else if (! OVERLOAD_TYPE_P (TREE_TYPE (arg1))
-  && (! arg2 || ! OVERLOAD_TYPE_P (TREE_TYPE (arg2
+  else if (! OVERLOAD_TYPE_P (arg1_type)
+  && (! arg2 || ! OVERLOAD_TYPE_P (arg2_type)))
 goto builtin;
 
   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
@@ -5903,11 +5906,11 @@ build_new_op_1 (const op_location_t , enum 
tree_code code, int flags,
   args[2] = NULL_TREE;
 
   /* Add class-member operators to the candidate set.  */
-  if (CLASS_TYPE_P (TREE_TYPE (arg1)))
+  if (CLASS_TYPE_P (arg1_type))
 {
   tree fns;
 
-  fns = lookup_fnfields (TREE_TYPE (arg1), fnname, 1);
+  fns = lookup_fnfields (arg1_type, fnname, 1);
   if (fns == error_mark_node)
{
  result = error_mark_node;
@@ -5927,7 +5930,7 @@ build_new_op_1 (const op_location_t , enum tree_code 
code, int flags,
  has an enumeration type, or T2 or reference to cv-qualified-opt
  T2 for the second argument, if the second argument has an
  enumeration type.  Filter out those that don't match.  */
-  else if (! arg2 || ! CLASS_TYPE_P (TREE_TYPE (arg2)))
+  else if (! arg2 || ! CLASS_TYPE_P (arg2_type))
 {
   struct z_candidate **candp, **next;
 
@@ -5947,9 +5950,9 @@ build_new_op_1 (const op_location_t , enum tree_code 
code, int flags,
 
  if (TYPE_REF_P (parmtype))
parmtype = TREE_TYPE (parmtype);
- if (TREE_CODE (TREE_TYPE (args[i])) == ENUMERAL_TYPE
+ if (TREE_CODE (unlowered_expr_type (args[i])) == ENUMERAL_TYPE
  && (same_type_ignoring_top_level_qualifiers_p
- (TREE_TYPE (args[i]), parmtype)))
+ (unlowered_expr_type (args[i]), parmtype)))
break;
 
  parmlist = TREE_CHAIN (parmlist);
@@ -6124,15 +6127,15 @@ build_new_op_1 (const op_location_t , enum 
tree_code code, int flags,
case LE_EXPR:
case EQ_EXPR:
case NE_EXPR:
- if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE
- && TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE
- && (TYPE_MAIN_VARIANT (TREE_TYPE (arg1))
- != TYPE_MAIN_VARIANT (TREE_TYPE (arg2)))
+ if (TREE_CODE (arg1_type) == ENUMERAL_TYPE
+ && TREE_CODE (arg2_type) == ENUMERAL_TYPE
+ && (TYPE_MAIN_VARIANT (arg1_type)
+ != TYPE_MAIN_VARIANT (arg2_type))
  && (complain & tf_warning))
{
  warning (OPT_Wenum_compare,
   "comparison between %q#T and %q#T",
-  TREE_TYPE (arg1), TREE_TYPE (arg2));
+  arg1_type, arg2_type);
}
  break;
default:
diff --git a/gcc/testsuite/g++.dg/expr/bitfield13.C 
b/gcc/testsuite/g++.dg/expr/bitfield13.C
new file mode 100644
index 000..3f57d5f0397
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/bitfield13.C
@@ -0,0 +1,36 @@
+// PR c++/82165
+// { dg-do compile { target c++11 } }
+
+struct flags {
+  enum field { f0, f1, no_field 

[C++ PATCH 2/4] Fix conversions for built-in operator overloading candidates.

2019-09-15 Thread Jason Merrill
While working on C++20 operator<=>, I noticed that build_new_op_1 was doing
too much conversion when a built-in candidate was selected; the standard
says it should only perform user-defined conversions, and then leave the
normal operator semantics to handle any standard conversions.  This is
important for operator<=> because a comparison of two different unscoped
enums is ill-formed; if we promote the enums to int here, cp_build_binary_op
never gets to see the original operand types, so we can't give the error.

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

* call.c (build_new_op_1): Don't apply any standard conversions to
the operands of a built-in operator.  Don't suppress conversions in
cp_build_unary_op.
* typeck.c (cp_build_unary_op): Do integral promotions for enums.
---
 gcc/cp/call.c| 51 
 gcc/cp/typeck.c  |  4 ++--
 gcc/cp/ChangeLog |  7 +++
 3 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index c3045d948c5..457fa6605c2 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6139,41 +6139,40 @@ build_new_op_1 (const op_location_t , enum 
tree_code code, int flags,
  break;
}
 
- /* We need to strip any leading REF_BIND so that bitfields
-don't cause errors.  This should not remove any important
-conversions, because builtins don't apply to class
-objects directly.  */
+ /* "If a built-in candidate is selected by overload resolution, the
+operands of class type are converted to the types of the
+corresponding parameters of the selected operation function,
+except that the second standard conversion sequence of a
+user-defined conversion sequence (12.3.3.1.2) is not applied."  */
  conv = cand->convs[0];
- if (conv->kind == ck_ref_bind)
-   conv = next_conversion (conv);
- arg1 = convert_like (conv, arg1, complain);
+ if (conv->user_conv_p)
+   {
+ while (conv->kind != ck_user)
+   conv = next_conversion (conv);
+ arg1 = convert_like (conv, arg1, complain);
+   }
 
  if (arg2)
{
  conv = cand->convs[1];
- if (conv->kind == ck_ref_bind)
-   conv = next_conversion (conv);
- else
-   arg2 = decay_conversion (arg2, complain);
-
- /* We need to call warn_logical_operator before
-converting arg2 to a boolean_type, but after
-decaying an enumerator to its value.  */
- if (complain & tf_warning)
-   warn_logical_operator (loc, code, boolean_type_node,
-  code_orig_arg1, arg1,
-  code_orig_arg2, arg2);
-
- arg2 = convert_like (conv, arg2, complain);
+ if (conv->user_conv_p)
+   {
+ while (conv->kind != ck_user)
+   conv = next_conversion (conv);
+ arg2 = convert_like (conv, arg2, complain);
+   }
}
+
  if (arg3)
{
  conv = cand->convs[2];
- if (conv->kind == ck_ref_bind)
-   conv = next_conversion (conv);
- convert_like (conv, arg3, complain);
+ if (conv->user_conv_p)
+   {
+ while (conv->kind != ck_user)
+   conv = next_conversion (conv);
+ arg3 = convert_like (conv, arg3, complain);
+   }
}
-
}
 }
 
@@ -6241,7 +6240,7 @@ build_new_op_1 (const op_location_t , enum tree_code 
code, int flags,
 case REALPART_EXPR:
 case IMAGPART_EXPR:
 case ABS_EXPR:
-  return cp_build_unary_op (code, arg1, candidates != 0, complain);
+  return cp_build_unary_op (code, arg1, false, complain);
 
 case ARRAY_REF:
   return cp_build_array_ref (input_location, arg1, arg2, complain);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 70094d1b426..620f2c9afdf 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6242,7 +6242,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool 
noconvert,
   : _("wrong type argument to unary plus"));
else
  {
-   if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
+   if (!noconvert && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
  arg = cp_perform_integral_promotions (arg, complain);
 
/* Make sure the result is not an lvalue: a unary plus or minus
@@ -6267,7 +6267,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool 
noconvert,
   | WANT_VECTOR_OR_COMPLEX,
   arg, true)))
errstring = _("wrong type argument to bit-complement");
- 

[C++ PATCH 4/4] PR c++/30277 - int-width bit-field promotion.

2019-09-15 Thread Jason Merrill
Here, if cp_perform_integral_promotions saw that the TREE_TYPE of a
bit-field reference was the same as the type it promotes to, it didn't do
anything.  But then decay_conversion saw that the bit-field reference was
unchanged, and converted it to its declared type.  So I needed to add
something to make it clear that promotion has been done.  But then the 33819
change caused trouble by looking through the NOP_EXPR I just added.  This
was the wrong fix for that bug; I've now fixed that better by recognizing in
cp_perform_integral_promotions that we won't promote a bit-field larger than
32 bits, so we should use the declared type.

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

PR c++/33819 - long bit-field promotion.
* typeck.c (cp_perform_integral_promotions): Handle large bit-fields
properly.  Handle 32-bit non-int bit-fields properly.
(is_bitfield_expr_with_lowered_type): Don't look through NOP_EXPR.
---
 gcc/cp/typeck.c| 29 --
 gcc/testsuite/g++.dg/expr/bitfield14.C | 17 +++
 gcc/cp/ChangeLog   |  6 ++
 3 files changed, 41 insertions(+), 11 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/expr/bitfield14.C

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 620f2c9afdf..c6bf41ee7a4 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1971,12 +1971,6 @@ is_bitfield_expr_with_lowered_type (const_tree exp)
   else
return NULL_TREE;
 
-CASE_CONVERT:
-  if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (exp, 0)))
- == TYPE_MAIN_VARIANT (TREE_TYPE (exp)))
-   return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
-  /* Fallthrough.  */
-
 default:
   return NULL_TREE;
 }
@@ -2189,13 +2183,23 @@ cp_perform_integral_promotions (tree expr, 
tsubst_flags_t complain)
   if (error_operand_p (expr))
 return error_mark_node;
 
+  type = TREE_TYPE (expr);
+
   /* [conv.prom]
 
- If the bitfield has an enumerated type, it is treated as any
- other value of that type for promotion purposes.  */
-  type = is_bitfield_expr_with_lowered_type (expr);
-  if (!type || TREE_CODE (type) != ENUMERAL_TYPE)
-type = TREE_TYPE (expr);
+ A prvalue for an integral bit-field (11.3.9) can be converted to a prvalue
+ of type int if int can represent all the values of the bit-field;
+ otherwise, it can be converted to unsigned int if unsigned int can
+ represent all the values of the bit-field. If the bit-field is larger yet,
+ no integral promotion applies to it. If the bit-field has an enumerated
+ type, it is treated as any other value of that type for promotion
+ purposes.  */
+  tree bitfield_type = is_bitfield_expr_with_lowered_type (expr);
+  if (bitfield_type
+  && (TREE_CODE (bitfield_type) == ENUMERAL_TYPE
+ || TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)))
+type = bitfield_type;
+
   gcc_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type));
   /* Scoped enums don't promote.  */
   if (SCOPED_ENUM_P (type))
@@ -2203,6 +2207,9 @@ cp_perform_integral_promotions (tree expr, tsubst_flags_t 
complain)
   promoted_type = type_promotes_to (type);
   if (type != promoted_type)
 expr = cp_convert (promoted_type, expr, complain);
+  else if (bitfield_type && bitfield_type != type)
+/* Prevent decay_conversion from converting to bitfield_type.  */
+expr = build_nop (type, expr);
   return expr;
 }
 
diff --git a/gcc/testsuite/g++.dg/expr/bitfield14.C 
b/gcc/testsuite/g++.dg/expr/bitfield14.C
new file mode 100644
index 000..546af85ba10
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/bitfield14.C
@@ -0,0 +1,17 @@
+// PR c++/30277
+// { dg-do compile { target c++11 } }
+
+struct S
+{
+  signed long l: 32;
+};
+
+void foo(long) = delete;
+void foo(int) {}
+
+int main()
+{
+  S x = {1};
+  foo(x.l+0);
+  return 0;
+}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bed72c90a2e..7bf28f81fae 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
 2019-09-15  Jason Merrill  
 
+   PR c++/30277 - int-width bit-field promotion.
+   PR c++/33819 - long bit-field promotion.
+   * typeck.c (cp_perform_integral_promotions): Handle large bit-fields
+   properly.  Handle 32-bit non-int bit-fields properly.
+   (is_bitfield_expr_with_lowered_type): Don't look through NOP_EXPR.
+
PR c++/82165 - enum bitfields and operator overloading.
* call.c (build_new_op_1): Use unlowered_expr_type.
 
-- 
2.21.0



[C++ PATCH 1/4] Handle location wrappers better in warn_logical_operator.

2019-09-15 Thread Jason Merrill
When we introduced location wrappers, we added fold_for_warn to warnings
that are interested in a constant value, or wrapper-stripping to warnings
that are interested in literal constants.  This particular warning is
looking for a literal constant, but was wrongly changed to use
fold_for_warn; this patch makes it strip instead.

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

* c-warn.c (warn_logical_operator): Strip location wrappers.  Don't
fold_for_warn in "|| mask" warning.
---
 gcc/c-family/c-warn.c  | 40 
 gcc/c-family/ChangeLog |  5 +
 2 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index d671b77a2b0..bee5449bcb1 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -208,32 +208,32 @@ warn_logical_operator (location_t location, enum 
tree_code code, tree type,
  programmer. That is, an expression such as op && MASK
  where op should not be any boolean expression, nor a
  constant, and mask seems to be a non-boolean integer constant.  */
+  STRIP_ANY_LOCATION_WRAPPER (op_right);
   if (TREE_CODE (op_right) == CONST_DECL)
 /* An enumerator counts as a constant.  */
 op_right = DECL_INITIAL (op_right);
+  tree stripped_op_left = tree_strip_any_location_wrapper (op_left);
   if (!truth_value_p (code_left)
   && INTEGRAL_TYPE_P (TREE_TYPE (op_left))
-  && !CONSTANT_CLASS_P (op_left)
-  && !TREE_NO_WARNING (op_left))
+  && !CONSTANT_CLASS_P (stripped_op_left)
+  && TREE_CODE (stripped_op_left) != CONST_DECL
+  && !TREE_NO_WARNING (op_left)
+  && TREE_CODE (op_right) == INTEGER_CST
+  && !integer_zerop (op_right)
+  && !integer_onep (op_right))
 {
-  tree folded_op_right = fold_for_warn (op_right);
-  if (TREE_CODE (folded_op_right) == INTEGER_CST
- && !integer_zerop (folded_op_right)
- && !integer_onep (folded_op_right))
-   {
- bool warned;
- if (or_op)
-   warned
- = warning_at (location, OPT_Wlogical_op,
-   "logical % applied to non-boolean constant");
- else
-   warned
- = warning_at (location, OPT_Wlogical_op,
-   "logical % applied to non-boolean constant");
- if (warned)
-   TREE_NO_WARNING (op_left) = true;
- return;
-   }
+  bool warned;
+  if (or_op)
+   warned
+ = warning_at (location, OPT_Wlogical_op,
+   "logical % applied to non-boolean constant");
+  else
+   warned
+ = warning_at (location, OPT_Wlogical_op,
+   "logical % applied to non-boolean constant");
+  if (warned)
+   TREE_NO_WARNING (op_left) = true;
+  return;
 }
 
   /* We do not warn for constants because they are typical of macro
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 2b700c2c4bd..93bdf3e0798 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,8 @@
+2019-09-15  Jason Merrill  
+
+   * c-warn.c (warn_logical_operator): Strip location wrappers.  Don't
+   fold_for_warn in "|| mask" warning.
+
 2019-09-10  Martin Liska  
 
* c.opt: Use newly added WarnRemoved.

base-commit: ce026385ee57427978053620a038bffaac90819e
-- 
2.21.0



Re: [PATCH 2/4]: C++ P1423R3 char8_t remediation: Update feature test macro, add deleted operators, update u8path

2019-09-15 Thread Tom Honermann
A revised patch is attached that adds proper preprocessor conditionals 
around the deleted ostream inserters.  Apparently I had previously 
implemented a quick hack for testing purposes, neglected to add a FIXME 
comment, and then forgot about the hack.  Shame on me.


Tom.

On 9/15/19 3:39 PM, Tom Honermann wrote:
This patch increments the __cpp_lib_char8_t feature test macro, adds 
deleted operator<< overloads for basic_ostream, and modifies u8path to 
accept sequences of char8_t for both the C++17 implementation of 
std::filesystem, and the filesystem TS implementation.


The implementation mechanism used for u8path differs between the C++17 
and filesystem TS implementations.  The changes to the former take 
advantage of C++17 'if constexpr'.  The changes to the latter retain 
C++11 compatibility and rely on tag dispatching.


libstdc++-v3/ChangeLog:

2019-09-15  Tom Honermann  

  * libstdc++-v3/include/bits/c++config: Bumped the value of the
    __cpp_lib_char8_t feature test macro.
  * libstdc++-v3/include/bits/fs_path.h (u8path): Modified u8path to
    accept sequences of char8_t.
  * libstdc++-v3/include/experimental/bits/fs_path.h (u8path):
    Modified u8path to accept sequences of char8_t.
  * libstdc++-v3/include/std/ostream: Added deleted overloads of
    wchar_t, char8_t, char16_t, and char32_t for ordinary and wide
    formatted character and string inserters.

Tom.


diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index c8e099aaadd..5bcf32d95ef 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -620,7 +620,7 @@ namespace std
 # endif
 #endif
 #ifdef _GLIBCXX_USE_CHAR8_T
-# define __cpp_lib_char8_t 201811L
+# define __cpp_lib_char8_t 201907L
 #endif
 
 /* Define if __float128 is supported on this host. */
diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h
index 71354515403..f3f539412fc 100644
--- a/libstdc++-v3/include/bits/fs_path.h
+++ b/libstdc++-v3/include/bits/fs_path.h
@@ -153,9 +153,24 @@ namespace __detail
 
   template())),
-	   typename _Val = typename std::iterator_traits<_Iter>::value_type>
+	   typename _Val = typename std::iterator_traits<_Iter>::value_type,
+	   typename _UnqualVal = std::remove_const_t<_Val>>
 using __value_type_is_char
-  = std::enable_if_t, char>>;
+  = std::enable_if_t,
+			 _UnqualVal>;
+
+  template())),
+	   typename _Val = typename std::iterator_traits<_Iter>::value_type,
+	   typename _UnqualVal = std::remove_const_t<_Val>>
+using __value_type_is_char_or_char8_t
+  = std::enable_if_t<__or_v<
+			   std::is_same<_UnqualVal, char>
+#ifdef _GLIBCXX_USE_CHAR8_T
+			   ,std::is_same<_UnqualVal, char8_t>
+#endif
+			   >,
+			 _UnqualVal>;
 
   // @} group filesystem-detail
 } // namespace __detail
@@ -639,29 +654,41 @@ namespace __detail
   /// Create a path from a UTF-8-encoded sequence of char
   template,
-	   typename _Require2 = __detail::__value_type_is_char<_InputIterator>>
+	   typename _CharT =
+	 __detail::__value_type_is_char_or_char8_t<_InputIterator>>
 inline path
 u8path(_InputIterator __first, _InputIterator __last)
 {
 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  // XXX This assumes native wide encoding is UTF-16.
-  std::codecvt_utf8_utf16 __cvt;
-  path::string_type __tmp;
-  if constexpr (is_pointer_v<_InputIterator>)
+#ifdef _GLIBCXX_USE_CHAR8_T
+  if constexpr (is_same_v<_CharT, char8_t>)
 	{
-	  if (__str_codecvt_in_all(__first, __last, __tmp, __cvt))
-	return path{ __tmp };
+	  return path{ __first, __last };
 	}
   else
 	{
-	  const std::string __u8str{__first, __last};
-	  const char* const __ptr = __u8str.data();
-	  if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt))
-	return path{ __tmp };
+#endif
+	  // XXX This assumes native wide encoding is UTF-16.
+	  std::codecvt_utf8_utf16 __cvt;
+	  path::string_type __tmp;
+	  if constexpr (is_pointer_v<_InputIterator>)
+	{
+	  if (__str_codecvt_in_all(__first, __last, __tmp, __cvt))
+		return path{ __tmp };
+	}
+	  else
+	{
+	  const std::string __u8str{__first, __last};
+	  const char* const __ptr = __u8str.data();
+	  if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt))
+		return path{ __tmp };
+	}
+	  _GLIBCXX_THROW_OR_ABORT(filesystem_error(
+	  "Cannot convert character sequence",
+	  std::make_error_code(errc::illegal_byte_sequence)));
+#ifdef _GLIBCXX_USE_CHAR8_T
 	}
-  _GLIBCXX_THROW_OR_ABORT(filesystem_error(
-	"Cannot convert character sequence",
-	std::make_error_code(errc::illegal_byte_sequence)));
+#endif
 #else
   // This assumes native normal encoding is UTF-8.
   return path{ __first, __last };
@@ -671,21 +698,32 @@ namespace __detail
   /// Create a path from a UTF-8-encoded sequence of char
   template,
-	   typename _Require2 = 

Re: [PATCH 4/4]: C++ P1423R3 char8_t remediation: New tests

2019-09-15 Thread Tom Honermann
A revised patch is attached that modifies the tests for deleted ostream 
inserters to require C++2a.  This is required by the revision of patch 
2/4 that adds proper preprocessor conditionals to the definitions.


Tom.

On 9/15/19 3:40 PM, Tom Honermann wrote:
This patch adds new tests to validate new deleted overloads of wchar_t, 
char8_t, char16_t, and char32_t for ordinary and wide formatted 
character and string ostream inserters.


Additionally, new tests are added to validate invocations of u8path with 
sequences of char8_t for both the C++17 and filesystem TS implementations.


libstdc++-v3/ChangeLog:

2019-09-15  Tom Honermann  

  * 
libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc: 


    New test to validate deleted overloads of character and string
    inserters for narrow ostreams.
  * 
libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc: 


    New test to validate deleted overloads of character and string
    inserters for wide ostreams.
  * 
libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path-char8_t.cc:

    New test to validate u8path invocations with sequences of
    char8_t.
  * 
libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path-char8_t.cc 


    New test to validate u8path invocations with sequences of
    char8_t.

Tom.


commit b7eb4714cc2c999ce0491358fcbcebf4a8723185
Author: Tom Honermann 
Date:   Sun Sep 15 22:25:28 2019 -0400

P1423R3 char8_t remediation: New tests

This patch adds new tests to validate new deleted overloads of wchar_t,
char8_t, char16_t, and char32_t for ordinary and wide formatted
character and string ostream inserters.

Additionally, new tests are added to validate invocations of u8path with
sequences of char8_t for both the C++17 and filesystem TS implementations.

diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc
new file mode 100644
index 000..f2eb538f42e
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+// 29.7.2 Header  synopsys; deleted character inserters.
+
+// Test character inserters defined as deleted by P1423.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include 
+
+void test_character_inserters(std::ostream )
+{
+  os << 'x';   // ok.
+  os << L'x';  // { dg-error "use of deleted function" }
+  os << u8'x'; // { dg-error "use of deleted function" }
+  os << u'x';  // { dg-error "use of deleted function" }
+  os << U'x';  // { dg-error "use of deleted function" }
+}
+
+void test_string_inserters(std::ostream )
+{
+  os << "text";  // ok.
+  os << L"text";  // { dg-error "use of deleted function" }
+  os << u8"text"; // { dg-error "use of deleted function" }
+  os << u"text";  // { dg-error "use of deleted function" }
+  os << U"text";  // { dg-error "use of deleted function" }
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc
new file mode 100644
index 000..1422a01aab3
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+// 29.7.2 

[CFI, Darwin] A hook to allow target-handling of Personality and LSDA indirections.

2019-09-15 Thread Iain Sandoe
If an assembler is used that supports .cfi_xxx, then (usually) GCC's 
configuration will detect this and try to use it to generate frame insns.

This will not work for Darwin since the default implementation for the 
personality and LSDA indirection is not correct for Mach-O ABI. 

As of now we are currently “lucky” in that the Darwin implementation of objdump 
(based on LLVM) does not recognise “-Wf” (and also has slightly different 
whitespace output) which means that even tho most of the modern assemblers for 
Darwin *do* consume .cfi_ instructions, the GCC configure is not detecting 
this and we are falling back to the old direct DWARF output for CFA/FDEs.

There is no point in fixing the configure, until the codegen will produce 
useful output.

So, this patch introduces a target hook to allow target-specific processing of 
personality and LSDA indirections (if the hook is not populated, the default 
implementation is used).

Once this fixed is applied it is possible to make progress towards modernising 
the Darwin handling of the frame insns (and, hopefully, with the newer dsymutil 
implementations to progress towards consuming DWARF4, at least).

OK for trunk?
thanks
Iain

gcc/ChangeLog:

2019-09-16  Iain Sandoe  

* config/darwin-protos.h (darwin_make_eh_symbol_indirect): New.
* config/darwin.c (darwin_make_eh_symbol_indirect): New.
* config/darwin.h (TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT): New hook.
* doc/tm.texi: Regenerated.
* doc/tm.texi.in: Declare new hook.
* dwarf2out.c (dwarf2out_do_cfi_startproc): Allow for target hook to 
alter the code gen
for personality and LSDA indirections.
* target.def: Describe new hook.


diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
index e5614b627d..bb3fe19e0d 100644
--- a/gcc/config/darwin-protos.h
+++ b/gcc/config/darwin-protos.h
@@ -68,6 +68,7 @@ extern void darwin_non_lazy_pcrel (FILE *, rtx);
 
 extern void darwin_emit_unwind_label (FILE *, tree, int, int);
 extern void darwin_emit_except_table_label (FILE *);
+extern rtx darwin_make_eh_symbol_indirect (rtx, bool);
 
 extern void darwin_pragma_ignore (struct cpp_reader *);
 extern void darwin_pragma_options (struct cpp_reader *);
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index e62a5c6595..7ef73cc58b 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -2157,6 +2157,18 @@ darwin_emit_except_table_label (FILE *file)
   except_table_label_num++);
   ASM_OUTPUT_LABEL (file, section_start_label);
 }
+
+rtx
+darwin_make_eh_symbol_indirect (rtx orig, bool ARG_UNUSED (pubvis))
+{
+  if (DARWIN_PPC == 0 && TARGET_64BIT)
+return orig;
+
+  return gen_rtx_SYMBOL_REF (Pmode,
+machopic_indirection_name (orig,
+   /*stub_p=*/false));
+}
+
 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */
 
 void
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index fde191d5c4..06e6f0c3da 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -593,6 +593,9 @@ extern GTY(()) int darwin_ms_struct;
 /* Emit a label to separate the exception table.  */
 #define TARGET_ASM_EMIT_EXCEPT_TABLE_LABEL darwin_emit_except_table_label
 
+/* Make an EH (personality or LDSA) symbol indirect as needed.  */
+#define TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT darwin_make_eh_symbol_indirect
+
 /* Our profiling scheme doesn't LP labels and counter words.  */
 
 #define NO_PROFILE_COUNTERS1
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 0b5a08d490..635faa22dc 100644
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index a9200551ed..c6d457cb5e 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -6445,6 +6445,8 @@ the jump-table.
 
 @hook TARGET_ASM_UNWIND_EMIT
 
+@hook TARGET_ASM_MAKE_EH_SYMBOL_INDIRECT
+
 @hook TARGET_ASM_UNWIND_EMIT_BEFORE_INSN
 
 @node Exception Region Output
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index aa7fd7eb46..b6d25c109a 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -988,7 +988,12 @@ dwarf2out_do_cfi_startproc (bool second)
 in the assembler.  Further, the assembler can't handle any
 of the weirder relocation types.  */
   if (enc & DW_EH_PE_indirect)
-   ref = dw2_force_const_mem (ref, true);
+   {
+ if (targetm.asm_out.make_eh_symbol_indirect != NULL)
+   ref = targetm.asm_out.make_eh_symbol_indirect (ref, true);
+ else
+   ref = dw2_force_const_mem (ref, true);
+   }
 
   fprintf (asm_out_file, "\t.cfi_personality %#x,", enc);
   output_addr_const (asm_out_file, ref);
@@ -1006,7 +1011,12 @@ dwarf2out_do_cfi_startproc (bool second)
   SYMBOL_REF_FLAGS (ref) = SYMBOL_FLAG_LOCAL;
 
   if (enc & DW_EH_PE_indirect)
-   ref = dw2_force_const_mem (ref, true);
+   {
+ if (targetm.asm_out.make_eh_symbol_indirect != NULL)
+   ref = 

[PATCH 3/4]: C++ P1423R3 char8_t remediation: Updates to existing tests

2019-09-15 Thread Tom Honermann

This patch updates existing tests to validate the new value for the
__cpp_lib_char8_t feature test macros and to exercise u8path factory
function invocations with std::string, std::string_view, and interator
pair arguments.

libstdc++-v3/ChangeLog:

2019-09-15  Tom Honermann  

 * libstdc++-v3/testsuite/experimental/feat-char8_t.cc: Updated the
   expected __cpp_lib_char8_t feature test macro value.
 * libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path.cc:
   Added testing of u8path invocation with std::string,
   std::string_view, and iterators thereof.
 * 
libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path.cc:

   Added testing of u8path invocation with std::string,
   std::string_view, and iterators thereof.

Tom.
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path.cc
index aff722b5867..fb337ce1284 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path.cc
@@ -19,6 +19,7 @@
 // { dg-do run { target c++17 } }
 
 #include 
+#include 
 #include 
 
 namespace fs = std::filesystem;
@@ -34,6 +35,22 @@ test01()
 
   p = fs::u8path("\xf0\x9d\x84\x9e");
   VERIFY( p.u8string() == u8"\U0001D11E" );
+
+  std::string s1 = "filename2";
+  p = fs::u8path(s1);
+  VERIFY( p.u8string() == u8"filename2" );
+
+  std::string s2 = "filename3";
+  p = fs::u8path(s2.begin(), s2.end());
+  VERIFY( p.u8string() == u8"filename3" );
+
+  std::string_view sv1{ s1 };
+  p = fs::u8path(sv1);
+  VERIFY( p.u8string() == u8"filename2" );
+
+  std::string_view sv2{ s2 };
+  p = fs::u8path(sv2.begin(), sv2.end());
+  VERIFY( p.u8string() == u8"filename3" );
 }
 
 void
diff --git a/libstdc++-v3/testsuite/experimental/feat-char8_t.cc b/libstdc++-v3/testsuite/experimental/feat-char8_t.cc
index e843604266c..c9b277a4626 100644
--- a/libstdc++-v3/testsuite/experimental/feat-char8_t.cc
+++ b/libstdc++-v3/testsuite/experimental/feat-char8_t.cc
@@ -12,6 +12,6 @@
 
 #ifndef  __cpp_lib_char8_t
 #  error "__cpp_lib_char8_t"
-#elif  __cpp_lib_char8_t != 201811L
-#  error "__cpp_lib_char8_t != 201811L"
+#elif  __cpp_lib_char8_t != 201907L
+#  error "__cpp_lib_char8_t != 201907L"
 #endif
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path.cc
index bdeb3946a15..83219b7ddda 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path.cc
@@ -35,6 +35,14 @@ test01()
 
   p = fs::u8path("\xf0\x9d\x84\x9e");
   VERIFY( p.u8string() == u8"\U0001D11E" );
+
+  std::string s1 = "filename2";
+  p = fs::u8path(s1);
+  VERIFY( p.u8string() == u8"filename2" );
+
+  std::string s2 = "filename3";
+  p = fs::u8path(s2.begin(), s2.end());
+  VERIFY( p.u8string() == u8"filename3" );
 }
 
 void


[PATCH 4/4]: C++ P1423R3 char8_t remediation: New tests

2019-09-15 Thread Tom Honermann
This patch adds new tests to validate new deleted overloads of wchar_t, 
char8_t, char16_t, and char32_t for ordinary and wide formatted 
character and string ostream inserters.


Additionally, new tests are added to validate invocations of u8path with 
sequences of char8_t for both the C++17 and filesystem TS implementations.


libstdc++-v3/ChangeLog:

2019-09-15  Tom Honermann  

 * 
libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc:

   New test to validate deleted overloads of character and string
   inserters for narrow ostreams.
 * 
libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc:

   New test to validate deleted overloads of character and string
   inserters for wide ostreams.
 * 
libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path-char8_t.cc:

   New test to validate u8path invocations with sequences of
   char8_t.
 * 
libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path-char8_t.cc

   New test to validate u8path invocations with sequences of
   char8_t.

Tom.
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc
new file mode 100644
index 000..87afb295086
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+// 29.7.2 Header  synopsys; deleted character inserters.
+
+// Test character inserters defined as deleted by P1423.
+
+// { dg-options "-std=gnu++17 -fchar8_t" }
+// { dg-do compile { target c++17 } }
+
+#include 
+
+void test_character_inserters(std::ostream )
+{
+  os << 'x';   // ok.
+  os << L'x';  // { dg-error "use of deleted function" }
+  os << u8'x'; // { dg-error "use of deleted function" }
+  os << u'x';  // { dg-error "use of deleted function" }
+  os << U'x';  // { dg-error "use of deleted function" }
+}
+
+void test_string_inserters(std::ostream )
+{
+  os << "text";  // ok.
+  os << L"text";  // { dg-error "use of deleted function" }
+  os << u8"text"; // { dg-error "use of deleted function" }
+  os << u"text";  // { dg-error "use of deleted function" }
+  os << U"text";  // { dg-error "use of deleted function" }
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc
new file mode 100644
index 000..701de16822b
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+// 29.7.2 Header  synopsys; deleted character inserters.
+
+// Test wide character inserters defined as deleted by P1423.
+
+// { dg-options "-std=gnu++17 -fchar8_t" }
+// { dg-do compile { target c++17 } }
+
+#include 
+
+void test_character_inserters(std::wostream )
+{
+  os << 'x';   // ok.
+  os << L'x';  // ok.
+  os << u8'x'; // { dg-error "use of deleted function" }
+  os << u'x';  // { dg-error "use of deleted function" }
+  os << U'x';  // { dg-error "use of deleted function" }
+}
+
+void test_string_inserters(std::wostream )
+{
+  os << "text";   // ok.
+  os << L"text";  // ok.
+  os << u8"text"; // { dg-error "use of deleted function" }
+  os << u"text";  // { dg-error "use of deleted function" }
+  os << U"text";  // { dg-error "use of deleted function" }
+}
diff --git 

[PATCH 2/4]: C++ P1423R3 char8_t remediation: Update feature test macro, add deleted operators, update u8path

2019-09-15 Thread Tom Honermann
This patch increments the __cpp_lib_char8_t feature test macro, adds 
deleted operator<< overloads for basic_ostream, and modifies u8path to 
accept sequences of char8_t for both the C++17 implementation of 
std::filesystem, and the filesystem TS implementation.


The implementation mechanism used for u8path differs between the C++17 
and filesystem TS implementations.  The changes to the former take 
advantage of C++17 'if constexpr'.  The changes to the latter retain 
C++11 compatibility and rely on tag dispatching.


libstdc++-v3/ChangeLog:

2019-09-15  Tom Honermann  

 * libstdc++-v3/include/bits/c++config: Bumped the value of the
   __cpp_lib_char8_t feature test macro.
 * libstdc++-v3/include/bits/fs_path.h (u8path): Modified u8path to
   accept sequences of char8_t.
 * libstdc++-v3/include/experimental/bits/fs_path.h (u8path):
   Modified u8path to accept sequences of char8_t.
 * libstdc++-v3/include/std/ostream: Added deleted overloads of
   wchar_t, char8_t, char16_t, and char32_t for ordinary and wide
   formatted character and string inserters.

Tom.
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index c8e099aaadd..5bcf32d95ef 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -620,7 +620,7 @@ namespace std
 # endif
 #endif
 #ifdef _GLIBCXX_USE_CHAR8_T
-# define __cpp_lib_char8_t 201811L
+# define __cpp_lib_char8_t 201907L
 #endif
 
 /* Define if __float128 is supported on this host. */
diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h
index 71354515403..f3f539412fc 100644
--- a/libstdc++-v3/include/bits/fs_path.h
+++ b/libstdc++-v3/include/bits/fs_path.h
@@ -153,9 +153,24 @@ namespace __detail
 
   template())),
-	   typename _Val = typename std::iterator_traits<_Iter>::value_type>
+	   typename _Val = typename std::iterator_traits<_Iter>::value_type,
+	   typename _UnqualVal = std::remove_const_t<_Val>>
 using __value_type_is_char
-  = std::enable_if_t, char>>;
+  = std::enable_if_t,
+			 _UnqualVal>;
+
+  template())),
+	   typename _Val = typename std::iterator_traits<_Iter>::value_type,
+	   typename _UnqualVal = std::remove_const_t<_Val>>
+using __value_type_is_char_or_char8_t
+  = std::enable_if_t<__or_v<
+			   std::is_same<_UnqualVal, char>
+#ifdef _GLIBCXX_USE_CHAR8_T
+			   ,std::is_same<_UnqualVal, char8_t>
+#endif
+			   >,
+			 _UnqualVal>;
 
   // @} group filesystem-detail
 } // namespace __detail
@@ -639,29 +654,41 @@ namespace __detail
   /// Create a path from a UTF-8-encoded sequence of char
   template,
-	   typename _Require2 = __detail::__value_type_is_char<_InputIterator>>
+	   typename _CharT =
+	 __detail::__value_type_is_char_or_char8_t<_InputIterator>>
 inline path
 u8path(_InputIterator __first, _InputIterator __last)
 {
 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  // XXX This assumes native wide encoding is UTF-16.
-  std::codecvt_utf8_utf16 __cvt;
-  path::string_type __tmp;
-  if constexpr (is_pointer_v<_InputIterator>)
+#ifdef _GLIBCXX_USE_CHAR8_T
+  if constexpr (is_same_v<_CharT, char8_t>)
 	{
-	  if (__str_codecvt_in_all(__first, __last, __tmp, __cvt))
-	return path{ __tmp };
+	  return path{ __first, __last };
 	}
   else
 	{
-	  const std::string __u8str{__first, __last};
-	  const char* const __ptr = __u8str.data();
-	  if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt))
-	return path{ __tmp };
+#endif
+	  // XXX This assumes native wide encoding is UTF-16.
+	  std::codecvt_utf8_utf16 __cvt;
+	  path::string_type __tmp;
+	  if constexpr (is_pointer_v<_InputIterator>)
+	{
+	  if (__str_codecvt_in_all(__first, __last, __tmp, __cvt))
+		return path{ __tmp };
+	}
+	  else
+	{
+	  const std::string __u8str{__first, __last};
+	  const char* const __ptr = __u8str.data();
+	  if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt))
+		return path{ __tmp };
+	}
+	  _GLIBCXX_THROW_OR_ABORT(filesystem_error(
+	  "Cannot convert character sequence",
+	  std::make_error_code(errc::illegal_byte_sequence)));
+#ifdef _GLIBCXX_USE_CHAR8_T
 	}
-  _GLIBCXX_THROW_OR_ABORT(filesystem_error(
-	"Cannot convert character sequence",
-	std::make_error_code(errc::illegal_byte_sequence)));
+#endif
 #else
   // This assumes native normal encoding is UTF-8.
   return path{ __first, __last };
@@ -671,21 +698,32 @@ namespace __detail
   /// Create a path from a UTF-8-encoded sequence of char
   template,
-	   typename _Require2 = __detail::__value_type_is_char<_Source>>
+	   typename _CharT = __detail::__value_type_is_char_or_char8_t<_Source>>
 inline path
 u8path(const _Source& __source)
 {
 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  if constexpr (is_convertible_v)
+#ifdef _GLIBCXX_USE_CHAR8_T
+  if constexpr (is_same_v<_CharT, char8_t>)
 	{
-	  const 

[PATCH 1/4]: C++ P1423R3 char8_t remediation: Decouple constraints for u8path from path constructors

2019-09-15 Thread Tom Honermann
This patch moves helper classes and functions for std::filesystem::path 
out of the class definition to a detail namespace so that they are 
available to the implementations of std::filesystem::u8path.  Prior to 
this patch, the SFINAE constraints for those implementations were 
specified via delegation to the overloads of path constructors with a 
std::locale parameter; it just so happened that those overloads had the 
same constraints.  As of P1423R3, u8path and those overloads no longer 
have the same constraints, so this dependency must be broken.


This patch also updates the experimental implementation of the 
filesystem TS to add SFINAE constraints to its implementations of 
u8path.  These functions were previously unconstrained and marked with a 
TODO comment.


This patch does not provide any intentional behavioral changes other 
than the added constraints to the experimental filesystem TS 
implementation of u8path.


I recommend applying the patch and viewing the diff with white space 
ignored when reviewing; there will be many fewer differences this way.


Alternatives to this refactoring would have been to make the u8path 
overloads friends of class path, or to make the helpers public members. 
Both of those approaches struck me as less desirable than this approach, 
though this approach does require more code changes and will affect 
implementation detail portions of mangled names for path constructors 
and inline member functions (mostly function template specializations).


libstdc++-v3/ChangeLog:

2019-09-15  Tom Honermann  

 * include/bits/fs_path.h: Moved helper utilities out of
   std::filesystem::path into a detail namespace to make them
   available for use by u8path.
 * include/experimental/bits/fs_path.h: Moved helper utilities out
   of std::experimental::filesystem::v1::path into a detail
   namespace to make them available for use by u8path.

Tom.
diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h
index e1083acf30f..71354515403 100644
--- a/libstdc++-v3/include/bits/fs_path.h
+++ b/libstdc++-v3/include/bits/fs_path.h
@@ -59,103 +59,114 @@ namespace filesystem
 {
 _GLIBCXX_BEGIN_NAMESPACE_CXX11
 
-  /** @addtogroup filesystem
+  class path;
+
+namespace __detail
+{
+  /** @addtogroup filesystem-detail
*  @{
*/
 
-  /// A filesystem path.
-  class path
-  {
-template
-  using __is_encoded_char = __is_one_of,
-	char,
+  template
+using __is_encoded_char = __is_one_of,
+	  char,
 #ifdef _GLIBCXX_USE_CHAR8_T
-	char8_t,
+	  char8_t,
 #endif
 #if _GLIBCXX_USE_WCHAR_T
-	wchar_t,
+	  wchar_t,
 #endif
-	char16_t, char32_t>;
+	  char16_t, char32_t>;
 
-template>
-  using __is_path_iter_src
-	= __and_<__is_encoded_char,
-		 std::is_base_of>;
+  template>
+using __is_path_iter_src
+  = __and_<__is_encoded_char,
+	   std::is_base_of>;
 
-template
-  static __is_path_iter_src<_Iter>
-  __is_path_src(_Iter, int);
-
-template
-  static __is_encoded_char<_CharT>
-  __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int);
-
-template
-  static __is_encoded_char<_CharT>
-  __is_path_src(const basic_string_view<_CharT, _Traits>&, int);
+  template
+static __is_path_iter_src<_Iter>
+__is_path_src(_Iter, int);
 
-template
-  static std::false_type
-  __is_path_src(const _Unknown&, ...);
-
-template
-  struct __constructible_from;
-
-template
-  struct __constructible_from<_Iter, _Iter>
-  : __is_path_iter_src<_Iter>
-  { };
+  template
+static __is_encoded_char<_CharT>
+__is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int);
 
-template
-  struct __constructible_from<_Source, void>
-  : decltype(__is_path_src(std::declval<_Source>(), 0))
-  { };
+  template
+static __is_encoded_char<_CharT>
+__is_path_src(const basic_string_view<_CharT, _Traits>&, int);
 
-template
-  using _Path = typename
-	std::enable_if<__and_<__not_, path>>,
-			  __not_>>,
-			  __constructible_from<_Tp1, _Tp2>>::value,
-		   path>::type;
+  template
+static std::false_type
+__is_path_src(const _Unknown&, ...);
 
-template
-  static _Source
-  _S_range_begin(_Source __begin) { return __begin; }
+  template
+struct __constructible_from;
 
-struct __null_terminated { };
+  template
+struct __constructible_from<_Iter, _Iter>
+: __is_path_iter_src<_Iter>
+{ };
 
-template
-  static __null_terminated
-  _S_range_end(_Source) { return {}; }
+  template
+struct __constructible_from<_Source, void>
+: decltype(__is_path_src(std::declval<_Source>(), 0))
+{ };
 
-template
-  static const _CharT*
-  _S_range_begin(const basic_string<_CharT, _Traits, _Alloc>& __str)
-  { return __str.data(); }
+  template
+using _Path = typename
+  std::enable_if<__and_<__not_, path>>,
+			__not_>>,
+			   

[PATCH 0/4]: C++ P1423R3 char8_t remediation implementation

2019-09-15 Thread Tom Honermann
This series of patches provides an implementation of the changes for C++ 
proposal P1423R3 [1].


These changes do not impact default libstdc++ behavior for C++17 and 
earlier; they are only active for C++2a or when the -fchar8_t option is 
specified.


Tested x86_64-linux.

Patch 1: Decouple constraints for u8path from path constructors.
Patch 2: Update __cpp_lib_char8_t feature test macro value, add deleted 
operators, update u8path.

Patch 3: Updates to existing tests.
Patch 4: New tests.

Tom.

[1]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1423r3.html


Re: [Patch, Fortran] CO_BROADCAST for derived types with allocatable components

2019-09-15 Thread Paul Richard Thomas
Hi Sandro,

This patch looks fine to me. I have a question about the comment:
"This code is obviously added because the finalizer is not trusted to
free all memory."
'obviously'? Not to me :-( Maybe you can expand on this?

As to the stat and errmsg: Leave them for the time being. However, an
attempt will have to be made to implement F2018 "16.6 Collective
subroutines". I don't know enough about the coarrays implementation to
be able to help you about detecting these conditions. Maybe Tobias
Burnus can help?

OK to commit.

Paul

PS Sometime before very long, something will have to be done about the
exponential code bloat that structure_alloc_comps. The more users that
there are for it the tougher it is going to get!

On Thu, 22 Aug 2019 at 18:41, Alessandro Fanfarillo
 wrote:
>
> Dear all,
> please find in attachment a preliminary patch that adds support to
> co_broadcast for allocatable components of derived types.
> The patch is currently ignoring the stat and errmsg arguments, mostly
> because I am not sure how to handle them properly. I have created a
> new data structure called used to pass those argument to the
> preexisting structure_alloc_comps.
> Suggestions on how to handle them are more than welcome :-)
>
> The patch builds correctly on x86_64 and it has been tested with
> OpenCoarrays and the following test cases:
>
> https://github.com/sourceryinstitute/OpenCoarrays/blob/co_broadcast-derived-type/src/tests/unit/collectives/co_broadcast_allocatable_components.f90
>
> https://github.com/sourceryinstitute/OpenCoarrays/blob/co_broadcast-derived-type/src/tests/unit/collectives/co_broadcast_allocatable_components_array.f90
>
> Regards,



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


[Committed] PR fortran/91727 -- NULL pointer dereference

2019-09-15 Thread Steve Kargl
Committed as obvious.

The patch checks for a NULL pointer dereference.  In this
case, it pointers to an error in the Fortran code, and so
gfortran now issues an informative error message.

2019-09-15  Steven G. Kargl  

PR fortran/91727
* resolve.c (conformable_arrays):  If array-spec is NULL, then
allocate-object is a scalar.  a conformability check only occurs
for an array source-expr.

2019-09-15  Steven G. Kargl  

PR fortran/91727
* gfortran.dg/pr91727.f90: New test.

-- 
Steve
Index: gcc/fortran/resolve.c
===
--- gcc/fortran/resolve.c	(revision 275715)
+++ gcc/fortran/resolve.c	(working copy)
@@ -7487,7 +7487,7 @@ conformable_arrays (gfc_expr *e1, gfc_expr *e2)
   for (tail = e2->ref; tail && tail->next; tail = tail->next);
 
   /* First compare rank.  */
-  if ((tail && e1->rank != tail->u.ar.as->rank)
+  if ((tail && (!tail->u.ar.as || e1->rank != tail->u.ar.as->rank))
   || (!tail && e1->rank != e2->rank))
 {
   gfc_error ("Source-expr at %L must be scalar or have the "
Index: gcc/testsuite/gfortran.dg/pr91727.f90
===
--- gcc/testsuite/gfortran.dg/pr91727.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/pr91727.f90	(working copy)
@@ -0,0 +1,9 @@
+! { dg-do compile }
+! Code contributed by Gerhard Steinmetz.
+program p
+   type t
+  class(*), allocatable :: a
+   end type
+   type(t) :: x
+   allocate (x%a, source=[1]) ! { dg-error "have the same rank as" }
+end


Re: [PATCH testsuite, arm] cache fp16 hw effective-target tests

2019-09-15 Thread Ramana Radhakrishnan
On Fri, Sep 13, 2019 at 5:31 PM Sandra Loosemore
 wrote:
>
> In some bare-metal environments, the tests for fp16 runtime support fail
> in a way that causes a timeout rather than immediate failure.  (E.g.,
> the runtime might provide a do-nothing exception handler that just sits
> in a tight loop and never returns.)  This patch changes the
> effective-target tests for fp16 hardware support to cache the result of
> the test so that we don't have to do this more than once.  I think it
> was probably just an oversight that it wasn't done this way originally,
> since the target is hardly likely to sprout fp16 instruction support
> midway through the test run anyway.  ;-)  Anyway, test results are the
> same with this patch, they just run faster.  OK to commit?

Ok, thanks.

Ramana

>
> -Sandra


Re: [patch, fortran] Fix ICE on invalid with DO steps

2019-09-15 Thread Thomas Koenig

Hi Steve,


s/previusly/previously


Fixed, committed. Thanks for the review!


Do you it gfortran should skip the front-end optimization pass
if error(s) have already been reported?  On entry ito this pass,
you could test for the error count and simply return.


I thought about this for doing this here.  It's a front-end pass,
but for error checking and warnings, not an optimization one, so
I thought throwing a few additional errors / warnings would not
hurt.

Regards

Thomas


Re: [patch, fortran] Fix ICE on invalid with DO steps

2019-09-15 Thread Steve Kargl
On Sun, Sep 15, 2019 at 03:55:55PM +0200, Thomas Koenig wrote:
> 
> Regression-tested.  OK for all affected branches (trunk, 9 and 8)?
> 

OK with minor spelling fix.

> +   sgn = mpz_cmp_ui (dl->ext.iterator->step->value.integer, 0);
> +   /* This can happen, but then the error has been
> +  reported previusly.  */

s/previusly/previously

Do you it gfortran should skip the front-end optimization pass
if error(s) have already been reported?  On entry ito this pass,
you could test for the error count and simply return.

int wcnt, ecnt;
gfc_get_errors (, )
if (ecnt > 0)
   return;

-- 
Steve


Re: [Patch, fortran] PR91588 - ICE in check_inquiry, at fortran/expr.c:2673

2019-09-15 Thread Steve Kargl
On Sun, Sep 15, 2019 at 12:40:02PM +0100, Paul Richard Thomas wrote:
> The attached bootstraps and regtests on FC30/x86_64 - OK for trunk?
> 
> It strikes me that this should be backported since the bug is rather
> fundamental and ispresent all the way back to version 4.8. An obvious
> question is how far back? To 8-branch?
> 

OK.  If the patch applies cleanly, go back to 8-branch.

-- 
Steve


Re: C++ PATCH for c++/91740 - ICE with constexpr call and ?: in ARRAY_REF

2019-09-15 Thread Jason Merrill

On 9/11/19 4:15 PM, Marek Polacek wrote:

This ICEs since r267272 - more location wrapper nodes, but not because we can't
cope with new location wrappers, but because that commit introduced a call to
maybe_constant_value in cp_build_array_ref.  In this testcase we call it with

   f (VIEW_CONVERT_EXPR("BAR")) ? 1 : 0

argument and that crashes in fold_convert because we end up trying to convert
"BAR" of type const char[4] to const char * when evaluating the call.  At this
point, decay_conversion hasn't turned the argument into (const char *) "BAR"
yet.

The ICE doesn't occur without :?, because then the call will be wrapped in
NON_DEPENDENT_EXPR and constexpr throws its hands (I'm anthropomorphizing) up
when it encounters such an expression.

I noticed that build_non_dependent_expr doesn't wrap op0 of ?: in N_D_E.  This
is so since r70606 -- Nathan, is there a reason not to do it?  Doing it fixes
this problem.

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

2019-09-11  Marek Polacek  

PR c++/91740 - ICE with constexpr call and ?: in ARRAY_REF.
* pt.c (build_non_dependent_expr): Call build_non_dependent_expr for
the first operand.

* g++.dg/cpp1y/var-templ63.C: New test.

diff --git gcc/cp/pt.c gcc/cp/pt.c
index c5915a5ecd0..775389d8245 100644
--- gcc/cp/pt.c
+++ gcc/cp/pt.c
@@ -26709,7 +26709,7 @@ build_non_dependent_expr (tree expr)
if (TREE_CODE (expr) == COND_EXPR)
  return build3 (COND_EXPR,
   TREE_TYPE (expr),
-  TREE_OPERAND (expr, 0),
+  build_non_dependent_expr (TREE_OPERAND (expr, 0)),
   (TREE_OPERAND (expr, 1)
? build_non_dependent_expr (TREE_OPERAND (expr, 1))
: build_non_dependent_expr (TREE_OPERAND (expr, 0))),


OK.  I wonder why this code copies op0 for the ?: extension rather than 
leave it null?


Jason



Re: [C++ Patch] Another bunch of location fixes

2019-09-15 Thread Jason Merrill

On 9/12/19 9:41 AM, Paolo Carlini wrote:

+ if (!valid_array_size_p (dname
+  ? declarator->id_loc : input_location,


Use the id_loc local variable?

OK with that change.

Jason



Re: C++ PATCH for c++/91678 - wrong error with decltype and location wrapper

2019-09-15 Thread Jason Merrill

On 9/5/19 9:24 PM, Marek Polacek wrote:

They use
non_lvalue_loc, but that won't create a NON_LVALUE_EXPR wrapper around a 
location
wrapper.


That seems like the bug. maybe_lvalue_p should be true for 
VIEW_CONVERT_EXPR.


Jason


[patch, fortran] Fix ICE on invalid with DO steps

2019-09-15 Thread Thomas Koenig

Hello world,

the attached patch fixes an ICE on invalid, where the fact that
the step in do i = 1, 3, .1 is actually zero slipped through.

Regression-tested.  OK for all affected branches (trunk, 9 and 8)?

Regards

Thomas

2019-09-15  Thomas Koenig  

PR fortran/91550
* frontend-passes.c (do_subscript): If step equals
zero, a previuos error has been reported; do nothing
in this case.
* resolve.c (gfc_resolve_iterator): Move error checking
after type conversion.

2019-09-15  Thomas Koenig  

PR fortran/91550
* gfortran.dg/do_subscript_6.f90: New test.


Index: frontend-passes.c
===
--- frontend-passes.c	(Revision 275719)
+++ frontend-passes.c	(Arbeitskopie)
@@ -2578,6 +2578,7 @@ do_subscript (gfc_expr **e)
 	  bool have_do_start, have_do_end;
 	  bool error_not_proven;
 	  int warn;
+	  int sgn;
 
 	  dl = lp->c;
 	  if (dl == NULL)
@@ -2606,7 +2607,16 @@ do_subscript (gfc_expr **e)
 		 Do not warn in this case.  */
 
 	  if (dl->ext.iterator->step->expr_type == EXPR_CONSTANT)
-		mpz_init_set (do_step, dl->ext.iterator->step->value.integer);
+		{
+		  sgn = mpz_cmp_ui (dl->ext.iterator->step->value.integer, 0);
+		  /* This can happen, but then the error has been
+		 reported previusly.  */
+		  if (sgn == 0)
+		continue;
+
+		  mpz_init_set (do_step, dl->ext.iterator->step->value.integer);
+		}
+
 	  else
 		continue;
 
@@ -2632,9 +2642,8 @@ do_subscript (gfc_expr **e)
 	  /* No warning inside a zero-trip loop.  */
 	  if (have_do_start && have_do_end)
 		{
-		  int sgn, cmp;
+		  int cmp;
 
-		  sgn = mpz_cmp_ui (do_step, 0);
 		  cmp = mpz_cmp (do_end, do_start);
 		  if ((sgn > 0 && cmp < 0) || (sgn < 0 && cmp > 0))
 		break;
Index: resolve.c
===
--- resolve.c	(Revision 275719)
+++ resolve.c	(Arbeitskopie)
@@ -7105,6 +7105,19 @@ gfc_resolve_iterator (gfc_iterator *iter, bool rea
   "Step expression in DO loop"))
 return false;
 
+  /* Convert start, end, and step to the same type as var.  */
+  if (iter->start->ts.kind != iter->var->ts.kind
+  || iter->start->ts.type != iter->var->ts.type)
+gfc_convert_type (iter->start, >var->ts, 1);
+
+  if (iter->end->ts.kind != iter->var->ts.kind
+  || iter->end->ts.type != iter->var->ts.type)
+gfc_convert_type (iter->end, >var->ts, 1);
+
+  if (iter->step->ts.kind != iter->var->ts.kind
+  || iter->step->ts.type != iter->var->ts.type)
+gfc_convert_type (iter->step, >var->ts, 1);
+
   if (iter->step->expr_type == EXPR_CONSTANT)
 {
   if ((iter->step->ts.type == BT_INTEGER
@@ -7118,19 +7131,6 @@ gfc_resolve_iterator (gfc_iterator *iter, bool rea
 	}
 }
 
-  /* Convert start, end, and step to the same type as var.  */
-  if (iter->start->ts.kind != iter->var->ts.kind
-  || iter->start->ts.type != iter->var->ts.type)
-gfc_convert_type (iter->start, >var->ts, 1);
-
-  if (iter->end->ts.kind != iter->var->ts.kind
-  || iter->end->ts.type != iter->var->ts.type)
-gfc_convert_type (iter->end, >var->ts, 1);
-
-  if (iter->step->ts.kind != iter->var->ts.kind
-  || iter->step->ts.type != iter->var->ts.type)
-gfc_convert_type (iter->step, >var->ts, 1);
-
   if (iter->start->expr_type == EXPR_CONSTANT
   && iter->end->expr_type == EXPR_CONSTANT
   && iter->step->expr_type == EXPR_CONSTANT)
! { dg-do compile }
! { dg-options "-std=legacy" }
! PR 91550 - this used to cause an ICE
! Test case by Gerhard Steinmetz
program p
   real :: a(3)
   integer :: i
   do i = 1, 3, .1 ! { dg-error "cannot be zero" }
  a(i) = i
   end do
end


[C++ PATCH] simplify clone predicate

2019-09-15 Thread Nathan Sidwell
This patch replaces the decl_cloned_function_p function call with simpler macro 
uses.  As only cdtors are cloned, we can use IDENTIFIER_CDTOR_P to check.


In the process I discovered the documentation had bitrotted -- we were giving 
non-function_decls to the predicate, sometimes intentionally (template_decls), 
and sometimes unintentionally (record_types).  The new semantics are we can give 
 any _decl to the predicate and only function_decls to the accessor.  The 
change in pt.d is because at namespace scope, we chain record_types ( & 
unions) on the chain list.  Previously that was harmless but now causes the 
predicate to assert.


Applying to trunk.

nathan
--
Nathan Sidwell
2019-09-15  Nathan Sidwell  

	* cp-tree.h (DECL_CLONED_FUNCTION_P): Reimplement using
	IDENTIFIER_CDTOR_P, correct documentation.
	(DECL_CLONED_FUNCTION): Directly access field.
	(decl_cloned_function_p): Delete.
	* class.c (decl_cloned_function_p): Delete.
	* pt.c (instantiate_template_1): Check DECL_CHAIN is a decl.

Index: gcc/cp/class.c
===
--- gcc/cp/class.c	(revision 275726)
+++ gcc/cp/class.c	(working copy)
@@ -4701,43 +4701,6 @@ build_clone (tree fn, tree name)
   return clone;
 }
 
-/* Implementation of DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P, do
-   not invoke this function directly.
-
-   For a non-thunk function, returns the address of the slot for storing
-   the function it is a clone of.  Otherwise returns NULL_TREE.
-
-   If JUST_TESTING, looks through TEMPLATE_DECL and returns NULL if
-   cloned_function is unset.  This is to support the separate
-   DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P modes; using the latter
-   on a template makes sense, but not the former.  */
-
-tree *
-decl_cloned_function_p (const_tree decl, bool just_testing)
-{
-  tree *ptr;
-  if (just_testing)
-decl = STRIP_TEMPLATE (decl);
-
-  if (TREE_CODE (decl) != FUNCTION_DECL
-  || !DECL_LANG_SPECIFIC (decl)
-  || DECL_LANG_SPECIFIC (decl)->u.fn.thunk_p)
-{
-#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
-  if (!just_testing)
-	lang_check_failed (__FILE__, __LINE__, __FUNCTION__);
-  else
-#endif
-	return NULL;
-}
-
-  ptr = _LANG_SPECIFIC (decl)->u.fn.u5.cloned_function;
-  if (just_testing && *ptr == NULL_TREE)
-return NULL;
-  else
-return ptr;
-}
-
 /* Produce declarations for all appropriate clones of FN.  If
UPDATE_METHODS is true, the clones are added to the
CLASSTYPE_MEMBER_VEC.  */
Index: gcc/cp/cp-tree.h
===
--- gcc/cp/cp-tree.h	(revision 275726)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -2874,13 +2874,17 @@ struct GTY(()) lang_decl {
   (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (NODE)\
|| DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (NODE))
 
-/* Nonzero if NODE (a FUNCTION_DECL) is a cloned constructor or
+/* Nonzero if NODE (a _DECL) is a cloned constructor or
destructor.  */
-#define DECL_CLONED_FUNCTION_P(NODE) (!!decl_cloned_function_p (NODE, true))
+#define DECL_CLONED_FUNCTION_P(NODE)		\
+  (DECL_NAME (NODE)\
+   && IDENTIFIER_CDTOR_P (DECL_NAME (NODE))	\
+   && !DECL_MAYBE_IN_CHARGE_CDTOR_P (NODE))
 
 /* If DECL_CLONED_FUNCTION_P holds, this is the function that was
cloned.  */
-#define DECL_CLONED_FUNCTION(NODE) (*decl_cloned_function_p (NODE, false))
+#define DECL_CLONED_FUNCTION(NODE)		\
+  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE))->u.fn.u5.cloned_function)
 
 /* Perform an action for each clone of FN, if FN is a function with
clones.  This macro should be used like:
@@ -6333,7 +6337,6 @@ extern void check_abi_tags			(tree);
 extern tree missing_abi_tags			(tree);
 extern void fixup_type_variants			(tree);
 extern void fixup_attribute_variants		(tree);
-extern tree* decl_cloned_function_p		(const_tree, bool);
 extern void clone_function_decl			(tree, bool);
 extern void adjust_clone_args			(tree);
 extern void deduce_noexcept_on_destructor   (tree);
Index: gcc/cp/pt.c
===
--- gcc/cp/pt.c	(revision 275726)
+++ gcc/cp/pt.c	(working copy)
@@ -19905,8 +19905,9 @@ instantiate_template_1 (tree tmpl, tree
  instantiate all the alternate entry points as well.  We do this
  by cloning the instantiation of the main entry point, not by
  instantiating the template clones.  */
-  if (DECL_CHAIN (gen_tmpl) && DECL_CLONED_FUNCTION_P (DECL_CHAIN (gen_tmpl)))
-clone_function_decl (fndecl, /*update_methods=*/false);
+  if (tree chain = DECL_CHAIN (gen_tmpl))
+if (DECL_P (chain) && DECL_CLONED_FUNCTION_P (chain))
+  clone_function_decl (fndecl, /*update_methods=*/false);
 
   if (!access_ok)
 {


[Patch, fortran] PR91588 - ICE in check_inquiry, at fortran/expr.c:2673

2019-09-15 Thread Paul Richard Thomas
The attached bootstraps and regtests on FC30/x86_64 - OK for trunk?

It strikes me that this should be backported since the bug is rather
fundamental and ispresent all the way back to version 4.8. An obvious
question is how far back? To 8-branch?

Cheers

Paul

2019-09-15  Paul Thomas  

PR fortran/91588
* expr.c (check_inquiry): Remove extended component refs by
using symbol pointers. If a function argument is an associate
variable with a constant target, copy the target expression in
place of the argument expression. Check that the charlen is not
NULL before using the string length.
(gfc_check_assign): Remove extraneous space.

2019-09-15  Paul Thomas  

PR fortran/91588
* gfortran.dg/associate_49.f90 : New test.
Index: gcc/fortran/expr.c
===
*** gcc/fortran/expr.c	(revision 275695)
--- gcc/fortran/expr.c	(working copy)
*** check_inquiry (gfc_expr *e, int not_rest
*** 2610,2615 
--- 2610,2617 
  
int i = 0;
gfc_actual_arglist *ap;
+   gfc_symbol *sym;
+   gfc_symbol *asym;
  
if (!e->value.function.isym
|| !e->value.function.isym->inquiry)
*** check_inquiry (gfc_expr *e, int not_rest
*** 2619,2638 
if (e->symtree == NULL)
  return MATCH_NO;
  
!   if (e->symtree->n.sym->from_intmod)
  {
!   if (e->symtree->n.sym->from_intmod == INTMOD_ISO_FORTRAN_ENV
! 	  && e->symtree->n.sym->intmod_sym_id != ISOFORTRAN_COMPILER_OPTIONS
! 	  && e->symtree->n.sym->intmod_sym_id != ISOFORTRAN_COMPILER_VERSION)
  	return MATCH_NO;
  
!   if (e->symtree->n.sym->from_intmod == INTMOD_ISO_C_BINDING
! 	  && e->symtree->n.sym->intmod_sym_id != ISOCBINDING_C_SIZEOF)
  	return MATCH_NO;
  }
else
  {
!   name = e->symtree->n.sym->name;
  
functions = inquiry_func_gnu;
if (gfc_option.warn_std & GFC_STD_F2003)
--- 2621,2642 
if (e->symtree == NULL)
  return MATCH_NO;
  
!   sym = e->symtree->n.sym;
! 
!   if (sym->from_intmod)
  {
!   if (sym->from_intmod == INTMOD_ISO_FORTRAN_ENV
! 	  && sym->intmod_sym_id != ISOFORTRAN_COMPILER_OPTIONS
! 	  && sym->intmod_sym_id != ISOFORTRAN_COMPILER_VERSION)
  	return MATCH_NO;
  
!   if (sym->from_intmod == INTMOD_ISO_C_BINDING
! 	  && sym->intmod_sym_id != ISOCBINDING_C_SIZEOF)
  	return MATCH_NO;
  }
else
  {
!   name = sym->name;
  
functions = inquiry_func_gnu;
if (gfc_option.warn_std & GFC_STD_F2003)
*** check_inquiry (gfc_expr *e, int not_rest
*** 2657,2697 
if (!ap->expr)
  	continue;
  
if (ap->expr->ts.type == BT_UNKNOWN)
  	{
! 	  if (ap->expr->symtree->n.sym->ts.type == BT_UNKNOWN
! 	  && !gfc_set_default_type (ap->expr->symtree->n.sym, 0, gfc_current_ns))
  	return MATCH_NO;
  
! 	  ap->expr->ts = ap->expr->symtree->n.sym->ts;
  	}
  
! 	/* Assumed character length will not reduce to a constant expression
! 	   with LEN, as required by the standard.  */
! 	if (i == 5 && not_restricted && ap->expr->symtree
! 	&& ap->expr->symtree->n.sym->ts.type == BT_CHARACTER
! 	&& (ap->expr->symtree->n.sym->ts.u.cl->length == NULL
! 		|| ap->expr->symtree->n.sym->ts.deferred))
! 	  {
! 	gfc_error ("Assumed or deferred character length variable %qs "
! 			"in constant expression at %L",
! 			ap->expr->symtree->n.sym->name,
! 			>expr->where);
! 	  return MATCH_ERROR;
! 	  }
! 	else if (not_restricted && !gfc_check_init_expr (ap->expr))
! 	  return MATCH_ERROR;
  
! 	if (not_restricted == 0
! 	  && ap->expr->expr_type != EXPR_VARIABLE
! 	  && !check_restricted (ap->expr))
  	  return MATCH_ERROR;
  
! 	if (not_restricted == 0
! 	&& ap->expr->expr_type == EXPR_VARIABLE
! 	&& ap->expr->symtree->n.sym->attr.dummy
! 	&& ap->expr->symtree->n.sym->attr.optional)
! 	  return MATCH_NO;
  }
  
return MATCH_YES;
--- 2661,2708 
if (!ap->expr)
  	continue;
  
+   asym = ap->expr->symtree ? ap->expr->symtree->n.sym : NULL;
+ 
if (ap->expr->ts.type == BT_UNKNOWN)
  	{
! 	  if (asym && asym->ts.type == BT_UNKNOWN
! 	  && !gfc_set_default_type (asym, 0, gfc_current_ns))
  	return MATCH_NO;
  
! 	  ap->expr->ts = asym->ts;
  	}
  
!   if (asym && asym->assoc && asym->assoc->target
! 	  && asym->assoc->target->expr_type == EXPR_CONSTANT)
! 	{
! 	  gfc_free_expr (ap->expr);
! 	  ap->expr = gfc_copy_expr (asym->assoc->target);
! 	}
  
!   /* Assumed character length will not reduce to a constant expression
! 	 with LEN, as required by the standard.  */
!   if (i == 5 && not_restricted && asym
! 	  && asym->ts.type == BT_CHARACTER
! 	  && ((asym->ts.u.cl && asym->ts.u.cl->length == NULL)
! 	  || asym->ts.deferred))
! 	{
! 	  gfc_error ("Assumed or deferred character length variable %qs "
! 		 "in constant expression at %L",
! 		  asym->name, >expr->where);
  	  return MATCH_ERROR;
+ 	}
+   else if (not_restricted &&