[C++ PATCH] PR c++/86398

2018-07-04 Thread Ville Voutilainen
This has been buggy for a while, but since we were implementing
the library triviality traits in terms of just the intrinsic since GCC 8,
not too many users ran into it. The bug has been worked around
in the library, but I'd rather have the intrinsic give the right
answer and not require the library work-around.

Tested on Linux-PPC64, ok for trunk and the gcc-8 branch?

2018-07-04  Ville Voutilainen  

gcc/cp/

PR c++/86398
* method.c (is_trivially_xible): Return false
if is_xible_helper returns a NULL_TREE.

testsuite/

PR c++/86398
* g++.dg/ext/is_trivially_constructible1.C: Add new tests.
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 858655b..0b208a8 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1216,7 +1216,7 @@ is_trivially_xible (enum tree_code code, tree to, tree from)
   tree expr;
   expr = is_xible_helper (code, to, from, /*trivial*/true);
 
-  if (expr == error_mark_node)
+  if (expr == NULL_TREE || expr == error_mark_node)
 return false;
   tree nt = cp_walk_tree_without_duplicates (&expr, check_nontriv, NULL);
   return !nt;
diff --git a/gcc/testsuite/g++.dg/ext/is_trivially_constructible1.C b/gcc/testsuite/g++.dg/ext/is_trivially_constructible1.C
index 175eae9..191b696 100644
--- a/gcc/testsuite/g++.dg/ext/is_trivially_constructible1.C
+++ b/gcc/testsuite/g++.dg/ext/is_trivially_constructible1.C
@@ -39,6 +39,11 @@ SA(!__is_trivially_constructible(void,int));
 SA(!__is_trivially_constructible(const void,int));
 SA(!__is_trivially_constructible(volatile void,int));
 SA(!__is_trivially_constructible(const volatile void,int));
+SA(!__is_trivially_constructible(int, void*));
+SA(!__is_trivially_constructible(int, int*));
+SA(!__is_trivially_constructible(int, const int*));
+SA(!__is_trivially_constructible(int*, void*));
+SA(!__is_trivially_constructible(int*, const int*));
 
 SA(!__is_trivially_constructible(D));
 


[C++ PATCH] PR c++/79133

2018-07-06 Thread Ville Voutilainen
Tested on Linux-PPC64. Ok for trunk, perhaps with the change
that I move the test under cpp1y, since it's a c++14 test anyway?

I considered pushing the captures into the parameter scope. I don't
know how to do that; changing the pushdecl_outermost_localscope
to a pushdecl doesn't seem to cut it; I guess that I should add
a new function into name-lookup.[ch], but I wonder whether
that makes sense, considering that this is lambda-only functionality.
I also wonder whether it makes more sense than the solution
in this patch, considering that we handle packs here as well
and capturepack/parampack, capturepack/param, capture/parampack
and capture/param clashes.

Guidance welcome. This approach has the benefit that it, well,
seems to work. :)

2018-07-07  Ville Voutilainen  

gcc/cp/

PR c++/79133
* lambda.c (start_lambda_function): Reject captures and parameters
with the same name.

testsuite/

PR c++/79133
* g++.dg/cpp0x/lambda/lambda-shadow3.C: New.
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 3776d6b..534434a 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -1424,7 +1424,28 @@ start_lambda_function (tree fco, tree lambda_expr)
   /* Push the proxies for any explicit captures.  */
   for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); cap;
cap = TREE_CHAIN (cap))
-build_capture_proxy (TREE_PURPOSE (cap), TREE_VALUE (cap));
+{
+  /* DR 2211: check that captures and parameters
+	 do not have the same name. */
+  for (tree parms = DECL_ARGUMENTS (fco); parms;
+	   parms = TREE_CHAIN (parms))
+	{
+	  tree real_cap = TREE_VALUE (cap);
+	  tree real_parms = parms;
+	  if (PACK_EXPANSION_P (real_cap))
+	real_cap = PACK_EXPANSION_PATTERN (real_cap);
+	  if (PACK_EXPANSION_P (parms))
+	real_parms = PACK_EXPANSION_PATTERN (parms);
+	  if (DECL_P (real_cap)
+	  && DECL_NAME (real_cap) != this_identifier
+	  && DECL_NAME (real_cap) == DECL_NAME (real_parms))
+	error_at (DECL_SOURCE_LOCATION (parms),
+		  "capture %qE and lambda parameter %qE "
+		  "have the same name",
+		  cap, parms);
+	}
+  build_capture_proxy (TREE_PURPOSE (cap), TREE_VALUE (cap));
+}
 
   return body;
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
new file mode 100644
index 000..b006470
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++14 } }
+
+int main() {
+  int x = 42;
+  auto lambda = [x](int x) {}; // { dg-error "have the same name" }
+  auto lambda2 = [x=x](int x) {}; // { dg-error "have the same name" }
+  auto lambda3 = [x](auto... x) {}; // { dg-error "have the same name" }
+  auto lambda4 = [](auto... x) {
+auto lambda5 = [x...](auto... x) {};  // { dg-error "have the same name" }
+auto lambda6 = [x...](int x) {};  // { dg-error "have the same name" }
+  };
+}


Re: [C++ PATCH] PR c++/79133

2018-07-07 Thread Ville Voutilainen
On 7 July 2018 at 16:15, Jason Merrill  wrote:
> Did you consider handling this in check_local_shadow?

Roughly like this, not fully tested yet:

2018-07-07  Ville Voutilainen  

gcc/cp/

PR c++/79133
* name-lookup.c (check_local_shadow): Reject captures and parameters
with the same name.

testsuite/

PR c++/79133
* g++.dg/cpp0x/lambda/lambda-shadow3.C: New.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 3aafb0f..cc2d3c0 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2640,6 +2640,7 @@ check_local_shadow (tree decl)
 		  || TREE_CODE (decl) == TYPE_DECL)))
   && DECL_FUNCTION_SCOPE_P (old)
   && (!DECL_ARTIFICIAL (decl)
+	  || is_capture_proxy (decl)
 	  || DECL_IMPLICIT_TYPEDEF_P (decl)
 	  || (VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl
 {
@@ -2648,7 +2649,8 @@ check_local_shadow (tree decl)
   /* Don't complain if it's from an enclosing function.  */
   if (DECL_CONTEXT (old) == current_function_decl
 	  && TREE_CODE (decl) != PARM_DECL
-	  && TREE_CODE (old) == PARM_DECL)
+	  && TREE_CODE (old) == PARM_DECL
+	  && !is_capture_proxy (decl))
 	{
 	  /* Go to where the parms should be and see if we find
 	 them there.  */
@@ -2665,6 +2667,20 @@ check_local_shadow (tree decl)
 	  return;
 	}
 	}
+  /* DR 2211: check that captures and parameters
+	 do not have the same name. */
+  else if (current_lambda_expr ()
+	   && DECL_CONTEXT (old) == lambda_function (current_lambda_expr ())
+	   && TREE_CODE (old) == PARM_DECL
+	   && is_capture_proxy (decl))
+	{
+	  if (DECL_NAME (decl) != this_identifier)
+	error_at (DECL_SOURCE_LOCATION (old),
+		  "capture %qE and lambda parameter %qE "
+		  "have the same name",
+		  decl, old);
+	  return;
+	}
 
   /* The local structure or class can't use parameters of
 	 the containing function anyway.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
new file mode 100644
index 000..b006470
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++14 } }
+
+int main() {
+  int x = 42;
+  auto lambda = [x](int x) {}; // { dg-error "have the same name" }
+  auto lambda2 = [x=x](int x) {}; // { dg-error "have the same name" }
+  auto lambda3 = [x](auto... x) {}; // { dg-error "have the same name" }
+  auto lambda4 = [](auto... x) {
+auto lambda5 = [x...](auto... x) {};  // { dg-error "have the same name" }
+auto lambda6 = [x...](int x) {};  // { dg-error "have the same name" }
+  };
+}


Re: [C++ PATCH] PR c++/79133

2018-07-07 Thread Ville Voutilainen
On 7 July 2018 at 21:12, Paolo Carlini  wrote:
> Should we really print the same name twice? Looks like we don't have
> available (yet) a location for cap - that would likely enable fancy things -
> but in that case too I don't think the user would find that interesting
> seeing the same name twice. Also, we are using %E, thus we are pretty
> printing expressions - which in general we don't want to do - I see that in
> the case of cap it gives pretty obfuscated results for the last two tests
> (what the heck is __lambda3?!?). So, all in all, maybe print the name once,
> as parms, or something like that, for the time being? Or try to avoid %E
> altogether?

What should I print instead of %E?


Re: [C++ PATCH] PR c++/79133

2018-07-07 Thread Ville Voutilainen
On 7 July 2018 at 21:55, Ville Voutilainen  wrote:
> On 7 July 2018 at 21:12, Paolo Carlini  wrote:
>> Should we really print the same name twice? Looks like we don't have
>> available (yet) a location for cap - that would likely enable fancy things -
>> but in that case too I don't think the user would find that interesting
>> seeing the same name twice. Also, we are using %E, thus we are pretty
>> printing expressions - which in general we don't want to do - I see that in
>> the case of cap it gives pretty obfuscated results for the last two tests
>> (what the heck is __lambda3?!?). So, all in all, maybe print the name once,
>> as parms, or something like that, for the time being? Or try to avoid %E
>> altogether?
>
> What should I print instead of %E?

%qD instead of %qE, presumably. That seems to do the same thing in the
new patch, but I can sure change it.
Attached.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 3aafb0f..b883054 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2640,6 +2640,7 @@ check_local_shadow (tree decl)
 		  || TREE_CODE (decl) == TYPE_DECL)))
   && DECL_FUNCTION_SCOPE_P (old)
   && (!DECL_ARTIFICIAL (decl)
+	  || is_capture_proxy (decl)
 	  || DECL_IMPLICIT_TYPEDEF_P (decl)
 	  || (VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl
 {
@@ -2648,7 +2649,8 @@ check_local_shadow (tree decl)
   /* Don't complain if it's from an enclosing function.  */
   if (DECL_CONTEXT (old) == current_function_decl
 	  && TREE_CODE (decl) != PARM_DECL
-	  && TREE_CODE (old) == PARM_DECL)
+	  && TREE_CODE (old) == PARM_DECL
+	  && !is_capture_proxy (decl))
 	{
 	  /* Go to where the parms should be and see if we find
 	 them there.  */
@@ -2665,6 +2667,20 @@ check_local_shadow (tree decl)
 	  return;
 	}
 	}
+  /* DR 2211: check that captures and parameters
+	 do not have the same name. */
+  else if (current_lambda_expr ()
+	   && DECL_CONTEXT (old) == lambda_function (current_lambda_expr ())
+	   && TREE_CODE (old) == PARM_DECL
+	   && is_capture_proxy (decl))
+	{
+	  if (DECL_NAME (decl) != this_identifier)
+	error_at (DECL_SOURCE_LOCATION (old),
+		  "capture %qD and lambda parameter %qD "
+		  "have the same name",
+		  decl, old);
+	  return;
+	}
 
   /* The local structure or class can't use parameters of
 	 the containing function anyway.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
new file mode 100644
index 000..b006470
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++14 } }
+
+int main() {
+  int x = 42;
+  auto lambda = [x](int x) {}; // { dg-error "have the same name" }
+  auto lambda2 = [x=x](int x) {}; // { dg-error "have the same name" }
+  auto lambda3 = [x](auto... x) {}; // { dg-error "have the same name" }
+  auto lambda4 = [](auto... x) {
+auto lambda5 = [x...](auto... x) {};  // { dg-error "have the same name" }
+auto lambda6 = [x...](int x) {};  // { dg-error "have the same name" }
+  };
+}


Re: [C++ PATCH] PR c++/79133

2018-07-07 Thread Ville Voutilainen
Needed one more tweak; when dealing with a capture proxy, always bail
out and never fall through to the warning-handling
code below the DR 2211 check.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 3aafb0f..fee5482 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2640,6 +2640,7 @@ check_local_shadow (tree decl)
 		  || TREE_CODE (decl) == TYPE_DECL)))
   && DECL_FUNCTION_SCOPE_P (old)
   && (!DECL_ARTIFICIAL (decl)
+	  || is_capture_proxy (decl)
 	  || DECL_IMPLICIT_TYPEDEF_P (decl)
 	  || (VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl
 {
@@ -2648,7 +2649,8 @@ check_local_shadow (tree decl)
   /* Don't complain if it's from an enclosing function.  */
   if (DECL_CONTEXT (old) == current_function_decl
 	  && TREE_CODE (decl) != PARM_DECL
-	  && TREE_CODE (old) == PARM_DECL)
+	  && TREE_CODE (old) == PARM_DECL
+	  && !is_capture_proxy (decl))
 	{
 	  /* Go to where the parms should be and see if we find
 	 them there.  */
@@ -2665,6 +2667,20 @@ check_local_shadow (tree decl)
 	  return;
 	}
 	}
+  /* DR 2211: check that captures and parameters
+	 do not have the same name. */
+  else if (is_capture_proxy (decl))
+	{
+	  if (current_lambda_expr ()
+	  && DECL_CONTEXT (old) == lambda_function (current_lambda_expr ())
+	  && TREE_CODE (old) == PARM_DECL
+	  && DECL_NAME (decl) != this_identifier)
+	error_at (DECL_SOURCE_LOCATION (old),
+		  "capture %qD and lambda parameter %qD "
+		  "have the same name",
+		  decl, old);
+	  return;
+	}
 
   /* The local structure or class can't use parameters of
 	 the containing function anyway.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
new file mode 100644
index 000..b006470
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++14 } }
+
+int main() {
+  int x = 42;
+  auto lambda = [x](int x) {}; // { dg-error "have the same name" }
+  auto lambda2 = [x=x](int x) {}; // { dg-error "have the same name" }
+  auto lambda3 = [x](auto... x) {}; // { dg-error "have the same name" }
+  auto lambda4 = [](auto... x) {
+auto lambda5 = [x...](auto... x) {};  // { dg-error "have the same name" }
+auto lambda6 = [x...](int x) {};  // { dg-error "have the same name" }
+  };
+}


Re: [C++ PATCH] PR c++/79133

2018-07-07 Thread Ville Voutilainen
On 8 July 2018 at 00:35, Paolo Carlini  wrote:
> Hi,
>
> On 07/07/2018 23:20, Ville Voutilainen wrote:
>>
>> +   error_at (DECL_SOURCE_LOCATION (old),
>> + "capture %qD and lambda parameter %qD "
>> + "have the same name",
>> + decl, old);
>
> Let's consider, say (with -Wshadow):
>
> int main() {
>   int x = 42;
>   auto lambda0 = [x]() { int x; };
> }
>
> I'm thinking that the new diagnostic should be more consistent with it.

There are a couple of errors that do an "error: redeclaration of foo"
followed by an inform "previously declared here". I would suggest that I do
an "error: declaration of parameter foo"
followed by an inform "previously declared as a capture here". How
does that sound?
That would make this more consistent with such a shadow warning, but I
don't want
to use the shadowing wording (which would be easy to do; just set
'shadowed' and do
a 'goto inform'), because this isn't shadowing in the precise sense;
the shadowing cases
are warnings, whereas this is more like the redeclaration errors in
the same function.


Re: [C++ PATCH] PR c++/79133

2018-07-07 Thread Ville Voutilainen
On 8 July 2018 at 01:54, Paolo Carlini  wrote:
>> That would make this more consistent with such a shadow warning, but I
>> don't want
>> to use the shadowing wording (which would be easy to do; just set
>> 'shadowed' and do
>> a 'goto inform'), because this isn't shadowing in the precise sense;
>> the shadowing cases
>> are warnings, whereas this is more like the redeclaration errors in
>> the same function.
>
> ... indeed and that annoys me a bit. Not having studied at all c++/79133 so
> far (sorry) it seems a little weird to me that according to the standard we
> have to handle the two types of "shadowing" in different ways, one more
> strict, one less. Thus I would suggest double checking the details of that,
> eventually with Jason too in terms of the actual patch you would like to
> apply.

Well. The PR is about DR 2211 which, in simple terms, says that lambda
parameters
and captures cannot have the same name. See
http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#2211

That's stricter than -Wshadow, but otherwise equally strict as the
other error cases already handled
in check_local_shadow. So I'll make this error case more consistent
with the others. We already
handle redeclaration errors slightly differently from shadowing
warnings in that function.


Re: [PATCH] Simplify the base characteristics for some type traits

2018-07-19 Thread Ville Voutilainen
On 19 July 2018 at 20:18, Jonathan Wakely  wrote:
> This removes some seemingly redundant conditions from a few traits. If
> __is_trivially_assignable correctly checks the assignable condition as
> well as triviality, then we don't need is_assignable explicitly.  Does
> anybody see a problem with that

It should work; if it doesn't, that's a bug in the compiler. Both
is_constructible
and is_assignable and trivial variants thereof go to the same
"is_xible" code path,
so it should be fair for the library to expect that it all works. In
case it doesn't,
that's something that I will fix in the front-end.

> I added some extra tests for cases that had been problematic with
> __is_trivially_constructible.

That seems reasonable; some of those tests are now duplicated on the
compiler side,
but I think that's fine.


Re: [PATCH] PR libstdc++/86751 default assignment operators for std::pair

2018-07-31 Thread Ville Voutilainen
On 31 July 2018 at 20:07, Jonathan Wakely  wrote:
> The solution for PR 77537 causes ambiguities due to the extra copy
> assignment operator taking a __nonesuch_no_braces parameter. The copy
> and move assignment operators can be defined as defaulted to meet the
> semantics required by the standard.
>
> In order to preserve ABI compatibility (specifically argument passing
> conventions for pair) we need a new base class that makes the
> assignment operators non-trivial.
>
> PR libstdc++/86751
> * include/bits/stl_pair.h (__nonesuch_no_braces): Remove.
> (__pair_base): New class with non-trivial copy assignment operator.
> (pair): Derive from __pair_base. Define copy assignment and move
> assignment operators as defaulted.
> * testsuite/20_util/pair/86751.cc: New test.
>
>
> Ville, this passes all our tests, but am I forgetting something that
> means this isn't right?

Pairs of references?


Re: [PATCH] libstdc++: Compile std::allocator instantiations as C++20

2024-04-11 Thread Ville Voutilainen
On Thu, 11 Apr 2024 at 20:22, Jonathan Wakely  wrote:
>
> I'm considering this late patch for gcc-14 to workaround an issue
> discovered by a recent Clang change.
>
> I'm not yet sure if Clang is right to require these symbols. It's not
> really clear, because always_inline isn't part of the standard so it's
> not clear how it should interact with explicit instantiations and
> modules. Exporting these four extra symbols doesn't hurt, even if Clang
> ends up reverting or revising its change that requires them.
>
> Another way to fix it would be to suppress the explicit instantiation
> declarations in  for C++20, so that the compiler
> always instantiates them implicitly as needed. We do similar things for
> the explicit instantiations of std::string etc. so that new member
> functions that aren't in the .so are implicitly instantiated as needed.
>
> That would look like this instead:
>
> --- a/libstdc++-v3/include/bits/allocator.h
> +++ b/libstdc++-v3/include/bits/allocator.h
> @@ -281,7 +281,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
>// Inhibit implicit instantiations for required instantiations,
>// which are defined via explicit instantiations elsewhere.
> -#if _GLIBCXX_EXTERN_TEMPLATE
> +#if _GLIBCXX_EXTERN_TEMPLATE && __cplusplus <= 201703L
>extern template class allocator;
>extern template class allocator;
>  #endif
>
> But we might want to export the new functions from the library
> eventually anyway, so doing it now (before Clang 19 is released) might
> be the best option.
>
> Thoughts?

I think the symbol export is a fine solution. Both of these solutions
work, so I don't have a strong preference,
I have a minor preference for not suppressing explicit instantiations
that are otherwise already there,
but that is indeed not a strong preference.


Re: [PATCH] libstdc++: Implement P2255R2 dangling checks for std::tuple [PR108822]

2024-01-11 Thread Ville Voutilainen
On Fri, 12 Jan 2024 at 00:16, Jonathan Wakely  wrote:
>
> I'd like to commit this to trunk for GCC 14. Please take a look.

Without looking at it in excruciating detail, it's pretty much along
the lines of what I have always envisioned
to be a powerful combination of concepts and if-constexpr. My general
principle on this is "looks like an improvement,
so if it passes all the tests, ship it". :)

Sure, I have envisioned going even further with that combination, such
as significantly reducing the number of overloads
and doing more of it as an if-constexpr ladder, but there's a balance
where emulating the effects of overload resolution
in something like that can become such a burden that the benefits are
no longer there. If the field were green, I'd consider
that as the approach from the get-go when initially designing a type
like tuple, instead of doing it as an overload set.


Re: [PATCH 1/3] libstdc++: Use RAII in

2024-07-03 Thread Ville Voutilainen
On Wed, 3 Jul 2024 at 18:33, Jonathan Wakely  wrote:
>
> On Thu, 27 Jun 2024 at 11:52, Jonathan Wakely wrote:
> >
> > This refactoring to use RAII doesn't seem to make any difference in
> > benchmarks, although the generated code for some std::vector operations
> > seems to be slightly larger. Maybe it will be faster (or slower) in some
> > cases I didn't test?
> >
> > I think I like the change anyway - any other opinions on whether it's an
> > improvement?
>
> Any thoughts before I push this? Better? Worse? Needs more cowbell?

I think the patch is an improvement. Push it.


Re: [PATCH 1/2] libstdc++: Move std::optional assertions out of _M_get()

2024-07-24 Thread Ville Voutilainen
On Wed, 24 Jul 2024 at 22:51, Jonathan Wakely  wrote:
>
> Tested x86_64-linux.
>
> Any reason not to do this? I don't think the assertions are useful to
> catch implementation bugs where we access the contained value without
> checking it - we should use tests for that.

Looks good to me.

> The current assertions also result in repeated invalid bug reports, such
> as PR 91281, PR 101659, PR 102712, and PR 107894.

I'm not sure moving the assertions helps with that, maybe some of
those bug reports
are caused by people not knowing how to enable the assertions.


Re: Trait built-in naming convention

2024-05-02 Thread Ville Voutilainen
On Thu, 2 May 2024 at 20:25, Ken Matsui  wrote:
> > There was some discussion of how to name the built-ins back in
> > https://gcc.gnu.org/pipermail/gcc-patches/2007-March/thread.html#212171
> > but __builtin wasn't discussed.
> >
> > Apparently this naming convention follows the MSVC precedent:
> > http://msdn2.microsoft.com/en-us/library/ms177194.aspx
> >
> > I notice some discussion of this pattern around Clang adding various
> > built-ins in https://github.com/llvm/llvm-project/issues/61852
> > indicating that this is a policy based on precedent.
> >
> > But I don't see any actual reason for this pattern other than that it's
> > what Paolo happened to do in 2007.
> >
> > I'm not sure what the right way forward is.  Perhaps we're stuck with
> > the questionable choices of the past.
> >
>
> Hmm, I personally prefer the __builtin prefix.  However, it seems that
> we need to reach a consensus across MSVC, Clang, and GCC.  Would this
> be realistically possible?
>
> Until then, I think it would be better to use __ for all built-in
> traits.  What do you think?

My 0.02: __builtin as a prefix doesn't serve much of a purpose.
Consider __is_constructible. It doesn't add value
to make that __builtin_is_constructible. It's a built-in. Of course
it's a built-in. It's a compiler-implemented trait, and
this is just the intrinsic that implements it.

Most of the existing builtins for traits don't use a __builtin prefix.
Not in GCC, not in other compilers. They are indeed
just double-underscored versions of the traits. I think that's fine,
and consistent. There's precedent for this
across Embarcadero, Clang, MSVC, and GCC. See
https://clang.llvm.org/docs/LanguageExtensions.html

Yes, I know it's inconsistent with other built-ins that aren't C++
library traits. But the water's been flowing under
the bridge on that question for a while now.

I would also prefer at least considering mimicking a trait builtin's
name if some other compiler did it first. That's not a hill
to die on, we don't need to be 100% compatible including the naming,
but if we can, we should just use a name that was
chosen by someone else already. It's just nice to have the same name
if the traits do exactly the same thing. If they don't,
then it's good and in fact very good to give our trait a different name.


Re: [PATCH] libstdc++: Rewrite std::variant comparisons without macros

2024-05-07 Thread Ville Voutilainen
On Tue, 7 May 2024 at 16:47, Jonathan Wakely  wrote:
>
> I don't think using a macro for these really saves us much, we can do
> this to avoid duplication instead. And now it's not a big, multi-line
> macro that's a pain to edit.
>
> Any objections?

No, that's beautiful, ship it.


[v3 PATCH] Implement make_array and to_array from the Fundamentals v2 TS draft

2015-07-12 Thread Ville Voutilainen
Tested on Linux-PPC64.

2015-07-12  Ville Voutilainen  
Implement std::experimental::fundamentals_v2::make_array and
std::experimental::fundamentals_v2::to_array.
* include/Makefile.am: Add array.
* include/Makefile.in: Add array.
* include/experimental/array: New.
* testsuite/experimental/array/make_array.cc: Likewise.
* testsuite/experimental/array/neg.cc: Likewise.
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 05be8ad..41fc4af 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -646,6 +646,7 @@ experimental_builddir = ./experimental
 experimental_headers = \
${experimental_srcdir}/algorithm \
${experimental_srcdir}/any \
+   ${experimental_srcdir}/array \
${experimental_srcdir}/chrono \
${experimental_srcdir}/deque \
${experimental_srcdir}/erase_if.h \
@@ -657,6 +658,7 @@ experimental_headers = \
${experimental_srcdir}/memory \
${experimental_srcdir}/numeric \
${experimental_srcdir}/optional \
+   ${experimental_srcdir}/propagate_const \
${experimental_srcdir}/ratio \
${experimental_srcdir}/set \
${experimental_srcdir}/string \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index bab83b4..b2a140c 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -935,6 +935,7 @@ experimental_builddir = ./experimental
 experimental_headers = \
${experimental_srcdir}/algorithm \
${experimental_srcdir}/any \
+   ${experimental_srcdir}/array \
${experimental_srcdir}/chrono \
${experimental_srcdir}/deque \
${experimental_srcdir}/erase_if.h \
@@ -946,6 +947,7 @@ experimental_headers = \
${experimental_srcdir}/memory \
${experimental_srcdir}/numeric \
${experimental_srcdir}/optional \
+   ${experimental_srcdir}/propagate_const \
${experimental_srcdir}/ratio \
${experimental_srcdir}/set \
${experimental_srcdir}/string \
diff --git a/libstdc++-v3/include/experimental/array 
b/libstdc++-v3/include/experimental/array
new file mode 100644
index 000..1e1b60e
--- /dev/null
+++ b/libstdc++-v3/include/experimental/array
@@ -0,0 +1,106 @@
+//  -*- C++ -*-
+
+// Copyright (C) 2015 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file experimental/array
+ *  This is a TS C++ Library header.
+ */
+
+#ifndef _GLIBCXX_EXPERIMENTAL_ARRAY
+#define _GLIBCXX_EXPERIMENTAL_ARRAY 1
+
+#pragma GCC system_header
+
+#if __cplusplus <= 201103L
+# include 
+#else
+
+#include 
+#include 
+#include 
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace experimental
+{
+inline namespace fundamentals_v2
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   * @defgroup make_array Array creation functions
+   * @ingroup experimental
+   *
+   * Array creation functions as described in N4529,
+   * Working Draft, C++ Extensions for Library Fundamentals, Version 2
+   *
+   * @{
+   */
+
+template 
+struct __is_reference_wrapper : false_type
+{ };
+
+template 
+struct __is_reference_wrapper> : true_type
+{ };
+
+template 
+constexpr auto make_array(_Types&&... __t)
+  -> array,
+ common_type_t<_Types...>,
+ _D>,
+   sizeof...(_Types)>
+{
+  static_assert(__or_<__not_>,
+__and_<__not_<__is_reference_wrapper>>...>>
+::value,
+"make_array cannot be used without an explicit target type "
+"if any of the types given is a reference_wrapper");
+  return {{__t...}};
+}
+
+template 
+constexpr array, _N>
+__to_array(_Tp (&__a)[_N],
+   index_sequence<_Idx...>)
+{
+  return {{__a[_Idx]...}};
+}
+
+template 
+constexpr array, _N> to_array(_Tp (&__a)[_N])
+{
+  return __to_array(__a, make_index_sequence<_N

Re: [v3 PATCH] Implement make_array and to_array from the Fundamentals v2 TS draft

2015-07-12 Thread Ville Voutilainen
On 12 July 2015 at 21:45, Ville Voutilainen  wrote:
> Tested on Linux-PPC64.
>
> 2015-07-12  Ville Voutilainen  
> Implement std::experimental::fundamentals_v2::make_array and
> std::experimental::fundamentals_v2::to_array.
> * include/Makefile.am: Add array.
> * include/Makefile.in: Add array.
> * include/experimental/array: New.
> * testsuite/experimental/array/make_array.cc: Likewise.
> * testsuite/experimental/array/neg.cc: Likewise.

Very minor cleanup in a new patch, use is_void<_D> instead of is_same<_D, void>,
indent the static assert a bit more clearly.
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 05be8ad..41fc4af 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -646,6 +646,7 @@ experimental_builddir = ./experimental
 experimental_headers = \
${experimental_srcdir}/algorithm \
${experimental_srcdir}/any \
+   ${experimental_srcdir}/array \
${experimental_srcdir}/chrono \
${experimental_srcdir}/deque \
${experimental_srcdir}/erase_if.h \
@@ -657,6 +658,7 @@ experimental_headers = \
${experimental_srcdir}/memory \
${experimental_srcdir}/numeric \
${experimental_srcdir}/optional \
+   ${experimental_srcdir}/propagate_const \
${experimental_srcdir}/ratio \
${experimental_srcdir}/set \
${experimental_srcdir}/string \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index bab83b4..b2a140c 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -935,6 +935,7 @@ experimental_builddir = ./experimental
 experimental_headers = \
${experimental_srcdir}/algorithm \
${experimental_srcdir}/any \
+   ${experimental_srcdir}/array \
${experimental_srcdir}/chrono \
${experimental_srcdir}/deque \
${experimental_srcdir}/erase_if.h \
@@ -946,6 +947,7 @@ experimental_headers = \
${experimental_srcdir}/memory \
${experimental_srcdir}/numeric \
${experimental_srcdir}/optional \
+   ${experimental_srcdir}/propagate_const \
${experimental_srcdir}/ratio \
${experimental_srcdir}/set \
${experimental_srcdir}/string \
diff --git a/libstdc++-v3/include/experimental/array 
b/libstdc++-v3/include/experimental/array
new file mode 100644
index 000..1ce4118
--- /dev/null
+++ b/libstdc++-v3/include/experimental/array
@@ -0,0 +1,107 @@
+//  -*- C++ -*-
+
+// Copyright (C) 2015 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file experimental/array
+ *  This is a TS C++ Library header.
+ */
+
+#ifndef _GLIBCXX_EXPERIMENTAL_ARRAY
+#define _GLIBCXX_EXPERIMENTAL_ARRAY 1
+
+#pragma GCC system_header
+
+#if __cplusplus <= 201103L
+# include 
+#else
+
+#include 
+#include 
+#include 
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace experimental
+{
+inline namespace fundamentals_v2
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   * @defgroup make_array Array creation functions
+   * @ingroup experimental
+   *
+   * Array creation functions as described in N4529,
+   * Working Draft, C++ Extensions for Library Fundamentals, Version 2
+   *
+   * @{
+   */
+
+template 
+struct __is_reference_wrapper : false_type
+{ };
+
+template 
+struct __is_reference_wrapper> : true_type
+{ };
+
+template 
+constexpr auto make_array(_Types&&... __t)
+  -> array,
+ common_type_t<_Types...>,
+ _D>,
+   sizeof...(_Types)>
+{
+  static_assert(__or_<
+  __not_>,
+  __and_<__not_<__is_reference_wrapper>>...>>
+::value,
+"make_array cannot be used without an explicit target type "
+"if any of the types given is a reference_wrapper");
+  return {{__t...}};
+}
+

Re: [v3 PATCH] Implement make_array and to_array from the Fundamentals v2 TS draft

2015-07-13 Thread Ville Voutilainen
On 13 July 2015 at 01:25, Ville Voutilainen  wrote:
> On 12 July 2015 at 21:45, Ville Voutilainen  
> wrote:
>> Tested on Linux-PPC64.
>>
>> 2015-07-12  Ville Voutilainen  
>> Implement std::experimental::fundamentals_v2::make_array and
>> std::experimental::fundamentals_v2::to_array.
>> * include/Makefile.am: Add array.
>> * include/Makefile.in: Add array.
>> * include/experimental/array: New.
>> * testsuite/experimental/array/make_array.cc: Likewise.
>> * testsuite/experimental/array/neg.cc: Likewise.
>
> Very minor cleanup in a new patch, use is_void<_D> instead of is_same<_D, 
> void>,
> indent the static assert a bit more clearly.

Oops, the implementation failed to forward() in make_array, new patch attached,
with a test for make_array with a move-only type.
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 05be8ad..41fc4af 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -646,6 +646,7 @@ experimental_builddir = ./experimental
 experimental_headers = \
${experimental_srcdir}/algorithm \
${experimental_srcdir}/any \
+   ${experimental_srcdir}/array \
${experimental_srcdir}/chrono \
${experimental_srcdir}/deque \
${experimental_srcdir}/erase_if.h \
@@ -657,6 +658,7 @@ experimental_headers = \
${experimental_srcdir}/memory \
${experimental_srcdir}/numeric \
${experimental_srcdir}/optional \
+   ${experimental_srcdir}/propagate_const \
${experimental_srcdir}/ratio \
${experimental_srcdir}/set \
${experimental_srcdir}/string \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index bab83b4..b2a140c 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -935,6 +935,7 @@ experimental_builddir = ./experimental
 experimental_headers = \
${experimental_srcdir}/algorithm \
${experimental_srcdir}/any \
+   ${experimental_srcdir}/array \
${experimental_srcdir}/chrono \
${experimental_srcdir}/deque \
${experimental_srcdir}/erase_if.h \
@@ -946,6 +947,7 @@ experimental_headers = \
${experimental_srcdir}/memory \
${experimental_srcdir}/numeric \
${experimental_srcdir}/optional \
+   ${experimental_srcdir}/propagate_const \
${experimental_srcdir}/ratio \
${experimental_srcdir}/set \
${experimental_srcdir}/string \
diff --git a/libstdc++-v3/include/experimental/array 
b/libstdc++-v3/include/experimental/array
new file mode 100644
index 000..b72895c
--- /dev/null
+++ b/libstdc++-v3/include/experimental/array
@@ -0,0 +1,107 @@
+//  -*- C++ -*-
+
+// Copyright (C) 2015 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file experimental/array
+ *  This is a TS C++ Library header.
+ */
+
+#ifndef _GLIBCXX_EXPERIMENTAL_ARRAY
+#define _GLIBCXX_EXPERIMENTAL_ARRAY 1
+
+#pragma GCC system_header
+
+#if __cplusplus <= 201103L
+# include 
+#else
+
+#include 
+#include 
+#include 
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace experimental
+{
+inline namespace fundamentals_v2
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   * @defgroup make_array Array creation functions
+   * @ingroup experimental
+   *
+   * Array creation functions as described in N4529,
+   * Working Draft, C++ Extensions for Library Fundamentals, Version 2
+   *
+   * @{
+   */
+
+template 
+struct __is_reference_wrapper : false_type
+{ };
+
+template 
+struct __is_reference_wrapper> : true_type
+{ };
+
+template 
+constexpr auto make_array(_Types&&... __t)
+  -> array,
+ common_type_t<_Types...>,
+ _D>,
+   sizeof...(_Types)>
+{
+  static_assert(__or_<
+  __not_>,
+  __and_<__no

[v3 PATCH] Implement N4280, Non-member size() and more (Revision 2)

2015-07-14 Thread Ville Voutilainen
Tested on Linux-PPC64.

2015-07-15  Ville Voutilainen  
Implement N4280, Non-member size() and more (Revision 2)
* include/bits/range_access.h: Change class to typename
in every template.
* include/bits/range_access.h(size, empty, data): New.
* testsuite/24_iterators/container_access.cc: New.
diff --git a/libstdc++-v3/include/bits/range_access.h 
b/libstdc++-v3/include/bits/range_access.h
index 510c0b1..448462f 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -43,7 +43,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the container.
*  @param  __cont  Container.
*/
-  template
+  template
 inline auto
 begin(_Container& __cont) -> decltype(__cont.begin())
 { return __cont.begin(); }
@@ -53,7 +53,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the const container.
*  @param  __cont  Container.
*/
-  template
+  template
 inline auto
 begin(const _Container& __cont) -> decltype(__cont.begin())
 { return __cont.begin(); }
@@ -63,7 +63,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the container.
*  @param  __cont  Container.
*/
-  template
+  template
 inline auto
 end(_Container& __cont) -> decltype(__cont.end())
 { return __cont.end(); }
@@ -73,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the const container.
*  @param  __cont  Container.
*/
-  template
+  template
 inline auto
 end(const _Container& __cont) -> decltype(__cont.end())
 { return __cont.end(); }
@@ -82,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @brief  Return an iterator pointing to the first element of the array.
*  @param  __arr  Array.
*/
-  template
+  template
 inline _GLIBCXX14_CONSTEXPR _Tp*
 begin(_Tp (&__arr)[_Nm])
 { return __arr; }
@@ -92,7 +92,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  of the array.
*  @param  __arr  Array.
*/
-  template
+  template
 inline _GLIBCXX14_CONSTEXPR _Tp*
 end(_Tp (&__arr)[_Nm])
 { return __arr + _Nm; }
@@ -103,7 +103,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the const container.
*  @param  __cont  Container.
*/
-  template
+  template
 inline constexpr auto
 cbegin(const _Container& __cont) noexcept(noexcept(std::begin(__cont)))
   -> decltype(std::begin(__cont))
@@ -114,7 +114,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the const container.
*  @param  __cont  Container.
*/
-  template
+  template
 inline constexpr auto
 cend(const _Container& __cont) noexcept(noexcept(std::end(__cont)))
   -> decltype(std::end(__cont))
@@ -125,7 +125,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the container.
*  @param  __cont  Container.
*/
-  template
+  template
 inline auto
 rbegin(_Container& __cont) -> decltype(__cont.rbegin())
 { return __cont.rbegin(); }
@@ -135,7 +135,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the const container.
*  @param  __cont  Container.
*/
-  template
+  template
 inline auto
 rbegin(const _Container& __cont) -> decltype(__cont.rbegin())
 { return __cont.rbegin(); }
@@ -145,7 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the container.
*  @param  __cont  Container.
*/
-  template
+  template
 inline auto
 rend(_Container& __cont) -> decltype(__cont.rend())
 { return __cont.rend(); }
@@ -155,7 +155,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the const container.
*  @param  __cont  Container.
*/
-  template
+  template
 inline auto
 rend(const _Container& __cont) -> decltype(__cont.rend())
 { return __cont.rend(); }
@@ -165,7 +165,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the array.
*  @param  __arr  Array.
*/
-  template
+  template
 inline reverse_iterator<_Tp*>
 rbegin(_Tp (&__arr)[_Nm])
 { return reverse_iterator<_Tp*>(__arr + _Nm); }
@@ -175,7 +175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the array.
*  @param  __arr  Array.
*/
-  template
+  template
 inline reverse_iterator<_Tp*>
 rend(_Tp (&__arr)[_Nm])
 { return reverse_iterator<_Tp*>(__arr); }
@@ -185,7 +185,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the initializer_list.
*  @param  __il  initializer_list.
*/
-  template
+  template
 inline reverse_iterator
 rbegin(initializer_list<_Tp> __il)
 { return reverse_iterator(__il.end()); }
@@ -195,7 +195,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the initializer_list.
*  @param  __il  initializer_list.
*/
-  template
+  template
 inline reverse_iterator
 rend(initializer_list<_Tp> __il)
 { return reverse_iterator(__il.begin()); }
@@ -205,7 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  the const container.
*  @param 

[v3 PATCH] Implement N4089 and N4387

2015-07-19 Thread Ville Voutilainen
Tested on Linux-PPC64.

2015-07-19  Ville Voutilainen  
Implement N4089 Safe conversions in unique_ptr (LWG 2118)
and N4387 LWG 2228: Missing SFINAE rule in unique_ptr
templated assignment
* include/bits/unique_ptr.h
(__remove_cv, __is_derived_Tp): Remove.
(default_delete::default_delete(const default_delete<_Up[]>)):
Constrain with array convertibility.
(default_delete::operator(_Up*)): Turn into a template,
constrain with array convertibility.
(__safe_conversion_up): New, single object version.
(unique_ptr(unique_ptr<_Up, _Ep>&& __u)): Constrain with array
convertibility.
(unique_ptr::operator=(unique_ptr<_Up, _Ep>&& __u)): Likewise, and add
is_assignable as a constraint.
(__safe_conversion_up): Array version, renamed from __safe_conversion,
updated to implement N4089.
(__safe_conversion_raw): New.
(unique_ptr(_Up __p)): Turn into a template, constrain with array
convertibility.
(unique_ptr(_Up __p,
typename conditional::value,
deleter_type, const deleter_type&>::type __d)): Likewise.
(unique_ptr(_Up __p, typename
 remove_reference::type&& __d)): Likewise.
(unique_ptr(unique_ptr<_Up, _Ep>&& __u)): Likewise.
(operator=(unique_ptr<_Up, _Ep>&& __u)): Likewise, and add
is_assignable as a constraint (array version).
(reset(_Up __p)): Turn into a template, constrain with array
convertibility.
(reset(nullptr_t p)): New.
* testsuite/20_util/default_delete/48631_neg.cc: Adjust.
* testsuite/20_util/unique_ptr/assign/48635.cc: Likewise.
* testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise.
* testsuite/20_util/unique_ptr/assign/cv_qual.cc: Likewise.
* testsuite/20_util/unique_ptr/cons/cv_qual.cc: Likewise.
* testsuite/20_util/unique_ptr/dr2228.cc: New.
* testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Adjust.


unique_ptr_fixes.diff.gz
Description: GNU Zip compressed data


Re: [v3 PATCH] Implement N4089 and N4387

2015-07-19 Thread Ville Voutilainen
On 19 July 2015 at 19:56, Ville Voutilainen  wrote:
> Tested on Linux-PPC64.
>
> 2015-07-19  Ville Voutilainen  
> Implement N4089 Safe conversions in unique_ptr (LWG 2118)
> and N4387 LWG 2228: Missing SFINAE rule in unique_ptr
> templated assignment
> * include/bits/unique_ptr.h
> (__remove_cv, __is_derived_Tp): Remove.
> (default_delete::default_delete(const default_delete<_Up[]>)):
> Constrain with array convertibility.
> (default_delete::operator(_Up*)): Turn into a template,
> constrain with array convertibility.
> (__safe_conversion_up): New, single object version.
> (unique_ptr(unique_ptr<_Up, _Ep>&& __u)): Constrain with array
> convertibility.
> (unique_ptr::operator=(unique_ptr<_Up, _Ep>&& __u)): Likewise, and add
> is_assignable as a constraint.
> (__safe_conversion_up): Array version, renamed from __safe_conversion,
> updated to implement N4089.
> (__safe_conversion_raw): New.
> (unique_ptr(_Up __p)): Turn into a template, constrain with array
> convertibility.
> (unique_ptr(_Up __p,
> typename conditional::value,
> deleter_type, const deleter_type&>::type __d)): Likewise.
> (unique_ptr(_Up __p, typename
>  remove_reference::type&& __d)): Likewise.
> (unique_ptr(unique_ptr<_Up, _Ep>&& __u)): Likewise.
> (operator=(unique_ptr<_Up, _Ep>&& __u)): Likewise, and add
> is_assignable as a constraint (array version).
> (reset(_Up __p)): Turn into a template, constrain with array
> convertibility.
> (reset(nullptr_t p)): New.
> * testsuite/20_util/default_delete/48631_neg.cc: Adjust.
> * testsuite/20_util/unique_ptr/assign/48635.cc: Likewise.
> * testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise.
> * testsuite/20_util/unique_ptr/assign/cv_qual.cc: Likewise.
> * testsuite/20_util/unique_ptr/cons/cv_qual.cc: Likewise.
> * testsuite/20_util/unique_ptr/dr2228.cc: New.
> * testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Adjust.

Minor changelog fix, the single-pointer functions aren't constrained with
array compatibility, but with deleter compatibility.

2015-07-19  Ville Voutilainen  
Implement N4089 Safe conversions in unique_ptr (LWG 2118)
and N4387 LWG 2228: Missing SFINAE rule in unique_ptr
templated assignment
* include/bits/unique_ptr.h
(__remove_cv, __is_derived_Tp): Remove.
(default_delete::default_delete(const default_delete<_Up[]>)):
Constrain with array convertibility.
(default_delete::operator(_Up*)): Turn into a template,
constrain with array convertibility.
(__safe_conversion_up): New, single object version.
(unique_ptr(unique_ptr<_Up, _Ep>&& __u)): Constrain with deleter
convertibility.
(unique_ptr::operator=(unique_ptr<_Up, _Ep>&& __u)): Likewise, and add
is_assignable as a constraint.
(__safe_conversion_up): Array version, renamed from __safe_conversion,
updated to implement N4089.
(__safe_conversion_raw): New.
(unique_ptr(_Up __p)): Turn into a template, constrain with array
convertibility.
(unique_ptr(_Up __p,
typename conditional::value,
deleter_type, const deleter_type&>::type __d)): Likewise.
(unique_ptr(_Up __p, typename
 remove_reference::type&& __d)): Likewise.
(unique_ptr(unique_ptr<_Up, _Ep>&& __u)): Likewise.
(operator=(unique_ptr<_Up, _Ep>&& __u)): Likewise, and add
is_assignable as a constraint (array version).
(reset(_Up __p)): Turn into a template, constrain with array
convertibility.
(reset(nullptr_t p)): New.
* testsuite/20_util/default_delete/48631_neg.cc: Adjust.
* testsuite/20_util/unique_ptr/assign/48635.cc: Likewise.
* testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise.
* testsuite/20_util/unique_ptr/assign/cv_qual.cc: Likewise.
* testsuite/20_util/unique_ptr/cons/cv_qual.cc: Likewise.
* testsuite/20_util/unique_ptr/dr2228.cc: New.
* testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Adjust.


Re: [v3 PATCH] Implement N4089 and N4387

2015-07-19 Thread Ville Voutilainen
On 19 July 2015 at 20:13, Ville Voutilainen  wrote:
> Minor changelog fix, the single-pointer functions aren't constrained with
> array compatibility, but with deleter compatibility.

And that should be single-object, not single-pointer, not that it has any
effect on the corrected changelog. :)


Re: [v3 PATCH] Implement N4089 and N4387

2015-07-19 Thread Ville Voutilainen
On 19 July 2015 at 20:14, Ville Voutilainen  wrote:
> On 19 July 2015 at 20:13, Ville Voutilainen  
> wrote:
>> Minor changelog fix, the single-pointer functions aren't constrained with
>> array compatibility, but with deleter compatibility.
>
> And that should be single-object, not single-pointer, not that it has any
> effect on the corrected changelog. :)

Argh, the paper number in the status table was wrong, although the
link was correct,
so the paper number for the missing sfinae condition in the changelog
was also wrong.

2015-07-19  Ville Voutilainen  
Implement N4089 Safe conversions in unique_ptr (LWG 2118)
and N4366 LWG 2228: Missing SFINAE rule in unique_ptr
templated assignment
* include/bits/unique_ptr.h
(__remove_cv, __is_derived_Tp): Remove.
(default_delete::default_delete(const default_delete<_Up[]>)):
Constrain with array convertibility.
(default_delete::operator(_Up*)): Turn into a template,
constrain with array convertibility.
(__safe_conversion_up): New, single object version.
(unique_ptr(unique_ptr<_Up, _Ep>&& __u)): Constrain with deleter
convertibility.
(unique_ptr::operator=(unique_ptr<_Up, _Ep>&& __u)): Likewise, and add
is_assignable as a constraint.
(__safe_conversion_up): Array version, renamed from __safe_conversion,
updated to implement N4089.
(__safe_conversion_raw): New.
(unique_ptr(_Up __p)): Turn into a template, constrain with array
convertibility.
(unique_ptr(_Up __p,
typename conditional::value,
deleter_type, const deleter_type&>::type __d)): Likewise.
(unique_ptr(_Up __p, typename
 remove_reference::type&& __d)): Likewise.
(unique_ptr(unique_ptr<_Up, _Ep>&& __u)): Likewise.
(operator=(unique_ptr<_Up, _Ep>&& __u)): Likewise, and add
is_assignable as a constraint (array version).
(reset(_Up __p)): Turn into a template, constrain with array
convertibility.
(reset(nullptr_t p)): New.
* testsuite/20_util/default_delete/48631_neg.cc: Adjust.
* testsuite/20_util/unique_ptr/assign/48635.cc: Likewise.
* testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise.
* testsuite/20_util/unique_ptr/assign/cv_qual.cc: Likewise.
* testsuite/20_util/unique_ptr/cons/cv_qual.cc: Likewise.
* testsuite/20_util/unique_ptr/dr2228.cc: New.
* testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Adjust.


[v3 PATCH] Implement N4279, Improved insertion interface for unique-key maps.

2015-07-20 Thread Ville Voutilainen
Tested on Linux-PPC64.

2015-07-21  Ville Voutilainen  
Implement N4279, Improved insertion interface for unique-key maps.
* include/bits/stl_map.h (try_emplace, insert_or_assign): New.
* include/bits/stl_tree.h (_M_get_insert_unique_pos,
_M_get_insert_equal_pos, _M_get_insert_hint_unique_pos,
_M_get_insert_hint_equal_pos): Make public.
* include/bits/unordered_map.h (try_emplace, insert_or_assign): New.
* testsuite/23_containers/map/modifiers/insert_or_assign/1.cc:
Likewise.
* testsuite/23_containers/map/modifiers/try_emplace/1.cc: Likewise.
* testsuite/23_containers/unordered_map/modifiers/insert_or_assign.cc:
Likewise.
* testsuite/23_containers/unordered_map/modifiers/try_emplace.cc:
Likewise.


improved-interface.diff.gz
Description: GNU Zip compressed data


[v3 PATCH] PR libstdc++/60970, implement LWG 2148

2015-07-25 Thread Ville Voutilainen
Tested on Linux-PPC64.

The proposed resolution of the issue doesn't really say whether our
regression test for PR libstdc++/52931 should remain valid. However,
it doesn't say that we shouldn't keep it valid, either. This approach
keeps it valid, but provides support for hashing enums. It took a while
to figure out suitable jiggery-pokery to make it so, but this approach
passes the testsuite without regressions. I considered an alternative
alias-template-based approach, but while that attempt would've worked
with our current front-end, it would not have worked on clang (and
it's thus far unclear whether it was intended to work by the language
rules).

2015-07-25  Ville Voutilainen  
PR libstdc++/60970, implement LWG 2148, hash support for
enum types.
* include/bits/functional_hash.h
(__hash_enum): New.
(hash): Derive from __hash_enum.
* testsuite/20_util/hash/60970.cc: New.
diff --git a/libstdc++-v3/include/bits/functional_hash.h 
b/libstdc++-v3/include/bits/functional_hash.h
index d94843f..f81864f 100644
--- a/libstdc++-v3/include/bits/functional_hash.h
+++ b/libstdc++-v3/include/bits/functional_hash.h
@@ -57,6 +57,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct hash;
 
+  // Helper struct for SFINAE-poisoning non-enum types.
+  template
+struct __hash_enum
+{
+private:
+  __hash_enum(__hash_enum&&);
+  ~__hash_enum();
+};
+
+  // Helper struct for hash with enum types.
+  template
+struct __hash_enum<_Tp, true> : public __hash_base
+{
+  size_t
+  operator()(_Tp __val) const noexcept
+  {
+   using __type = typename underlying_type<_Tp>::type;
+   return hash<__type>{}(static_cast<__type>(__val));
+  }
+};
+
+  /// Primary class template hash, usable for enum types only.
+  // Use with non-enum types still SFINAES.
+  template
+struct hash : __hash_enum<_Tp, is_enum<_Tp>::value>
+{ };
+
   /// Partial specializations for pointer types.
   template
 struct hash<_Tp*> : public __hash_base
diff --git a/libstdc++-v3/testsuite/20_util/hash/60970.cc 
b/libstdc++-v3/testsuite/20_util/hash/60970.cc
new file mode 100644
index 000..ddc626f
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/hash/60970.cc
@@ -0,0 +1,36 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do run }
+
+// Copyright (C) 2015 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
+// <http://www.gnu.org/licenses/>.
+
+
+#include 
+#include 
+
+using namespace std;
+
+enum E1 : int {FIRST=1, SECOND=2};
+enum class E2 : int {THIRD=42, FOURTH=666};
+
+int main()
+{
+  VERIFY(hash{}(1) == hash{}(FIRST));
+  VERIFY(hash{}(2) == hash{}(SECOND));
+  VERIFY(hash{}(42) == hash{}(E2::THIRD));
+  VERIFY(hash{}(666) == hash{}(E2::FOURTH));
+}


[PATCH COMMITTED] MAINTAINERS (Write After Approval): Add myself.

2015-07-29 Thread Ville Voutilainen
Fyi.

2015-07-29  Ville Voutilainen  
* MAINTAINERS (Write After Approval): Add myself.
diff --git a/ChangeLog b/ChangeLog
index 4fcf016..bf49729 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2015-07-29  Ville Voutilainen  
+   * MAINTAINERS (Write After Approval): Add myself.
+
 2012-12-29  Ben Elliston  
 
* config.sub, config.guess: Import from upstream.
diff --git a/MAINTAINERS b/MAINTAINERS
index bdfd2be..1e9211a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -592,6 +592,7 @@ Andre Vehreschild   
 Alex Velenko   
 Ilya Verbin
 Kugan Vivekanandarajah 
+Ville Voutilainen  
 Tom de Vries   
 Nenad Vukicevic
 Feng Wang  


Re: [PATCH COMMITTED] MAINTAINERS (Write After Approval): Add myself.

2015-07-29 Thread Ville Voutilainen
On 29 July 2015 at 21:48, Marek Polacek  wrote:
> On Wed, Jul 29, 2015 at 08:29:34PM +0300, Ville Voutilainen wrote:
>> Fyi.
>>
>> 2015-07-29  Ville Voutilainen  
>> * MAINTAINERS (Write After Approval): Add myself.
>
> There should be a blank line between these two lines.

Ok, I added the blank line and committed the change as obvious. :)


Re: [PATCH COMMITTED] MAINTAINERS (Write After Approval): Add myself.

2015-07-29 Thread Ville Voutilainen
On 29 July 2015 at 22:18, Ville Voutilainen  wrote:
> On 29 July 2015 at 21:48, Marek Polacek  wrote:
>> On Wed, Jul 29, 2015 at 08:29:34PM +0300, Ville Voutilainen wrote:
>>> Fyi.
>>>
>>> 2015-07-29  Ville Voutilainen  
>>> * MAINTAINERS (Write After Approval): Add myself.
>>
>> There should be a blank line between these two lines.
>
> Ok, I added the blank line and committed the change as obvious. :)

Although the commit message for this supposedly obvious change is f**ked up
since it claims I modified MAINTAINERS, whereas I modified ChangeLog.
Such fun.


[PATCH, RFC] Implement N4230, Nested namespace definition

2015-09-16 Thread Ville Voutilainen
This is the first stab, I haven't written the tests yet. Feedback would be
most welcome; should I put this code into a separate function? Is the minor
code duplication with the regular namespace definition ok?
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 3a68dd7..00f18fb 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16750,7 +16750,7 @@ cp_parser_namespace_definition (cp_parser* parser)
   tree identifier, attribs;
   bool has_visibility;
   bool is_inline;
-
+  cp_token* token;
   cp_ensure_no_omp_declare_simd (parser);
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE))
 {
@@ -16762,7 +16762,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 is_inline = false;
 
   /* Look for the `namespace' keyword.  */
-  cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
+  token = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
 
   /* Get the name of the namespace.  We do not attempt to distinguish
  between an original-namespace-definition and an
@@ -16776,6 +16776,33 @@ cp_parser_namespace_definition (cp_parser* parser)
   /* Parse any specified attributes.  */
   attribs = cp_parser_attributes_opt (parser);
 
+  if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+{
+  if (is_inline)
+error_at (token->location, "a nested % definition cannot 
be inline");
+  push_namespace (identifier);
+  int nest_count = 0;
+  while (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+{
+  cp_lexer_consume_token (parser->lexer);
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+identifier = cp_parser_identifier (parser);
+  else
+{
+  cp_parser_error (parser, "nested identifier required");
+  break;
+}
+  ++nest_count;
+  push_namespace (identifier);
+}
+  cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
+  cp_parser_namespace_body (parser);
+  while (nest_count--)
+pop_namespace ();
+  pop_namespace ();
+  cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+  return;
+}
   /* Look for the `{' to start the namespace.  */
   cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
   /* Start the namespace.  */


Re: [C++] Coding rule enforcement

2015-09-17 Thread Ville Voutilainen
>>>+  else if (warn_multiple_inheritance)
>>>+warning (OPT_Wmultiple_inheritance,
>>>+ "%qT defined with multiple direct bases", ref);
>>You don't need to guard the warning with a check of the warning flag; warning
>>will only give the warning if the option is enabled.
>the spelling mistake on the option I used to experiment on didn't help, but I 
>>discovered one must have the Var clause in the options file too, which I 
>didn't expect.
>Anyway, fixed now.  ok?

Note that there are a couple of places where 'namespace' is misspelled
as 'namepace' in the patch.


Re: [PATCH, RFC] Implement N4230, Nested namespace definition

2015-09-17 Thread Ville Voutilainen
On 17 September 2015 at 23:11, Jason Merrill  wrote:
> On 09/16/2015 07:55 AM, Ville Voutilainen wrote:
>>
>> This is the first stab, I haven't written the tests yet. Feedback would be
>> most welcome; should I put this code into a separate function? Is the
>> minor
>> code duplication with the regular namespace definition ok?
>
>
> I think I'd prefer to keep it in the same function, but avoid the code
> duplication.

Ok. Tested on Linux-PPC64. This patch doesn't handle attributes yet, it looks to
me as if gcc doesn't support namespace attributes in the location that
the standard
grammar puts them into. I had to adjust a couple of
point-of-declaration error/warning
locations in the testsuite, but those seem reasonable to me, biased as
I may be towards keeping
this patch simpler than keeping those locations where they were would
likely require.

Nathan, this patch touches areas close to ones that your "Coding rule
enforcement" patch
does, please be aware of potential merge conflicts.

/cp
2015-09-18  Ville Voutilainen  

Implement nested namespace definitions.
* parser.c (cp_parser_namespace_definition): Grok nested namespace
definitions.

/testsuite
2015-09-18  Ville Voutilainen  

Implement nested namespace definitions.
* g++.dg/cpp1z/nested-namespace-def.C: New.
* g++.dg/lookup/name-clash5.C: Adjust.
* g++.dg/lookup/name-clash6.C: Likewise.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4f424b6..9fee310 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16953,6 +16953,8 @@ cp_parser_namespace_definition (cp_parser* parser)
   tree identifier, attribs;
   bool has_visibility;
   bool is_inline;
+  cp_token* token;
+  int nested_definition_count = 0;
 
   cp_ensure_no_omp_declare_simd (parser);
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE))
@@ -16965,7 +16967,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 is_inline = false;
 
   /* Look for the `namespace' keyword.  */
-  cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
+  token = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
 
   /* Get the name of the namespace.  We do not attempt to distinguish
  between an original-namespace-definition and an
@@ -16979,11 +16981,32 @@ cp_parser_namespace_definition (cp_parser* parser)
   /* Parse any specified attributes.  */
   attribs = cp_parser_attributes_opt (parser);
 
-  /* Look for the `{' to start the namespace.  */
-  cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
   /* Start the namespace.  */
   push_namespace (identifier);
 
+  /* Parse any nested namespace definition. */
+  if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+{
+  if (is_inline)
+error_at (token->location, "a nested % definition cannot 
be inline");
+  while (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+{
+  cp_lexer_consume_token (parser->lexer);
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+identifier = cp_parser_identifier (parser);
+  else
+{
+  cp_parser_error (parser, "nested identifier required");
+  break;
+}
+  ++nested_definition_count;
+  push_namespace (identifier);
+}
+}
+
+  /* Look for the `{' to validate starting the namespace.  */
+  cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
+
   /* "inline namespace" is equivalent to a stub namespace definition
  followed by a strong using directive.  */
   if (is_inline)
@@ -17007,6 +17030,10 @@ cp_parser_namespace_definition (cp_parser* parser)
   if (has_visibility)
 pop_visibility (1);
 
+  /* Finish the nested namespace definitions.  */
+  while (nested_definition_count--)
+pop_namespace ();
+
   /* Finish the namespace.  */
   pop_namespace ();
   /* Look for the final `}'.  */
diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def.C 
b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def.C
new file mode 100644
index 000..da35835
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def.C
@@ -0,0 +1,14 @@
+// { dg-options "-std=c++1z" }
+
+namespace A::B::C
+{
+   struct X {};
+   namespace T::U::V { struct Y {}; };
+};
+
+A::B::C::X x;
+A::B::C::T::U::V::Y y;
+
+inline namespace D::E {}; // { dg-error "cannot be inline" }
+
+namespace F::G:: {}; // { dg-error "nested identifier required" }
diff --git a/gcc/testsuite/g++.dg/lookup/name-clash5.C 
b/gcc/testsuite/g++.dg/lookup/name-clash5.C
index 74595c2..9673bb9 100644
--- a/gcc/testsuite/g++.dg/lookup/name-clash5.C
+++ b/gcc/testsuite/g++.dg/lookup/name-clash5.C
@@ -6,8 +6,8 @@
 // "[Note: a namespace name or a class template name must be unique in its
 // declarative region (7.3.2, clause 14). ]"
 
-namespace N
-{ // {

Re: [PATCH, RFC] Implement N4230, Nested namespace definition

2015-09-17 Thread Ville Voutilainen
On 18 September 2015 at 01:23, Ville Voutilainen
 wrote:
> Ok. Tested on Linux-PPC64. This patch doesn't handle attributes yet, it looks 
> to
> me as if gcc doesn't support namespace attributes in the location that
> the standard
> grammar puts them into. I had to adjust a couple of


Ahem, oops, the patch doesn't do any sort of a pedwarn for standard versions
below cpp1z; I'll do a new patch taking that into account tomorrow. I don't
think we have maybe_warn_cpp1z or anything like that? Any preferences
how to deal with that?


Re: [PATCH, RFC] Implement N4230, Nested namespace definition

2015-09-18 Thread Ville Voutilainen
On 18 September 2015 at 02:02, Ville Voutilainen
 wrote:
> Ahem, oops, the patch doesn't do any sort of a pedwarn for standard versions
> below cpp1z; I'll do a new patch taking that into account tomorrow. I don't
> think we have maybe_warn_cpp1z or anything like that? Any preferences
> how to deal with that?

Here. Tested on Linux-PPC64.

/cp
2015-09-18  Ville Voutilainen  

Implement nested namespace definitions.
* parser.c (cp_parser_namespace_definition): Grok nested namespace
definitions.

/testsuite
2015-09-18  Ville Voutilainen  

Implement nested namespace definitions.
* g++.dg/cpp1z/nested-namespace-def1.C: New.
* g++.dg/cpp1z/nested-namespace-def2.C: Likewise.
* g++.dg/cpp1z/nested-namespace-def3.C: Likewise.
* g++.dg/lookup/name-clash5.C: Adjust.
* g++.dg/lookup/name-clash6.C: Likewise.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4f424b6..602a90b 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16953,6 +16953,8 @@ cp_parser_namespace_definition (cp_parser* parser)
   tree identifier, attribs;
   bool has_visibility;
   bool is_inline;
+  cp_token* token;
+  int nested_definition_count = 0;
 
   cp_ensure_no_omp_declare_simd (parser);
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE))
@@ -16965,7 +16967,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 is_inline = false;
 
   /* Look for the `namespace' keyword.  */
-  cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
+  token = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
 
   /* Get the name of the namespace.  We do not attempt to distinguish
  between an original-namespace-definition and an
@@ -16979,11 +16981,36 @@ cp_parser_namespace_definition (cp_parser* parser)
   /* Parse any specified attributes.  */
   attribs = cp_parser_attributes_opt (parser);
 
-  /* Look for the `{' to start the namespace.  */
-  cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
   /* Start the namespace.  */
   push_namespace (identifier);
 
+  /* Parse any nested namespace definition. */
+  if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+{
+  if (cxx_dialect < cxx1z)
+pedwarn (input_location, OPT_Wpedantic,
+ "nested namespace definitions only available with "
+ "-std=c++17 or -std=gnu++17");
+  if (is_inline)
+error_at (token->location, "a nested namespace definition cannot be 
inline");
+  while (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+{
+  cp_lexer_consume_token (parser->lexer);
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+identifier = cp_parser_identifier (parser);
+  else
+{
+  cp_parser_error (parser, "nested identifier required");
+  break;
+}
+  ++nested_definition_count;
+  push_namespace (identifier);
+}
+}
+
+  /* Look for the `{' to validate starting the namespace.  */
+  cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
+
   /* "inline namespace" is equivalent to a stub namespace definition
  followed by a strong using directive.  */
   if (is_inline)
@@ -17007,6 +17034,10 @@ cp_parser_namespace_definition (cp_parser* parser)
   if (has_visibility)
 pop_visibility (1);
 
+  /* Finish the nested namespace definitions.  */
+  while (nested_definition_count--)
+pop_namespace ();
+
   /* Finish the namespace.  */
   pop_namespace ();
   /* Look for the final `}'.  */
diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C 
b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C
new file mode 100644
index 000..d710ef1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C
@@ -0,0 +1,14 @@
+// { dg-options "-std=c++1z" }
+
+namespace A::B::C
+{
+   struct X {};
+   namespace T::U::V { struct Y {}; }
+}
+
+A::B::C::X x;
+A::B::C::T::U::V::Y y;
+
+inline namespace D::E {} // { dg-error "cannot be inline" }
+
+namespace F::G:: {} // { dg-error "nested identifier required" }
diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def2.C 
b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def2.C
new file mode 100644
index 000..c47a94a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def2.C
@@ -0,0 +1,5 @@
+// { dg-options "-std=c++11 -pedantic-errors" }
+
+namespace A::B::C // { dg-error "nested namespace definitions only available 
with" }
+{
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def3.C 
b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def3.C
new file mode 100644
index 000..f2dac8f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def3.C
@@ -0,0 +1,5 @@
+// { dg-options "-std=c++11" }
+
+namespace A::B::C
+{
+}
diff --git a/gcc/testsuite

Re: [PATCH, RFC] Implement N4230, Nested namespace definition

2015-09-18 Thread Ville Voutilainen
On 18 September 2015 at 19:27, Jason Merrill  wrote:
> On 09/17/2015 06:23 PM, Ville Voutilainen wrote:
>>
>> This patch doesn't handle attributes yet, it looks to
>> me as if gcc doesn't support namespace attributes in the location that
>> the standard grammar puts them into.
> Mind fixing that, too?

Can we please do that separately?

>
>> + "-std=c++17 or -std=gnu++17");
> Please use "1z" until C++17 is final.


Will do.


Re: [PATCH, RFC] Implement N4230, Nested namespace definition

2015-09-18 Thread Ville Voutilainen
On 18 September 2015 at 19:34, Jason Merrill  wrote:
 This patch doesn't handle attributes yet, it looks to
 me as if gcc doesn't support namespace attributes in the location that
 the standard grammar puts them into.
>>> Mind fixing that, too?
>> Can we please do that separately?
> I suppose so, but it seems pretty trivial.  In any case, looks like your
> patch would accept the odd
> namespace A __attribute ((visibility ("default"))) ::B { }


Yes, or namespace A[[nonsense]]::B {}. Those cases are easy to fix,
but namespace [[attribute_in_proper_location]] A {} seemingly caused
weird barfing. That's why I didn't put in the rejection of the former,
I'd prefer
to figure out the latter and the former at the same time, and I'd prefer doing
that once the basic facility is in. Yes, partly because I'll travel tomorrow. :)


Re: [PATCH, RFC] Implement N4230, Nested namespace definition

2015-09-18 Thread Ville Voutilainen
On 18 September 2015 at 20:26, Jason Merrill  wrote:
>>> I suppose so, but it seems pretty trivial.  In any case, looks like your
>>> patch would accept the odd
>>> namespace A __attribute ((visibility ("default"))) ::B { }
>> Yes, or namespace A[[nonsense]]::B {}. Those cases are easy to fix,
>> but namespace [[attribute_in_proper_location]] A {} seemingly caused
>> weird barfing. That's why I didn't put in the rejection of the former, I'd
>> prefer
>> to figure out the latter and the former at the same time, and I'd prefer
>> doing
>> that once the basic facility is in. Yes, partly because I'll travel
>> tomorrow. :)
> To fix the former, you just need to keep
>>/* Parse any specified attributes.  */
>>attribs = cp_parser_attributes_opt (parser);
> next to the open brace.  OK with that change, I suppose the other can wait.


I also need to diagnose the use of attributes with a nested namespace
definition,
so I need to add the error emission and test it. ;)


Re: [PATCH, RFC] Implement N4230, Nested namespace definition

2015-09-18 Thread Ville Voutilainen
On 18 September 2015 at 20:30, Ville Voutilainen
 wrote:
> On 18 September 2015 at 20:26, Jason Merrill  wrote:
>>>> I suppose so, but it seems pretty trivial.  In any case, looks like your
>>>> patch would accept the odd
>>>> namespace A __attribute ((visibility ("default"))) ::B { }
>>> Yes, or namespace A[[nonsense]]::B {}. Those cases are easy to fix,
>>> but namespace [[attribute_in_proper_location]] A {} seemingly caused
>>> weird barfing. That's why I didn't put in the rejection of the former, I'd
>>> prefer
>>> to figure out the latter and the former at the same time, and I'd prefer
>>> doing
>>> that once the basic facility is in. Yes, partly because I'll travel
>>> tomorrow. :)
>> To fix the former, you just need to keep
>>>/* Parse any specified attributes.  */
>>>attribs = cp_parser_attributes_opt (parser);
>> next to the open brace.  OK with that change, I suppose the other can wait.
>
>
> I also need to diagnose the use of attributes with a nested namespace
> definition,
> so I need to add the error emission and test it. ;)

Hmm, I already do that, the nested namespace definition parsing
effectively requires
an identifier. Ok, I'll give it a spin, I'll send an updated patch for
review. :)


Re: [PATCH, RFC] Implement N4230, Nested namespace definition

2015-09-18 Thread Ville Voutilainen
On 18 September 2015 at 20:38, Ville Voutilainen
 wrote:
> On 18 September 2015 at 20:30, Ville Voutilainen
>  wrote:
>> On 18 September 2015 at 20:26, Jason Merrill  wrote:
>>>>> I suppose so, but it seems pretty trivial.  In any case, looks like your
>>>>> patch would accept the odd
>>>>> namespace A __attribute ((visibility ("default"))) ::B { }
>>>> Yes, or namespace A[[nonsense]]::B {}. Those cases are easy to fix,
>>>> but namespace [[attribute_in_proper_location]] A {} seemingly caused
>>>> weird barfing. That's why I didn't put in the rejection of the former, I'd
>>>> prefer
>>>> to figure out the latter and the former at the same time, and I'd prefer
>>>> doing
>>>> that once the basic facility is in. Yes, partly because I'll travel
>>>> tomorrow. :)
>>> To fix the former, you just need to keep
>>>>/* Parse any specified attributes.  */
>>>>attribs = cp_parser_attributes_opt (parser);
>>> next to the open brace.  OK with that change, I suppose the other can wait.
>>
>>
>> I also need to diagnose the use of attributes with a nested namespace
>> definition,
>> so I need to add the error emission and test it. ;)
>
> Hmm, I already do that, the nested namespace definition parsing
> effectively requires
> an identifier. Ok, I'll give it a spin, I'll send an updated patch for
> review. :)

Argh, no. An attribute immediately following a nesting namespace would need
to be parsed before the nested namespace definition handling is done, otherwise
the nested namespace definition handling is never entered because the next token
is not CPP_SCOPE. So the attributes should be parsed and rejected where they are
parsed now if they are followed by a CPP_SCOPE. That's easy, I'll just check
for non-null attribs and diagnose.


Re: [PATCH, RFC] Implement N4230, Nested namespace definition

2015-09-18 Thread Ville Voutilainen
On 18 September 2015 at 20:46, Ville Voutilainen
 wrote:
> Argh, no. An attribute immediately following a nesting namespace would need
> to be parsed before the nested namespace definition handling is done, 
> otherwise
> the nested namespace definition handling is never entered because the next 
> token
> is not CPP_SCOPE. So the attributes should be parsed and rejected where they 
> are
> parsed now if they are followed by a CPP_SCOPE. That's easy, I'll just check
> for non-null attribs and diagnose.

New patch attached. I added tests for the partial attribute support in
it. Ok for trunk?
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4f424b6..e9353b0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16953,6 +16953,8 @@ cp_parser_namespace_definition (cp_parser* parser)
   tree identifier, attribs;
   bool has_visibility;
   bool is_inline;
+  cp_token* token;
+  int nested_definition_count = 0;
 
   cp_ensure_no_omp_declare_simd (parser);
   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE))
@@ -16965,7 +16967,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 is_inline = false;
 
   /* Look for the `namespace' keyword.  */
-  cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
+  token = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
 
   /* Get the name of the namespace.  We do not attempt to distinguish
  between an original-namespace-definition and an
@@ -16979,11 +16981,38 @@ cp_parser_namespace_definition (cp_parser* parser)
   /* Parse any specified attributes.  */
   attribs = cp_parser_attributes_opt (parser);
 
-  /* Look for the `{' to start the namespace.  */
-  cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
   /* Start the namespace.  */
   push_namespace (identifier);
 
+  /* Parse any nested namespace definition. */
+  if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+{
+  if (attribs)
+error_at (token->location, "a nested namespace definition cannot have 
attributes");
+  if (cxx_dialect < cxx1z)
+pedwarn (input_location, OPT_Wpedantic,
+ "nested namespace definitions only available with "
+ "-std=c++1z or -std=gnu++1z");
+  if (is_inline)
+error_at (token->location, "a nested namespace definition cannot be 
inline");
+  while (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+{
+  cp_lexer_consume_token (parser->lexer);
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+identifier = cp_parser_identifier (parser);
+  else
+{
+  cp_parser_error (parser, "nested identifier required");
+  break;
+}
+  ++nested_definition_count;
+  push_namespace (identifier);
+}
+}
+
+  /* Look for the `{' to validate starting the namespace.  */
+  cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
+
   /* "inline namespace" is equivalent to a stub namespace definition
  followed by a strong using directive.  */
   if (is_inline)
@@ -17007,6 +17036,10 @@ cp_parser_namespace_definition (cp_parser* parser)
   if (has_visibility)
 pop_visibility (1);
 
+  /* Finish the nested namespace definitions.  */
+  while (nested_definition_count--)
+pop_namespace ();
+
   /* Finish the namespace.  */
   pop_namespace ();
   /* Look for the final `}'.  */
diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C 
b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C
new file mode 100644
index 000..ebdb70b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C
@@ -0,0 +1,19 @@
+// { dg-options "-std=c++1z" }
+
+namespace A::B::C
+{
+   struct X {};
+   namespace T::U::V { struct Y {}; }
+}
+
+A::B::C::X x;
+A::B::C::T::U::V::Y y;
+
+inline namespace D::E {} // { dg-error "cannot be inline" }
+
+namespace F::G:: {} // { dg-error "nested identifier required" }
+
+namespace G __attribute ((visibility ("default"))) ::H {} // { dg-error 
"cannot have attributes" }
+
+namespace H [[deprecated]] ::I {} // { dg-error "cannot have 
attributes|ignored" }
+
diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def2.C 
b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def2.C
new file mode 100644
index 000..c47a94a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def2.C
@@ -0,0 +1,5 @@
+// { dg-options "-std=c++11 -pedantic-errors" }
+
+namespace A::B::C // { dg-error "nested namespace definitions only available 
with" }
+{
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def3.C 
b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def3.C
new file mode 100644
index 000..f2dac8f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def3.C
@@ -0

[C++ PATCH] Complete the implementation of N4230, Nested namespace definition.

2015-09-20 Thread Ville Voutilainen
Tested on Linux-PPC64.

/c-family
2015-09-20  Ville Voutilainen  

Complete the implementation of N4230, Nested namespace definition.
* c-cppbuiltin.c: Add __cpp_namespace_attributes and
__cpp_nested_namespace_definitions.

/cp
2015-09-20  Ville Voutilainen  

Complete the implementation of N4230, Nested namespace definition.
* parser.c (cp_parser_namespace_definition): Support namespace
attributes both before and after the namespace identifier.

/testsuite
2015-09-20  Ville Voutilainen  

Complete the implementation of N4230, Nested namespace definition.
* g++.dg/cpp1y/feat-cxx11-neg.C: Add tests for C++17 namespace
attributes and nested namespace definitions.
* g++.dg/cpp1y/feat-cxx98-neg.C: Likewise.
* g++.dg/cpp1z/feat-cxx1z.C: Likewise.
* g++.dg/cpp1y/feat-cxx14-neg.C: New.
* g++.dg/cpp1z/namespace-attribs.C: Likewise.
* g++.dg/cpp1z/nested-namespace-def1.C: Add tests for attributes
appearing before the namespace identifier.
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 0e45a57..b222a9f 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -870,6 +870,8 @@ c_cpp_builtins (cpp_reader *pfile)
{
  /* Set feature test macros for C++1z.  */
  cpp_define (pfile, "__cpp_static_assert=201411");
+ cpp_define (pfile, "__cpp_namespace_attributes=201411");
+ cpp_define (pfile, "__cpp_nested_namespace_definitions=201411");
}
   if (flag_concepts)
/* Use a value smaller than the 201507 specified in
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 2071276..ffea989 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -11645,6 +11645,9 @@ cp_parser_declaration (cp_parser* parser)
   (token2.type == CPP_NAME
&& (cp_lexer_peek_nth_token (parser->lexer, 3)->type
!= CPP_EQ))
+   || (token2.type == CPP_OPEN_SQUARE
+   && cp_lexer_peek_nth_token (parser->lexer, 2)->type
+   == CPP_OPEN_SQUARE)
   /* An unnamed namespace definition.  */
   || token2.type == CPP_OPEN_BRACE
   || token2.keyword == RID_ATTRIBUTE))
@@ -16969,6 +16972,9 @@ cp_parser_namespace_definition (cp_parser* parser)
   /* Look for the `namespace' keyword.  */
   token = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
 
+  /* Parse any specified attributes before the identifier.  */
+  attribs = cp_parser_attributes_opt (parser);
+
   /* Get the name of the namespace.  We do not attempt to distinguish
  between an original-namespace-definition and an
  extension-namespace-definition at this point.  The semantic
@@ -16978,8 +16984,15 @@ cp_parser_namespace_definition (cp_parser* parser)
   else
 identifier = NULL_TREE;
 
-  /* Parse any specified attributes.  */
-  attribs = cp_parser_attributes_opt (parser);
+  /* Parse any specified attributes after the identifier.  */
+  tree post_ident_attribs = cp_parser_attributes_opt (parser);
+  if (post_ident_attribs)
+{
+  if (attribs)
+attribs = chainon (attribs, post_ident_attribs);
+  else
+attribs = post_ident_attribs;
+}
 
   /* Start the namespace.  */
   push_namespace (identifier);
diff --git a/gcc/testsuite/g++.dg/cpp1y/feat-cxx11-neg.C 
b/gcc/testsuite/g++.dg/cpp1y/feat-cxx11-neg.C
index 81daa04..825d088 100644
--- a/gcc/testsuite/g++.dg/cpp1y/feat-cxx11-neg.C
+++ b/gcc/testsuite/g++.dg/cpp1y/feat-cxx11-neg.C
@@ -38,6 +38,17 @@
 #  error "__cpp_sized_deallocation" // { dg-error "error" }
 #endif
 
+// C++17 features:
+
+#ifndef __cpp_namespace_attributes
+#  error "__cpp_namespace_attributes" // { dg-error "error" }
+#endif
+
+#ifndef __cpp_nested_namespace_definitions
+#  error "__cpp_nested_namespace_definitions" // { dg-error "error" }
+#endif
+
+
 //  Array TS features:
 
 #ifndef __cpp_runtime_arrays
diff --git a/gcc/testsuite/g++.dg/cpp1y/feat-cxx14-neg.C 
b/gcc/testsuite/g++.dg/cpp1y/feat-cxx14-neg.C
new file mode 100644
index 000..221bd3f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/feat-cxx14-neg.C
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++14 } }
+
+// C++17 features:
+
+#ifndef __cpp_namespace_attributes
+#  error "__cpp_namespace_attributes" // { dg-error "error" }
+#endif
+
+#ifndef __cpp_nested_namespace_definitions
+#  error "__cpp_nested_namespace_definitions" // { dg-error "error" }
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C 
b/gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C
index 9c25fc3..886b3d3 100644
--- a/gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C
+++ b/gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C
@@ -113,6 +113,16 @@
 #  error "__cpp_sized_deallocation" // { dg-error "error" }
 #endif
 
+

Re: [C++ PATCH] Complete the implementation of N4230, Nested namespace definition.

2015-09-20 Thread Ville Voutilainen
On 21 September 2015 at 00:08, Ville Voutilainen
 wrote:
> /cp
> 2015-09-20  Ville Voutilainen  
>
> Complete the implementation of N4230, Nested namespace definition.
> * parser.c (cp_parser_namespace_definition): Support namespace
> attributes both before and after the namespace identifier.


Boo hiss, this change wasn't looking at the open-square that's
supposed to follow the first
open-square, I'm finishing testing the attached patch, which looks
at
cp_lexer_peek_nth_token (parser->lexer, 3)->type
instead of
cp_lexer_peek_nth_token (parser->lexer, 2)->type
which is already token2's type.
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index b45b53e..c396735 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2015-09-20  Ville Voutilainen  
+
+   Complete the implementation of N4230, Nested namespace definition.
+   * c-cppbuiltin.c: Add __cpp_namespace_attributes and
+   __cpp_nested_namespace_definitions.
+
 2015-09-18  Manuel López-Ibáñez  
 
* c-pragma.c (handle_pragma_diagnostic): Fix wrong return.
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 0e45a57..b222a9f 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -870,6 +870,8 @@ c_cpp_builtins (cpp_reader *pfile)
{
  /* Set feature test macros for C++1z.  */
  cpp_define (pfile, "__cpp_static_assert=201411");
+ cpp_define (pfile, "__cpp_namespace_attributes=201411");
+ cpp_define (pfile, "__cpp_nested_namespace_definitions=201411");
}
   if (flag_concepts)
/* Use a value smaller than the 201507 specified in
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ab71f92..ed782a6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2015-09-20  Ville Voutilainen  
+
+   Complete the implementation of N4230, Nested namespace definition.
+   * parser.c (cp_parser_namespace_definition): Support namespace
+   attributes both before and after the namespace identifier.
+
 2015-09-19  Trevor Saunders  
 
* cp-gimplify.c (gimplify_must_not_throw_expr): Adjust.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 2071276..0134189 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -11645,6 +11645,9 @@ cp_parser_declaration (cp_parser* parser)
   (token2.type == CPP_NAME
&& (cp_lexer_peek_nth_token (parser->lexer, 3)->type
!= CPP_EQ))
+   || (token2.type == CPP_OPEN_SQUARE
+   && cp_lexer_peek_nth_token (parser->lexer, 3)->type
+   == CPP_OPEN_SQUARE)
   /* An unnamed namespace definition.  */
   || token2.type == CPP_OPEN_BRACE
   || token2.keyword == RID_ATTRIBUTE))
@@ -16969,6 +16972,9 @@ cp_parser_namespace_definition (cp_parser* parser)
   /* Look for the `namespace' keyword.  */
   token = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
 
+  /* Parse any specified attributes before the identifier.  */
+  attribs = cp_parser_attributes_opt (parser);
+
   /* Get the name of the namespace.  We do not attempt to distinguish
  between an original-namespace-definition and an
  extension-namespace-definition at this point.  The semantic
@@ -16978,8 +16984,15 @@ cp_parser_namespace_definition (cp_parser* parser)
   else
 identifier = NULL_TREE;
 
-  /* Parse any specified attributes.  */
-  attribs = cp_parser_attributes_opt (parser);
+  /* Parse any specified attributes after the identifier.  */
+  tree post_ident_attribs = cp_parser_attributes_opt (parser);
+  if (post_ident_attribs)
+{
+  if (attribs)
+attribs = chainon (attribs, post_ident_attribs);
+  else
+attribs = post_ident_attribs;
+}
 
   /* Start the namespace.  */
   push_namespace (identifier);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5fd91c1..10747a9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,15 @@
+2015-09-20  Ville Voutilainen  
+
+   Complete the implementation of N4230, Nested namespace definition.
+   * g++.dg/cpp1y/feat-cxx11-neg.C: Add tests for C++17 namespace
+   attributes and nested namespace definitions.
+   * g++.dg/cpp1y/feat-cxx98-neg.C: Likewise.
+   * g++.dg/cpp1z/feat-cxx1z.C: Likewise.
+   * g++.dg/cpp1y/feat-cxx14-neg.C: New.
+   * g++.dg/cpp1z/namespace-attribs.C: Likewise.
+   * g++.dg/cpp1z/nested-namespace-def1.C: Add tests for attributes
+   appearing before the namespace identifier.
+
 2015-09-20  Oleg Endo  
 
* gcc.target/sh/pr43417.c: Move target independent test to ...
diff --git a/gcc/testsuite/g++.dg/cpp1y/feat-cxx11-neg.C 
b/gcc/testsuite/g++.dg/cpp1y/feat-cxx11-neg.C
index 81daa04..825d088 100644
--- a/gcc/testsuite/g++.dg/cpp1y/feat-cxx

[C++ PATCH] Fix small typos in the coding rule enforcement warnings.

2015-09-23 Thread Ville Voutilainen
Tested on Linux-PPC64, committed as obvious.

/cp
2015-09-23  Ville Voutilainen  

Fix small typos in the coding rule enforcement warnings.
* parser.c (cp_parser_namespace_definition): Replace 'namepace'
with 'namespace'.

/testsuite
2015-09-23  Ville Voutilainen  

Fix small typos in the coding rule enforcement warnings.
* g++.dg/diagnostic/disable.C: Replace 'namepace'
with 'namespace'.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index cc920926e..1148156 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -17043,7 +17043,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 
   has_visibility = handle_namespace_attrs (current_namespace, attribs);
 
-  warning  (OPT_Wnamespaces, "namepace %qD entered", current_namespace);
+  warning  (OPT_Wnamespaces, "namespace %qD entered", current_namespace);
 
   /* Parse the body of the namespace.  */
   cp_parser_namespace_body (parser);
diff --git a/gcc/testsuite/g++.dg/diagnostic/disable.C 
b/gcc/testsuite/g++.dg/diagnostic/disable.C
index a69033d..7d86e07 100644
--- a/gcc/testsuite/g++.dg/diagnostic/disable.C
+++ b/gcc/testsuite/g++.dg/diagnostic/disable.C
@@ -3,7 +3,7 @@
 #include 
 #include 
 
-namespace foo { } // { dg-warning "namepace" }
+namespace foo { } // { dg-warning "namespace" }
 
 template  X Foo (); // { dg-warning "template" }
 


[v3 PATCH] Avoid creating dangling references in case of nested tuples for tuple constructors that construct from other tuples.

2015-09-25 Thread Ville Voutilainen
Tested on Linux-PPC64.

2015-09-25  Ville Voutilainen  

Avoid creating dangling references in case of nested tuples
for tuple constructors that construct from other tuples.
* include/std/tuple (_TC::_NonNestedTuple): New.
* include/std/tuple (tuple::_TNTC): New.
* include/std/tuple (tuple(const tuple<_UElements...>&),
tuple(tuple<_UElements...>&&): Use _TNTC.
* testsuite/20_util/tuple/cons/nested_tuple_construct.cc: New.
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 59b992a..751d7eb 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -486,6 +486,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   return __and_...>::value;
 }
+
+template
+static constexpr bool _NonNestedTuple()
+{
+  return  __and_<__not_>,
+ __not_>
+  >::value;
+}
   };
 
   template
@@ -514,6 +522,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   return false;
 }
+
+template
+static constexpr bool _NonNestedTuple()
+{
+  return true;
+}
   };
 
   /// Primary class template, tuple
@@ -599,40 +613,54 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   constexpr tuple(tuple&&) = default; 
 
-  template using _TNTC =
+_TC::value && sizeof...(_Elements) == 1,
+_Elements...>;
+
+  template::template
 _ConstructibleTuple<_UElements...>()
   && _TMC<_UElements...>::template
-_ImplicitlyConvertibleTuple<_UElements...>(),
+_ImplicitlyConvertibleTuple<_UElements...>()
+  && _TNTC<_Dummy>::template
+_NonNestedTuple&>(),
 bool>::type=true>
 constexpr tuple(const tuple<_UElements...>& __in)
 : _Inherited(static_cast&>(__in))
 { }
 
-  template::template
 _ConstructibleTuple<_UElements...>()
   && !_TMC<_UElements...>::template
-_ImplicitlyConvertibleTuple<_UElements...>(),
+_ImplicitlyConvertibleTuple<_UElements...>()
+  && _TNTC<_Dummy>::template
+_NonNestedTuple&>(),
 bool>::type=false>
 explicit constexpr tuple(const tuple<_UElements...>& __in)
 : _Inherited(static_cast&>(__in))
 { }
 
-  template::template
 _MoveConstructibleTuple<_UElements...>()
   && _TMC<_UElements...>::template
-_ImplicitlyMoveConvertibleTuple<_UElements...>(),
+_ImplicitlyMoveConvertibleTuple<_UElements...>()
+  && _TNTC<_Dummy>::template
+_NonNestedTuple&&>(),
 bool>::type=true>
 constexpr tuple(tuple<_UElements...>&& __in)
 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
 
-  template::template
 _MoveConstructibleTuple<_UElements...>()
   && !_TMC<_UElements...>::template
-_ImplicitlyMoveConvertibleTuple<_UElements...>(),
+_ImplicitlyMoveConvertibleTuple<_UElements...>()
+  && _TNTC<_Dummy>::template
+_NonNestedTuple&&>(),
 bool>::type=false>
 explicit constexpr tuple(tuple<_UElements...>&& __in)
 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
diff --git 
a/libstdc++-v3/testsuite/20_util/tuple/cons/nested_tuple_construct.cc 
b/libstdc++-v3/testsuite/20_util/tuple/cons/nested_tuple_construct.cc
new file mode 100644
index 000..32ef3cc
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/nested_tuple_construct.cc
@@ -0,0 +1,60 @@
+#include 
+#include 
+#include 
+
+static std::string result;
+
+struct X {
+  int state; // this has to be here
+  X() {
+result += "Def";
+  }
+
+  X(X const&) {
+result += "Copy";
+  }
+
+  X(X&&) {
+result += "Move";
+  }
+
+  ~X() {
+result += "Dtor";
+  }
+};
+
+void f()
+{
+  X v;
+  std::tuple t1{v};
+  std::tuple&&> t2{std::move(t1)};
+  std::tuple> t3{std::move(t2)};
+}
+
+void f2()
+{
+  X v;
+  std::tuple t1{std::move(v)};
+  std::tuple&&> t2{std::move(t1)};
+  std::tuple> t3{std::move(t2)};
+}
+
+void f3()
+{
+  std::tuple t1{X{}};
+  std::tuple&&> t2{std::move(t1)};
+  std::tuple> t3{std::move(t2)};
+}
+
+int main()
+{
+  f();
+  VERIFY(result == "DefCopyMoveDtorDtorDtor");
+  result = "";
+  f2();
+  VERIFY(result == "DefMoveMoveDtorDtorDtor");
+  result = "";
+  f3();
+  VERIFY(result == "DefMoveDtorMoveDtorDtor");
+  result = "";
+}


[C++ PATCH] PR c++/54430

2015-10-01 Thread Ville Voutilainen
Tested on Linux-PPC64.

/cp
2015-10-01  Ville Voutilainen  

PR c++/54430
* name-lookup.c (push_binding): Make non-static.
* name-lookup.h (push_binding): Declare it.
* parser.c (cp_parser_range_for): Use it, get the range
declaration away from the scope until the range expression
has been parsed, then restore the declaration.

/testsuite
2015-10-01  Ville Voutilainen  

PR c++/54430
* g++.dg/cpp0x/range-for30.C: New.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index baaf3e7..bd052a4 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -332,7 +332,7 @@ new_class_binding (tree name, tree value, tree type, 
cp_binding_level *scope)
 /* Make DECL the innermost binding for ID.  The LEVEL is the binding
level at which this declaration is being bound.  */
 
-static void
+void
 push_binding (tree id, tree decl, cp_binding_level* level)
 {
   cxx_binding *binding;
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 4b94192..82b5e53 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -88,6 +88,7 @@ struct GTY(()) cxx_saved_binding {
 
 extern tree identifier_type_value (tree);
 extern void set_identifier_type_value (tree, tree);
+extern void push_binding (tree, tree, cp_binding_level*);
 extern void pop_binding (tree, tree);
 extern void pop_bindings_and_leave_scope (void);
 extern tree constructor_name (tree);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 1148156..8aeca40 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10725,6 +10725,11 @@ cp_parser_range_for (cp_parser *parser, tree scope, 
tree init, tree range_decl,
 {
   tree stmt, range_expr;
 
+  /* Get the range declaration momentarily out of the way so that
+ the range expression doesn't clash with it. */
+  if (range_decl != error_mark_node)
+pop_binding (DECL_NAME (range_decl), range_decl);
+
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
 {
   bool expr_non_constant_p;
@@ -10733,6 +10738,10 @@ cp_parser_range_for (cp_parser *parser, tree scope, 
tree init, tree range_decl,
   else
 range_expr = cp_parser_expression (parser);
 
+  /* Put the range declaration back into scope. */
+  if (range_decl != error_mark_node)
+push_binding (DECL_NAME (range_decl), range_decl, current_binding_level);
+
   /* If in template, STMT is converted to a normal for-statement
  at instantiation. If not, it is done just ahead. */
   if (processing_template_decl)
diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for30.C 
b/gcc/testsuite/g++.dg/cpp0x/range-for30.C
new file mode 100644
index 000..d559d0f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/range-for30.C
@@ -0,0 +1,17 @@
+// PR c++/54430
+// { dg-require-effective-target c++11 }
+
+struct A
+{
+  A(int) {}
+  int* begin() {return nullptr;}
+  int* end() {return nullptr;}
+};
+
+int main()
+{
+  int i[] = { 1, 2, 3, 4 };
+  for (int i : i);
+  for (auto i : i);
+  for (A v : v); // { dg-error "not declared in this scope" }
+}


[v3 PATCH] PR 67844

2015-10-04 Thread Ville Voutilainen
Tested on Linux-PPC64. The problem is a tad tricky, since
the bug triggered by the testcase is in a constructor that
will not be used, but will cause endless meta-recursion
via checking convertibility of an incomplete type that will
cause further recursion. While there might be ways to fix
that in the traits themselves, this is a straightforward fix,
for certain tuple-specific values of "straightforward". ;)

And hey, the problem and its solution were, once the bug
report came in, obvious to the resident tuple-hacker between
my chair and my keyboard. :)

2015-10-05  Ville Voutilainen  

PR 67844.
* include/std/tuple (_TC::_NonNestedTuple): Eagerly reject
conversions from tuple types same as the target tuple.
* testsuite/20_util/tuple/67844.cc: New.
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 751d7eb..8af01f4 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -457,6 +457,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 };
 
+  template
+class tuple;
 
   // Concept utility functions, reused in conditionally-explicit
   // constructors.
@@ -490,7 +492,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 template
 static constexpr bool _NonNestedTuple()
 {
-  return  __and_<__not_>,
+  return  __and_<__not_,
+   typename remove_cv<
+ typename remove_reference<_SrcTuple>::type
+   >::type>>,
+ __not_>,
  __not_>
   >::value;
 }
diff --git a/libstdc++-v3/testsuite/20_util/tuple/67844.cc 
b/libstdc++-v3/testsuite/20_util/tuple/67844.cc
new file mode 100644
index 000..5635462
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/67844.cc
@@ -0,0 +1,24 @@
+// { dg-do compile }
+
+#include 
+
+struct A
+{
+  template 
+  A(T)
+  {
+  }
+
+  A(const A&) = default;
+  A(A&&) = default;
+  A& operator=(const A&) = default;
+  A& operator=(A&&) = default;
+  ~A() = default;
+};
+
+int main()
+{
+  auto x = A{7};
+  std::make_tuple(x);
+}
+


[C++ PATCH] PR c++/58566

2015-10-11 Thread Ville Voutilainen
Tested on Linux-PPC64.

/cp
2015-10-11  Ville Voutilainen  

PR c++/58566
* lambda.c (lambda_return_type): Return error_mark_node
instead of void_type_node for the error cases.

/testsuite
2015-10-11  Ville Voutilainen  

PR c++/58566
* g++.dg/cpp0x/lambda/lambda-58566.C: New.


Re: [C++ PATCH] PR c++/58566

2015-10-11 Thread Ville Voutilainen
On 11 October 2015 at 20:05, Ville Voutilainen
 wrote:
> Tested on Linux-PPC64.
>
> /cp
> 2015-10-11  Ville Voutilainen  
>
> PR c++/58566
> * lambda.c (lambda_return_type): Return error_mark_node
> instead of void_type_node for the error cases.
>
> /testsuite
> 2015-10-11  Ville Voutilainen  
>
> PR c++/58566
> * g++.dg/cpp0x/lambda/lambda-58566.C: New.

..and now with the actual patch attached. :)
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index ceab646..b4f19af 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -175,7 +175,7 @@ lambda_return_type (tree expr)
   || BRACE_ENCLOSED_INITIALIZER_P (expr))
 {
   cxx_incomplete_type_error (expr, TREE_TYPE (expr));
-  return void_type_node;
+  return error_mark_node;
 }
   gcc_checking_assert (!type_dependent_expression_p (expr));
   return cv_unqualified (type_decays_to (unlowered_expr_type (expr)));
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-58566.C 
b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-58566.C
new file mode 100644
index 000..3101d0a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-58566.C
@@ -0,0 +1,10 @@
+// PR c++/58566
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  int foo()
+  {
+[this]{ return foo; }; // { dg-error "invalid use of member 
function|cannot convert" }
+  }
+};


C++ PATCH for DR 1518 (c++/54835, c++/60417)

2015-10-25 Thread Ville Voutilainen
It seems to me that there's a discrepancy in handling explicit
default constructors. Based on my tests, this works:

struct X {explicit X() {}};

void f(X) {}

int main()
{
f({});
}

However, if the explicit constructor is defaulted, gcc accepts the code:

struct X {explicit X() = default;};

void f(X) {}

int main()
{
f({});
}


Re: C++ PATCH for DR 1518 (c++/54835, c++/60417)

2015-10-25 Thread Ville Voutilainen
On 25 October 2015 at 22:15, Ville Voutilainen
 wrote:
> It seems to me that there's a discrepancy in handling explicit
> default constructors. Based on my tests, this works:
>
> struct X {explicit X() {}};
>
> void f(X) {}
>
> int main()
> {
> f({});
> }
>
> However, if the explicit constructor is defaulted, gcc accepts the code:
>
> struct X {explicit X() = default;};
>
> void f(X) {}
>
> int main()
> {
> f({});
> }

And to clarify, I'd expect both of those snippets to be rejected, but only the
former is.


[C++ PATCH] Remove the implementation of N3994, terse range-for loops.

2015-10-31 Thread Ville Voutilainen
Since N3994 ended up being rejected and was never included
in C++17, I want to remove the support for it. It's easy to bring
it back if such a facility is resurrected, but for now, let's remove
such an extension.

Tested on Linux-PPC64.

/cp
2015-10-31  Ville Voutilainen  

Remove the implementation of N3994, terse range-for loops.
* parser.c (cp_parser_for_init_statement): Remove the parsing
of a terse range-for.

/testsuite
2015-10-31  Ville Voutilainen  

Remove the implementation of N3994, terse range-for loops.
* g++.dg/cpp1z/range-for1.C: Remove.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c8f8b3d..8ca82d3 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -11279,22 +11279,6 @@ cp_parser_for_init_statement (cp_parser* parser, tree 
*decl)
   bool is_range_for = false;
   bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
 
-  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
- && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
-   {
- /* N3994 -- for (id : init) ... */
- if (cxx_dialect < cxx1z)
-   pedwarn (input_location, 0, "range-based for loop without a "
-"type-specifier only available with "
-"-std=c++1z or -std=gnu++1z");
- tree name = cp_parser_identifier (parser);
- tree type = cp_build_reference_type (make_auto (), /*rval*/true);
- *decl = build_decl (input_location, VAR_DECL, name, type);
- pushdecl (*decl);
- cp_lexer_consume_token (parser->lexer);
- return true;
-   }
-
   /* A colon is used in range-based for.  */
   parser->colon_corrects_to_scope_p = false;
 
diff --git a/gcc/testsuite/g++.dg/cpp1z/range-for1.C 
b/gcc/testsuite/g++.dg/cpp1z/range-for1.C
deleted file mode 100644
index 7e6d055..000
--- a/gcc/testsuite/g++.dg/cpp1z/range-for1.C
+++ /dev/null
@@ -1,12 +0,0 @@
-// { dg-options "-std=c++1z -pedantic-errors" }
-
-extern "C" int printf (const char *, ...);
-#include 
-
-int main()
-{
-  for (i : {1,2})
-{
-  printf ("%d ", i);
-}
-}


[v3 PATCH] Make the default constructors of tuple and pair conditionally explicit.

2015-10-31 Thread Ville Voutilainen
In the last meeting, while processing LWG 2510, LWG's guidance
was to make the default constructors of pair and tuple conditionally
explicit. This patch implements a new trait and uses it in pair and tuple.

Paolo, Jonathan is traveling and somewhat unlikely to be able to review
this for quite some time, could you please review this patch?

Tested on Linux-PPC64.

2015-11-01  Ville Voutilainen  

Make the default constructors of tuple and pair conditionally explicit.
* include/std/type_traits (
__do_is_implicitly_default_constructible_impl
__is_implicitly_default_constructible_impl,
__is_implicitly_default_constructible_safe,
__is_implicitly_default_constructible): New.
* include/bits/stl_pair.h (pair::pair()): Use it.
* include/std/tuple (tuple<_T1, _T2>::tuple): Use it.
* include/std/tuple (ImplicitlyDefaultConstructibleTuple): New.
* include/std/tuple (tuple<_Types...>::tuple()): Use it.
* testsuite/20_util/declval/requirements/1_neg.cc: Adjust.
* 
testsuite/20_util/is_implicitly_default_constructible/requirements/explicit_instantiation.cc:
New.
* 
testsuite/20_util/is_implicitly_default_constructible/requirements/typedefs.cc:
Likewise.
* testsuite/20_util/is_implicitly_default_constructible/value.cc: Likewise.
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Adjust.
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Likewise.
* testsuite/20_util/pair/cons/explicit_construct.cc: Likewise.
* testsuite/20_util/tuple/cons/explicit_construct.cc: Likewise.
diff --git a/libstdc++-v3/include/bits/stl_pair.h 
b/libstdc++-v3/include/bits/stl_pair.h
index a5a7898..dfcd357 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -141,13 +141,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template ,
- is_default_constructible<_U2>>
+ 
__is_implicitly_default_constructible<_U1>,
+ 
__is_implicitly_default_constructible<_U2>>
::value, bool>::type = true>
 #endif
   _GLIBCXX_CONSTEXPR pair()
   : first(), second() { }
 
+#if __cplusplus >= 201103L
+  template ,
+   is_default_constructible<_U2>,
+   __not_<
+ __and_<__is_implicitly_default_constructible<_U1>,
+__is_implicitly_default_constructible<_U2>>>>
+   ::value, bool>::type = false>
+  explicit constexpr pair()
+  : first(), second() { }
+#endif
+
   /** Two objects may be passed to a @c pair constructor to be copied.  */
 #if __cplusplus < 201103L
   pair(const _T1& __a, const _T2& __b)
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 8af01f4..e6c32b3 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -551,16 +551,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   return __and_...>::value;
 }
+static constexpr bool _ImplicitlyDefaultConstructibleTuple()
+{
+  return __and_<__is_implicitly_default_constructible<_Elements>...>
+::value;
+}
   };
 
 public:
   template::
-_DefaultConstructibleTuple(),
+_ImplicitlyDefaultConstructibleTuple(),
   bool>::type = true>
   constexpr tuple()
   : _Inherited() { }
 
+  template::
+_DefaultConstructibleTuple()
+  &&
+  !_TC2<_Dummy>::
+_ImplicitlyDefaultConstructibleTuple(),
+  bool>::type = false>
+  explicit constexpr tuple()
+  : _Inherited() { }
+
   // Shortcut for the cases where constructors taking _Elements...
   // need to be constrained.
   template using _TCC =
@@ -837,13 +852,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template ,
- is_default_constructible<_U2>>
+ 
__is_implicitly_default_constructible<_U1>,
+ 
__is_implicitly_default_constructible<_U2>>
::value, bool>::type = true>
 
   constexpr tuple()
   : _Inherited() { }
 
+  template ,
+is_default_constructible<_U2>,
+__not_<
+  __and_<__is_implicitly_default_constructible<_U1>,
+ __is_implicitly_default_constructible<_U2>>>>
+

Re: [v3 PATCH] Make the default constructors of tuple and pair conditionally explicit.

2015-11-02 Thread Ville Voutilainen
On 2 November 2015 at 17:19, Paolo Carlini  wrote:
> Anyway, so far the only detail which makes me a little nervous is the
> following:
>
> +  template 
> +struct __is_implicitly_default_constructible
> +  : public integral_constant +(is_default_constructible<_Tp>::value
> +&&
> __is_implicitly_default_constructible_safe<_Tp>::value)>
>
>
> I think we want to use __and_ (note that there isn't a single logical && in
> the whole type_traits, outside macros).


Yep. New patch, tested on Linux-PPC64. Minor typo fixes for the
changelog. Ok for trunk?


2015-11-01  Ville Voutilainen  

Make the default constructors of tuple and pair conditionally explicit.
* include/std/type_traits (
__do_is_implicitly_default_constructible_impl,
__is_implicitly_default_constructible_impl,
__is_implicitly_default_constructible_safe,
__is_implicitly_default_constructible): New.
* include/bits/stl_pair.h (pair::pair()): Use it.
* include/std/tuple (tuple<_T1, _T2>::tuple): Use it.
* include/std/tuple (_ImplicitlyDefaultConstructibleTuple): New.
* include/std/tuple (tuple<_Types...>::tuple()): Use it.
* testsuite/20_util/declval/requirements/1_neg.cc: Adjust.
* 
testsuite/20_util/is_implicitly_default_constructible/requirements/explicit_instantiation.cc:
New.
* 
testsuite/20_util/is_implicitly_default_constructible/requirements/typedefs.cc:
Likewise.
* testsuite/20_util/is_implicitly_default_constructible/value.cc: Likewise.
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Adjust.
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Likewise.
* testsuite/20_util/pair/cons/explicit_construct.cc: Likewise.
* testsuite/20_util/tuple/cons/explicit_construct.cc: Likewise.
diff --git a/libstdc++-v3/include/bits/stl_pair.h 
b/libstdc++-v3/include/bits/stl_pair.h
index a5a7898..dfcd357 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -141,13 +141,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template ,
- is_default_constructible<_U2>>
+ 
__is_implicitly_default_constructible<_U1>,
+ 
__is_implicitly_default_constructible<_U2>>
::value, bool>::type = true>
 #endif
   _GLIBCXX_CONSTEXPR pair()
   : first(), second() { }
 
+#if __cplusplus >= 201103L
+  template ,
+   is_default_constructible<_U2>,
+   __not_<
+ __and_<__is_implicitly_default_constructible<_U1>,
+__is_implicitly_default_constructible<_U2>>>>
+   ::value, bool>::type = false>
+  explicit constexpr pair()
+  : first(), second() { }
+#endif
+
   /** Two objects may be passed to a @c pair constructor to be copied.  */
 #if __cplusplus < 201103L
   pair(const _T1& __a, const _T2& __b)
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 8af01f4..e6c32b3 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -551,16 +551,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   return __and_...>::value;
 }
+static constexpr bool _ImplicitlyDefaultConstructibleTuple()
+{
+  return __and_<__is_implicitly_default_constructible<_Elements>...>
+::value;
+}
   };
 
 public:
   template::
-_DefaultConstructibleTuple(),
+_ImplicitlyDefaultConstructibleTuple(),
   bool>::type = true>
   constexpr tuple()
   : _Inherited() { }
 
+  template::
+_DefaultConstructibleTuple()
+  &&
+  !_TC2<_Dummy>::
+_ImplicitlyDefaultConstructibleTuple(),
+  bool>::type = false>
+  explicit constexpr tuple()
+  : _Inherited() { }
+
   // Shortcut for the cases where constructors taking _Elements...
   // need to be constrained.
   template using _TCC =
@@ -837,13 +852,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template ,
- is_default_constructible<_U2>>
+ 
__is_implicitly_default_constructible<_U1>,
+ 
__is_implicitly_default_constructible<_U2>>
::value, bool>::typ

Re: [v3 PATCH] Make the default constructors of tuple and pair conditionally explicit.

2015-11-02 Thread Ville Voutilainen
On 2 November 2015 at 21:20, Paolo Carlini  wrote:
> Can we follow the terse style already used elsewhere (eg,
> __is_direct_constructible_new_safe) thus directly inherit from __and_ and
> avoid explicit integral_constant? Otherwise patch looks good to me.


Sure. Tested again on Linux-PPC64, tests adjusted due to line changes,
Changelog entry updated to have a correct date on it.

2015-11-02  Ville Voutilainen  

Make the default constructors of tuple and pair conditionally explicit.
* include/std/type_traits (
__do_is_implicitly_default_constructible_impl,
__is_implicitly_default_constructible_impl,
__is_implicitly_default_constructible_safe,
__is_implicitly_default_constructible): New.
* include/bits/stl_pair.h (pair::pair()): Use it.
* include/std/tuple (tuple<_T1, _T2>::tuple): Use it.
* include/std/tuple (_ImplicitlyDefaultConstructibleTuple): New.
* include/std/tuple (tuple<_Types...>::tuple()): Use it.
* testsuite/20_util/declval/requirements/1_neg.cc: Adjust.
* 
testsuite/20_util/is_implicitly_default_constructible/requirements/explicit_instantiation.cc:
New.
* 
testsuite/20_util/is_implicitly_default_constructible/requirements/typedefs.cc:
Likewise.
* testsuite/20_util/is_implicitly_default_constructible/value.cc: Likewise.
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Adjust.
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Likewise.
* testsuite/20_util/pair/cons/explicit_construct.cc: Likewise.
* testsuite/20_util/tuple/cons/explicit_construct.cc: Likewise.
diff --git a/libstdc++-v3/include/bits/stl_pair.h 
b/libstdc++-v3/include/bits/stl_pair.h
index a5a7898..dfcd357 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -141,13 +141,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template ,
- is_default_constructible<_U2>>
+ 
__is_implicitly_default_constructible<_U1>,
+ 
__is_implicitly_default_constructible<_U2>>
::value, bool>::type = true>
 #endif
   _GLIBCXX_CONSTEXPR pair()
   : first(), second() { }
 
+#if __cplusplus >= 201103L
+  template ,
+   is_default_constructible<_U2>,
+   __not_<
+ __and_<__is_implicitly_default_constructible<_U1>,
+__is_implicitly_default_constructible<_U2>>>>
+   ::value, bool>::type = false>
+  explicit constexpr pair()
+  : first(), second() { }
+#endif
+
   /** Two objects may be passed to a @c pair constructor to be copied.  */
 #if __cplusplus < 201103L
   pair(const _T1& __a, const _T2& __b)
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 8af01f4..e6c32b3 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -551,16 +551,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   return __and_...>::value;
 }
+static constexpr bool _ImplicitlyDefaultConstructibleTuple()
+{
+  return __and_<__is_implicitly_default_constructible<_Elements>...>
+::value;
+}
   };
 
 public:
   template::
-_DefaultConstructibleTuple(),
+_ImplicitlyDefaultConstructibleTuple(),
   bool>::type = true>
   constexpr tuple()
   : _Inherited() { }
 
+  template::
+_DefaultConstructibleTuple()
+  &&
+  !_TC2<_Dummy>::
+_ImplicitlyDefaultConstructibleTuple(),
+  bool>::type = false>
+  explicit constexpr tuple()
+  : _Inherited() { }
+
   // Shortcut for the cases where constructors taking _Elements...
   // need to be constrained.
   template using _TCC =
@@ -837,13 +852,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template ,
- is_default_constructible<_U2>>
+ 
__is_implicitly_default_constructible<_U1>,
+ 
__is_implicitly_default_constructible<_U2>>
::value, bool>::type = true>
 
   constexpr tuple()
   : _Inherited() { }
 
+  template ,
+is_default_constructible<_U2>,
+__not_<
+  __and_<__is_implicitly_default_constructible<_U1>,
+ __is_implicitly_default_constructible<_U2>>&g

Re: [v3 PATCH] Make the default constructors of tuple and pair conditionally explicit.

2015-11-02 Thread Ville Voutilainen
On 2 November 2015 at 23:07, Paolo Carlini  wrote:
> Great, thanks a lot. Thinking more about this detail, I wonder if we should
> therefore apply the below too? Anything I'm missing?

Tested again on Linux-PPC64. Ok for trunk?

2015-11-03  Ville Voutilainen  

Make the default constructors of tuple and pair conditionally explicit.
* include/std/type_traits (is_unsigned, __is_array_unknown_bounds,
__is_default_constructible_atom, __is_default_constructible_safe,
__is_direct_constructible_new_safe, __is_direct_constructible_ref_cast,
__is_nt_default_constructible_impl, is_nothrow_default_constructible,
is_nothrow_constructible, is_nothrow_assignable,
is_trivially_constructible, is_trivially_copy_constructible,
is_trivially_move_constructible, is_trivially_assignable,
is_trivially_copy_assignable, is_trivially_move_assignable,
is_trivially_destructible): Simplify.
* include/std/type_traits (
__do_is_implicitly_default_constructible_impl,
__is_implicitly_default_constructible_impl,
__is_implicitly_default_constructible_safe,
__is_implicitly_default_constructible): New.
* include/bits/stl_pair.h (pair::pair()): Use it.
* include/std/tuple (tuple<_T1, _T2>::tuple): Use it.
* include/std/tuple (_ImplicitlyDefaultConstructibleTuple): New.
* include/std/tuple (tuple<_Types...>::tuple()): Use it.
* testsuite/20_util/declval/requirements/1_neg.cc: Adjust.
* 
testsuite/20_util/is_implicitly_default_constructible/requirements/explicit_instantiation.cc:
New.
* 
testsuite/20_util/is_implicitly_default_constructible/requirements/typedefs.cc:
Likewise.
* testsuite/20_util/is_implicitly_default_constructible/value.cc: Likewise.
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Adjust.
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Likewise.
* testsuite/20_util/pair/cons/explicit_construct.cc: Likewise.
* testsuite/20_util/tuple/cons/explicit_construct.cc: Likewise.
diff --git a/libstdc++-v3/include/bits/stl_pair.h 
b/libstdc++-v3/include/bits/stl_pair.h
index a5a7898..dfcd357 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -141,13 +141,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template ,
- is_default_constructible<_U2>>
+ 
__is_implicitly_default_constructible<_U1>,
+ 
__is_implicitly_default_constructible<_U2>>
::value, bool>::type = true>
 #endif
   _GLIBCXX_CONSTEXPR pair()
   : first(), second() { }
 
+#if __cplusplus >= 201103L
+  template ,
+   is_default_constructible<_U2>,
+   __not_<
+ __and_<__is_implicitly_default_constructible<_U1>,
+__is_implicitly_default_constructible<_U2>>>>
+   ::value, bool>::type = false>
+  explicit constexpr pair()
+  : first(), second() { }
+#endif
+
   /** Two objects may be passed to a @c pair constructor to be copied.  */
 #if __cplusplus < 201103L
   pair(const _T1& __a, const _T2& __b)
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 8af01f4..e6c32b3 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -551,16 +551,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
   return __and_...>::value;
 }
+static constexpr bool _ImplicitlyDefaultConstructibleTuple()
+{
+  return __and_<__is_implicitly_default_constructible<_Elements>...>
+::value;
+}
   };
 
 public:
   template::
-_DefaultConstructibleTuple(),
+_ImplicitlyDefaultConstructibleTuple(),
   bool>::type = true>
   constexpr tuple()
   : _Inherited() { }
 
+  template::
+_DefaultConstructibleTuple()
+  &&
+  !_TC2<_Dummy>::
+_ImplicitlyDefaultConstructibleTuple(),
+  bool>::type = false>
+  explicit constexpr tuple()
+  : _Inherited() { }
+
   // Shortcut for the cases where constructors taking _Elements...
   // need to be constrained.
   template using _TCC =
@@ -837,13 +852,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template ,
- is_default_constructible<_U2>>
+ 
__is_implicitly_default_constructible<_U1>,
+   

Re: [v3 PATCH] Make the default constructors of tuple and pair conditionally explicit.

2015-11-03 Thread Ville Voutilainen
On 3 November 2015 at 16:42, Jonathan Wakely  wrote:
> On 3 November 2015 at 02:37, Paolo Carlini wrote:
>> Hi,
>>
>> On 11/02/2015 09:20 PM, Ville Voutilainen wrote:
>>>
>>> On 2 November 2015 at 21:20, Paolo Carlini 
>>> wrote:
>>>>
>>>> Can we follow the terse style already used elsewhere (eg,
>>>> __is_direct_constructible_new_safe) thus directly inherit from __and_ and
>>>> avoid explicit integral_constant? Otherwise patch looks good to me.
>>>
>>>
>>> Sure. Tested again on Linux-PPC64, tests adjusted due to line changes,
>>> Changelog entry updated to have a correct date on it.
>>
>> Great, thanks a lot. Thinking more about this detail, I wonder if we should
>> therefore apply the below too? Anything I'm missing?
>
> I have a weak preference for deriving from xxx::type rather than xxx,
> so that the traits derive directly from either true_type or
> false_type, not indirectly via some other type that derives from
> true_type or false_type, but it probably isn't important.

I expect the inheritance hierarchies of these things to be linear, so
probably not
a huge matter. I did push the patch already. :)


[v3 PATCH] LWG 2510, make the default constructors of library tag types explicit.

2015-11-10 Thread Ville Voutilainen
Tested on Linux-X64.

2015-11-10  Ville Voutilainen  

LWG 2510, make the default constructors of library tag types
explicit.
* include/bits/mutex.h (defer_lock_t, try_lock_t,
adopt_lock_t): Add an explicit default constructor.
* include/bits/stl_pair.h (piecewise_construct_t): Likewise.
* include/bits/uses_allocator.h (allocator_arg_t): Likewise.
* libsupc++/new (nothrow_t): Likewise.
* testsuite/17_intro/tag_type_explicit_ctor.cc: New.
diff --git a/libstdc++-v3/include/bits/mutex.h 
b/libstdc++-v3/include/bits/mutex.h
index 43f5b0b..dd27989 100644
--- a/libstdc++-v3/include/bits/mutex.h
+++ b/libstdc++-v3/include/bits/mutex.h
@@ -129,14 +129,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif // _GLIBCXX_HAS_GTHREADS
 
   /// Do not acquire ownership of the mutex.
-  struct defer_lock_t { };
+  struct defer_lock_t { explicit defer_lock_t() = default; };
 
   /// Try to acquire ownership of the mutex without blocking.
-  struct try_to_lock_t { };
+  struct try_to_lock_t { explicit try_to_lock_t() = default; };
 
   /// Assume the calling thread has already obtained mutex ownership
   /// and manage it.
-  struct adopt_lock_t { };
+  struct adopt_lock_t { explicit adopt_lock_t() = default; };
 
   constexpr defer_lock_t   defer_lock { };
   constexpr try_to_lock_t  try_to_lock { };
diff --git a/libstdc++-v3/include/bits/stl_pair.h 
b/libstdc++-v3/include/bits/stl_pair.h
index dfcd357..d6f6b86 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -73,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __cplusplus >= 201103L
   /// piecewise_construct_t
-  struct piecewise_construct_t { };
+  struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
 
   /// piecewise_construct
   constexpr piecewise_construct_t piecewise_construct = 
piecewise_construct_t();
diff --git a/libstdc++-v3/include/bits/uses_allocator.h 
b/libstdc++-v3/include/bits/uses_allocator.h
index f9ea7d6..a0f084d 100644
--- a/libstdc++-v3/include/bits/uses_allocator.h
+++ b/libstdc++-v3/include/bits/uses_allocator.h
@@ -36,7 +36,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// [allocator.tag]
-  struct allocator_arg_t { };
+  struct allocator_arg_t { explicit allocator_arg_t() = default; };
 
   constexpr allocator_arg_t allocator_arg = allocator_arg_t();
 
diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new
index 0f6a05a..8621f73 100644
--- a/libstdc++-v3/libsupc++/new
+++ b/libstdc++-v3/libsupc++/new
@@ -79,7 +79,12 @@ namespace std
   };
 #endif
 
-  struct nothrow_t { };
+  struct nothrow_t
+  {
+#if __cplusplus >= 201103L
+explicit nothrow_t() = default;
+#endif
+  };
 
   extern const nothrow_t nothrow;
 
diff --git a/libstdc++-v3/testsuite/17_intro/tag_type_explicit_ctor.cc 
b/libstdc++-v3/testsuite/17_intro/tag_type_explicit_ctor.cc
new file mode 100644
index 000..4b9d217
--- /dev/null
+++ b/libstdc++-v3/testsuite/17_intro/tag_type_explicit_ctor.cc
@@ -0,0 +1,60 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++11" }
+
+// Copyright (C) 2015 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
+// <http://www.gnu.org/licenses/>.
+
+#include 
+#include 
+#include 
+#include 
+
+void f1(std::nothrow_t);
+void f2(std::piecewise_construct_t);
+void f3(std::allocator_arg_t);
+void f4(std::defer_lock_t);
+void f5(std::try_to_lock_t);
+void f6(std::adopt_lock_t);
+
+
+int main()
+{
+  std::nothrow_t v1;
+  std::piecewise_construct_t v2;
+  std::allocator_arg_t v3;
+  std::defer_lock_t v4;
+  std::try_to_lock_t v5;
+  std::try_to_lock_t v6;
+  std::nothrow_t v7 = {}; // { dg-error "explicit" }
+  std::piecewise_construct_t v8 = {}; // { dg-error "explicit" }
+  std::allocator_arg_t v9 = {}; // { dg-error "explicit" }
+  std::defer_lock_t v10 = {}; // { dg-error "explicit" }
+  std::try_to_lock_t v11 = {}; // { dg-error "explicit" }
+  std::try_to_lock_t v12 = {}; // { dg-error "explicit" }
+  f1(std::nothrow_t{});
+  f2(std::piecewise_construct_t{});
+  f3(std::allocator_arg_t{});
+  f4(std::defer_lock_t{});
+  f5(std::try_to_lock_t{});
+  f6(std::adopt_lock_t{});
+  f1({}); // { dg-error "explicit" }
+  f2({}); // { dg-error &q

[v3 PATCH] Implement D0013R2, logical type traits.

2015-11-11 Thread Ville Voutilainen
Tested on Linux-PPC64.

2015-11-11  Ville Voutilainen  

Implement D0013R2, logical type traits.

/libstdc++-v3
* include/experimental/type_traits (conjunction_v, disjunction_v,
negation_v): New.
* include/std/type_traits (conjunction, disjunction, negation):
Likewise.
* testsuite/20_util/declval/requirements/1_neg.cc: Adjust.
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Likewise.
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
Likewise.
* testsuite/experimental/type_traits/value.cc: Likewise.
* testsuite/20_util/logical_traits/requirements/explicit_instantiation.cc:
New.
* testsuite/20_util/logical_traits/requirements/typedefs.cc: Likewise.
* testsuite/20_util/logical_traits/value.cc: Likewise.

/testsuite
* g++.dg/cpp0x/Wattributes1.C: Adjust.
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C 
b/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C
index d818851..dd9011b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C
@@ -5,4 +5,4 @@
 #include 
 __attribute__((visibility("hidden")))void*operator new(std::size_t); // { 
dg-warning "visibility attribute ignored" }
 
-// { dg-message "previous declaration" "" { target *-*-* } 111 }
+// { dg-message "previous declaration" "" { target *-*-* } 116 }
diff --git a/libstdc++-v3/include/experimental/type_traits 
b/libstdc++-v3/include/experimental/type_traits
index b0ed3b0..b7f3bda 100644
--- a/libstdc++-v3/include/experimental/type_traits
+++ b/libstdc++-v3/include/experimental/type_traits
@@ -271,6 +271,28 @@ template class _Op, 
typename... _Args>
   constexpr bool is_detected_convertible_v
 = is_detected_convertible<_To, _Op, _Args...>::value;
 
+#if __cplusplus > 201402L
+
+#define __cpp_lib_experimental_logical_traits 201511
+
+using std::conjunction;
+using std::disjunction;
+using std::negation;
+
+template
+  constexpr bool conjunction_v
+= conjunction<_Bn...>::value;
+
+template
+  constexpr bool disjunction_v
+= disjunction<_Bn...>::value;
+
+template
+  constexpr bool negation_v
+= negation<_Pp>::value;
+
+#endif
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace fundamentals_v2
 } // namespace experimental
diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7448d5b..e5102de 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -154,6 +154,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public integral_constant
 { };
 
+#if __cplusplus > 201402L
+
+#define __cpp_lib_logical_traits 201511
+
+  template
+struct conjunction
+: __and_<_Bn...>
+{ };
+
+  template
+struct disjunction
+: __or_<_Bn...>
+{ };
+
+  template
+struct negation
+: __not_<_Pp>
+{ };
+#endif
+
   // For several sfinae-friendly trait implementations we transport both the
   // result information (as the member type) and the failure information (no
   // member type). This is very similar to std::enable_if, but we cannot use
diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc 
b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
index 4e7deda..37bc6b1 100644
--- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
@@ -19,7 +19,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-error "static assertion failed" "" { target *-*-* } 2239 }
+// { dg-error "static assertion failed" "" { target *-*-* } 2259 }
 
 #include 
 
diff --git 
a/libstdc++-v3/testsuite/20_util/logical_traits/requirements/explicit_instantiation.cc
 
b/libstdc++-v3/testsuite/20_util/logical_traits/requirements/explicit_instantiation.cc
new file mode 100644
index 000..b2b6c71
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/20_util/logical_traits/requirements/explicit_instantiation.cc
@@ -0,0 +1,30 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2015 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
+// <http://www.gnu.

Re: [v3 PATCH] Implement D0013R2, logical type traits.

2015-11-11 Thread Ville Voutilainen
On 12 November 2015 at 00:18, Jonathan Wakely  wrote:
> So I think we want to define them again, independently, in
> , even though it might lead to ambiguities

Here. Tested again on Linux-PPC64.

2015-11-11  Ville Voutilainen  

Implement D0013R2, logical type traits.

/libstdc++-v3
* include/experimental/type_traits (conjunction, disjunction,
negation, conjunction_v, disjunction_v, negation_v): New.
* include/std/type_traits (conjunction, disjunction, negation):
Likewise.
* testsuite/20_util/declval/requirements/1_neg.cc: Adjust.
* testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Likewise.
* testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
Likewise.
* testsuite/experimental/type_traits/value.cc: Likewise.
* testsuite/20_util/logical_traits/requirements/explicit_instantiation.cc:
New.
* testsuite/20_util/logical_traits/requirements/typedefs.cc: Likewise.
* testsuite/20_util/logical_traits/value.cc: Likewise.

/testsuite
* g++.dg/cpp0x/Wattributes1.C: Adjust.
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C 
b/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C
index d818851..dd9011b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C
@@ -5,4 +5,4 @@
 #include 
 __attribute__((visibility("hidden")))void*operator new(std::size_t); // { 
dg-warning "visibility attribute ignored" }
 
-// { dg-message "previous declaration" "" { target *-*-* } 111 }
+// { dg-message "previous declaration" "" { target *-*-* } 116 }
diff --git a/libstdc++-v3/include/experimental/type_traits 
b/libstdc++-v3/include/experimental/type_traits
index b0ed3b0..e4f3ffe 100644
--- a/libstdc++-v3/include/experimental/type_traits
+++ b/libstdc++-v3/include/experimental/type_traits
@@ -271,6 +271,35 @@ template class _Op, 
typename... _Args>
   constexpr bool is_detected_convertible_v
 = is_detected_convertible<_To, _Op, _Args...>::value;
 
+#define __cpp_lib_experimental_logical_traits 201511
+
+template
+  struct conjunction
+  : __and_<_Bn...>
+  { };
+
+template
+  struct disjunction
+  : __or_<_Bn...>
+  { };
+
+template
+  struct negation
+  : __not_<_Pp>
+  { };
+
+template
+  constexpr bool conjunction_v
+= conjunction<_Bn...>::value;
+
+template
+  constexpr bool disjunction_v
+= disjunction<_Bn...>::value;
+
+template
+  constexpr bool negation_v
+= negation<_Pp>::value;
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace fundamentals_v2
 } // namespace experimental
diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 7448d5b..e5102de 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -154,6 +154,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public integral_constant
 { };
 
+#if __cplusplus > 201402L
+
+#define __cpp_lib_logical_traits 201511
+
+  template
+struct conjunction
+: __and_<_Bn...>
+{ };
+
+  template
+struct disjunction
+: __or_<_Bn...>
+{ };
+
+  template
+struct negation
+: __not_<_Pp>
+{ };
+#endif
+
   // For several sfinae-friendly trait implementations we transport both the
   // result information (as the member type) and the failure information (no
   // member type). This is very similar to std::enable_if, but we cannot use
diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc 
b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
index 4e7deda..37bc6b1 100644
--- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
@@ -19,7 +19,7 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-error "static assertion failed" "" { target *-*-* } 2239 }
+// { dg-error "static assertion failed" "" { target *-*-* } 2259 }
 
 #include 
 
diff --git 
a/libstdc++-v3/testsuite/20_util/logical_traits/requirements/explicit_instantiation.cc
 
b/libstdc++-v3/testsuite/20_util/logical_traits/requirements/explicit_instantiation.cc
new file mode 100644
index 000..b2b6c71
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/20_util/logical_traits/requirements/explicit_instantiation.cc
@@ -0,0 +1,30 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2015 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 imp

Re: [v3 PATCH] LWG 2510, make the default constructors of library tag types explicit.

2015-11-12 Thread Ville Voutilainen
On 12 November 2015 at 16:23, Gerald Pfeifer  wrote:
> On Wed, 11 Nov 2015, Jonathan Wakely wrote:
>>
>> Fixed by this patch.
>
>
> Thanks, Jonathan!  Unfortunately bootstrap is still broken
> (on i386-unknown-freebsd11.0 at least):
>
> In file included from
> /scratch/tmp/gerald/gcc-HEAD/libstdc++-v3/src/c++11/thread.cc:27:0:
> /scratch/tmp/gerald/OBJ-1112-1414/i386-unknown-freebsd10.2/libstdc++-v3/include/
> thread: In function ‘void std::this_thread::sleep_for(const
> std::chrono::duration<_Rep1, _Period1>&)’:
> /scratch/tmp/gerald/OBJ-1112-1414/i386-unknown-freebsd10.2/libstdc++-v3/include/
> thread:300:44: error: ‘errno’ was not declared in this scope
>  while (::nanosleep(&__ts, &__ts) == -1 && errno == EINTR)
>^
> /scratch/tmp/gerald/OBJ-1112-1414/i386-unknown-freebsd10.2/libstdc++-v3/include/
> thread:300:53: error: ‘EINTR’ was not declared in this scope
>  while (::nanosleep(&__ts, &__ts) == -1 && errno == EINTR)


Note that that's a separate problem that has nothing to do with the
tag-type-explicit-default-ctor
patch.


Re: [PATCH] Fix obvious typo that breaks boot strap in delayed folding

2015-11-16 Thread Ville Voutilainen
>> On Sun, Nov 15, 2015 at 11:09:18PM +0100, Andreas Schwab wrote:
>>> Andi Kleen  writes:
>>>
>>> > Fix the obivous typos. To to commit?
>>>
>>> They are not typos.
>>
>> Ok. What do you suggest to fix the error then?
>Someone will need to fix the regression introduced by the C++ delayed
>folding.

The proposed patch makes no sense. The assignment is intentional,
the relevant flags of the element type are reflected onto the array type.
Doing a comparison there instead of assignment will not have the
desired effect.

Maybe I'm dense, but why is there a warning that suggests adding
parens around the assignment when it already has parens around it?
Is that diagnostic over-eager?


[v3 PATCH] PR libstdc++/68139

2015-12-10 Thread Ville Voutilainen
Tested on Linux-PPC64.

2015-12-11  Ville Voutilainen  

PR libstdc++/68139

/libstdc++-v3
* libsupc++/nested_exception.h (_S_rethrow): Use __std::addressof.

/testsuite
* 18_support/nested_exception/68139.cc: New.
diff --git a/libstdc++-v3/libsupc++/nested_exception.h 
b/libstdc++-v3/libsupc++/nested_exception.h
index a716f75..82b95df 100644
--- a/libstdc++-v3/libsupc++/nested_exception.h
+++ b/libstdc++-v3/libsupc++/nested_exception.h
@@ -37,6 +37,7 @@
 #else
 
 #include 
+#include 
 
 #if ATOMIC_INT_LOCK_FREE < 2
 #  error This platform does not support exception propagation.
@@ -142,7 +143,8 @@ namespace std
 {
   static void _S_rethrow(const _Tp& __t)
   {
-   if (auto __tp = dynamic_cast(&__t))
+   if (auto __tp =
+dynamic_cast(std::__addressof(__t)))
  __tp->rethrow_nested();
   }
 };
diff --git a/libstdc++-v3/testsuite/18_support/nested_exception/68139.cc 
b/libstdc++-v3/testsuite/18_support/nested_exception/68139.cc
new file mode 100644
index 000..551f931
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/nested_exception/68139.cc
@@ -0,0 +1,31 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++11" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2015 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
+// <http://www.gnu.org/licenses/>.
+
+#include 
+
+// libstdc++/68139
+struct C {
+virtual ~C(){}
+void operator&() const = delete;
+};
+
+int main() { std::rethrow_if_nested(C()); }
+


Re: [v3 PATCH] PR libstdc++/68139

2015-12-10 Thread Ville Voutilainen
On 11 December 2015 at 08:55, Marc Glisse  wrote:
> On Fri, 11 Dec 2015, Ville Voutilainen wrote:
>
>> Tested on Linux-PPC64.
>>
>> 2015-12-11  Ville Voutilainen  
>>
>>PR libstdc++/68139
>>
>>/libstdc++-v3
>>* libsupc++/nested_exception.h (_S_rethrow): Use __std::addressof.
>
>   ^^
>
> Typo.


I must be blind, but I don't see what you mean. :)


Re: [v3 PATCH] PR libstdc++/68139

2015-12-10 Thread Ville Voutilainen
On 11 December 2015 at 09:52, Marc Glisse  wrote:
/libstdc++-v3
* libsupc++/nested_exception.h (_S_rethrow): Use __std::addressof.
>>> Typo.
>> I must be blind, but I don't see what you mean. :)
> Shouldn't the underscores apply to addressof, not to the namespace?


Hah! Yes, thanks, I will fix that. :)


[PATCH] libstd++: Library-side tests for parenthesized aggregate init (c++/92878, c++/92947)

2020-02-23 Thread Ville Voutilainen
This shebang adds library tests for all cases of parenthesized aggregate
initialization that I could find. Tested locally on Linux-x64, going to
test with full suite on Linux-PPC64, OK for trunk if tests pass?

2020-02-23  Ville Voutilainen  

Library-side tests for parenthesized aggregate init

PR c++/92878
PR c++/92947

* testsuite/20_util/allocator_traits/members/92878_92947.cc: New.
* testsuite/20_util/any/assign/92878_92947.cc: Likewise.
* testsuite/20_util/any/cons/92878_92947.cc: Likewise.
* testsuite/20_util/is_constructible/92878_92947.cc: Likewise.
* testsuite/20_util/optional/assignment/92878_92947.cc: Likewise.
* testsuite/20_util/optional/cons/92878_92947.cc: Likewise.
* testsuite/20_util/pair/cons/92878_92947.cc: Likewise.
* testsuite/20_util/shared_ptr/creation/92878_92947.cc: Likewise.
* testsuite/20_util/specialized_algorithms/construct_at/92878_92947.cc:
Likewise.
* testsuite/20_util/unique_ptr/creation/92878_92947.cc: Likewise.
* testsuite/20_util/uses_allocator/92878_92947.cc: Likewise.
* testsuite/20_util/variant/92878_92947.cc: Likewise.
* testsuite/23_containers/deque/modifiers/emplace/92878_92947.cc:
Likewise.
* testsuite/23_containers/forward_list/modifiers/92878_92947.cc:
Likewise.
* testsuite/23_containers/list/modifiers/emplace/92878_92947.cc:
Likewise.
* testsuite/23_containers/map/modifiers/emplace/92878_92947.cc:
Likewise.
* testsuite/23_containers/multimap/modifiers/emplace/92878_92947.cc:
Likewise.
* testsuite/23_containers/multiset/modifiers/emplace/92878_92947.cc:
Likewise.
* testsuite/23_containers/priority_queue/92878_92947.cc: Likewise.
* testsuite/23_containers/queue/92878_92947.cc: Likewise.
* testsuite/23_containers/set/modifiers/emplace/92878_92947.cc:
Likewise.
* testsuite/23_containers/stack/92878_92947.cc: Likewise.
* testsuite/23_containers/unordered_map/modifiers/92878_92947.cc:
Likewise.
* testsuite/23_containers/unordered_multimap/modifiers/92878_92947.cc:
Likewise.
* testsuite/23_containers/unordered_multiset/modifiers/92878_92947.cc:
Likewise.
* testsuite/23_containers/unordered_set/modifiers/92878_92947.cc:
Likewise.
* testsuite/23_containers/vector/modifiers/emplace/92878_92947.cc:
Likewise.


aggr-init-lib-tests.diff.gz
Description: application/gzip


Re: [committed] libstdc++: Fix regression in std::move algorithm (PR 93872)

2020-02-25 Thread Ville Voutilainen
On Tue, 25 Feb 2020 at 15:36, Jonathan Wakely  wrote:
> I think what I'd really like to do is get rid of __memmove entirely.
> We already have code that does the explicit assignment in a loop, for
> the cases where we can't use __builtin_memmove because the type is not
> trivially copyable.
>
> We should just use that existing code during constant evaluation, i.e.
> don't do the __builtin_memmove optimizations during constant
> evaluation. It seems much cleaner to just not use the optimization
> rather than wrap it to be usable in constant expressions.
>
> We already have to do that for {copy,move}_backward anyway, because
> __memmove doesn't correctly implement the std::memmove semantics for
> overlapping ranges. But we do it **wrong** and turn copy_backward into
> move_backward during constant evaluation.
>
> Here's a patch that gets rid of __memmove and fixes that bug
> (generated with 'git diff -b' so that the changes to the logic aren't
> obscured by the whitespace changes caused by re-indenting).
>
> Maybe I should just go ahead and do this now, since __memmove (and the
> problems it causes) are new for GCC 10 anyway. That would revert
>  to something closer to the GCC 9 version.

Looks good to me.


Re: [PATCH 1/1] libstdc++: Deal with ENOSYS == ENOTSUP

2020-03-06 Thread Ville Voutilainen
On Fri, 6 Mar 2020 at 10:41, Andreas Krebbel  wrote:
>
> zTPF uses the same numeric value for ENOSYS and ENOTSUP.
>
> Ok for mainline?
>
> libstdc++-v3/ChangeLog:
>
> 2020-03-06  Andreas Krebbel  
>
> * src/c++11/system_error.cc: Omit the ENOTSUP case statement if it
> would match ENOSYS.
> ---
>  libstdc++-v3/src/c++11/system_error.cc | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/src/c++11/system_error.cc 
> b/libstdc++-v3/src/c++11/system_error.cc
> index 7844afe6d2a..1f06e67feea 100644
> --- a/libstdc++-v3/src/c++11/system_error.cc
> +++ b/libstdc++-v3/src/c++11/system_error.cc
> @@ -251,7 +251,8 @@ namespace
>  #ifdef ENOTSOCK
>case ENOTSOCK:
>  #endif
> -#ifdef ENOTSUP
> +#if defined ENOTSUP && (!defined ENOSYS || ENOTSUP != ENOSYS)

Hmm, what system does not have ENOSYS but has ENOTSUP? Meaning the
!defined ENOSYS
bit?


Re: [PATCH 1/1] libstdc++: Deal with ENOSYS == ENOTSUP

2020-03-06 Thread Ville Voutilainen
On Fri, 6 Mar 2020 at 11:52, Andreas Krebbel  wrote:

> > Hmm, what system does not have ENOSYS but has ENOTSUP? Meaning the
> > !defined ENOSYS
> > bit?
> >
> None that I know about. It is just to make sure the compare afterwards 
> operates on defined inputs.

Ah, I see, indeed. This dance is done also for EOPNOTSUPP, looks good
to me (but Jonathan still needs
to do the approval).


Re: [PATCH, libstdc++] Implement C++20 p1032 default_searcher constexprosity.

2019-11-15 Thread Ville Voutilainen
On Fri, 15 Nov 2019 at 22:16, Smith-Rowland, Edward M
 wrote:
>
> Pretty self-explanatory.

LGTM. Jonathan still needs to ack it.


Re: [PATCH][Hashtable 5/6] Remove H1/H2 template parameters

2019-11-17 Thread Ville Voutilainen
On Sun, 17 Nov 2019 at 23:15, François Dumont  wrote:
>
> H1 used to be a reference to the user Hash, now _Hashtable and unordered
> types agree on the same Hash type which is more intuitive.
>
> I also chose to not support anymore a stateful ranged hash functor. We
> only use _Mod_range_hashing and _Mask_range_hashing.
>
> Thanks to this simplification _M_bucket_index can also be simplified.

Do we know whether there are existing users that this breaks? Also, is
this ABI-compatible
for our unordered containers?


Re: [PATCH][Hashtable 5/6] Remove H1/H2 template parameters

2019-11-18 Thread Ville Voutilainen
On Mon, 18 Nov 2019 at 23:41, François Dumont  wrote:
> >   Also, is
> > this ABI-compatible
> > for our unordered containers?
> >
> IMHO, yes it is.
>
> In hashtable_policy.h _H1 was the user hash which I renamed in _Hash,
> the same template name that for unordered containers.
>
> _H2 was always _Mod_range_hashing and previous _Hash always
> _Default_ranged_hash, both stateless types. Only _H1 and _H2 were stored
> in _Hash_code_base for instance. _H1 is still as _Hash and _H2 was just
> empty and moreover stored last so removing it has no impact.

Right, and as I understood the code, it's all empty base objects
anyway, so it boils down to whether
a set of empty bases can change without causing an ABI break, and I
don't think there's an ABI
problem here because the actual _Hashtable is stored as a member of
various containers, and its
size doesn't change, and based on what you wrote, with which my
code-reading agrees, the behaviour
doesn't change either. So the patch seems okay to me.


Re: Implement the part of C++20 p1032 Misc constexpr bits.

2019-11-20 Thread Ville Voutilainen
On Wed, 20 Nov 2019 at 11:47, Christophe Lyon
 wrote:
>
> On Thu, 14 Nov 2019 at 16:55, Jonathan Wakely  wrote:
> >
> > On 09/11/19 02:07 +, Smith-Rowland, Edward M wrote:
> > >Here is the  part of C++20 p1032 Misc constexpr bits.
> > >
> > >Tested on x86_64-linux. OK?
> >
> > OK for trunk, thanks.
> >
>
> Hi,
>
> The new test constexpr_allocator_arg_t.cc fails on arm and aarch64 and
> many other targets according to gcc-testresults.
> Is that expected?

No, that's not expected. Can you give a link to the build log?


Re: Implement the part of C++20 p1032 Misc constexpr bits.

2019-11-20 Thread Ville Voutilainen
On Wed, 20 Nov 2019 at 12:16, Christophe Lyon
 wrote:
>
> On Wed, 20 Nov 2019 at 11:10, Ville Voutilainen
>  wrote:
> >
> > On Wed, 20 Nov 2019 at 11:47, Christophe Lyon
> >  wrote:
> > >
> > > On Thu, 14 Nov 2019 at 16:55, Jonathan Wakely  wrote:
> > > >
> > > > On 09/11/19 02:07 +, Smith-Rowland, Edward M wrote:
> > > > >Here is the  part of C++20 p1032 Misc constexpr bits.
> > > > >
> > > > >Tested on x86_64-linux. OK?
> > > >
> > > > OK for trunk, thanks.
> > > >
> > >
> > > Hi,
> > >
> > > The new test constexpr_allocator_arg_t.cc fails on arm and aarch64 and
> > > many other targets according to gcc-testresults.
> > > Is that expected?
> >
> > No, that's not expected. Can you give a link to the build log?
>
> On (cross) aarch64, I can see:
> FAIL: 20_util/tuple/cons/constexpr_allocator_arg_t.cc (test for excess errors)
> Excess errors:
> /libstdc++-v3/testsuite/20_util/tuple/cons/constexpr_allocator_arg_t.cc:48:
> error: non-constant condition for static assertion
> /libstdc++-v3/testsuite/20_util/tuple/cons/constexpr_allocator_arg_t.cc:48:
>   in 'constexpr' expansion of 'test_tuple()'
> /libstdc++-v3/testsuite/20_util/tuple/cons/constexpr_allocator_arg_t.cc:31:
>   in 'constexpr' expansion of 'ta.std::tuple double>::tuple >(std::allocator_arg, alloc)'
> /aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-aarch64-none-linux-gnu/gcc3/aarch64-none-linux-gnu/libstdc++-v3/include/tuple:705:
> error: 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail
> ...>::_Tuple_impl(std::allocator_arg_t, const _Alloc&) [with _Alloc =
> std::allocator; long unsigned int _Idx = 0; _Head = int; _Tail =
> {double, double}]' called in a constant expression
> /aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-aarch64-none-linux-gnu/gcc3/aarch64-none-linux-gnu/libstdc++-v3/include/tuple:251:
> error: call to non-'constexpr' function 'std::__uses_alloc_t<_Tp,
> _Alloc, _Args ...> std::__use_alloc(const _Alloc&) [with _Tp = int;
> _Alloc = std::allocator; _Args = {}; std::__uses_alloc_t<_Tp,
> _Alloc, _Args ...> = std::__uses_alloc_t >]'
>
>
> I see it failing at r278333, was it fixed since then?

Yes, in r278373.


Re: [C++ PATCH] PR c++/79133

2018-08-06 Thread Ville Voutilainen
On 8 July 2018 at 02:08, Ville Voutilainen  wrote:
> On 8 July 2018 at 01:54, Paolo Carlini  wrote:
>>> That would make this more consistent with such a shadow warning, but I
>>> don't want
>>> to use the shadowing wording (which would be easy to do; just set
>>> 'shadowed' and do
>>> a 'goto inform'), because this isn't shadowing in the precise sense;
>>> the shadowing cases
>>> are warnings, whereas this is more like the redeclaration errors in
>>> the same function.
>>
>> ... indeed and that annoys me a bit. Not having studied at all c++/79133 so
>> far (sorry) it seems a little weird to me that according to the standard we
>> have to handle the two types of "shadowing" in different ways, one more
>> strict, one less. Thus I would suggest double checking the details of that,
>> eventually with Jason too in terms of the actual patch you would like to
>> apply.
>
> Well. The PR is about DR 2211 which, in simple terms, says that lambda
> parameters
> and captures cannot have the same name. See
> http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#2211
>
> That's stricter than -Wshadow, but otherwise equally strict as the
> other error cases already handled
> in check_local_shadow. So I'll make this error case more consistent
> with the others. We already
> handle redeclaration errors slightly differently from shadowing
> warnings in that function.

Here's an updated patch. Tested on Linux-PPC64, OK for trunk?

Backports?

2018-08-06  Ville Voutilainen  

gcc/cp/

PR c++/79133
* name-lookup.c (check_local_shadow): Reject captures and parameters
with the same name.

testsuite/

PR c++/79133
* g++.dg/cpp0x/lambda/lambda-shadow3.C: New.
* g++.dg/cpp1y/lambda-generic-variadic18.C: Likewise.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 3aafb0f..72d87b3 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2640,6 +2640,7 @@ check_local_shadow (tree decl)
 		  || TREE_CODE (decl) == TYPE_DECL)))
   && DECL_FUNCTION_SCOPE_P (old)
   && (!DECL_ARTIFICIAL (decl)
+	  || is_capture_proxy (decl)
 	  || DECL_IMPLICIT_TYPEDEF_P (decl)
 	  || (VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl
 {
@@ -2648,7 +2649,8 @@ check_local_shadow (tree decl)
   /* Don't complain if it's from an enclosing function.  */
   if (DECL_CONTEXT (old) == current_function_decl
 	  && TREE_CODE (decl) != PARM_DECL
-	  && TREE_CODE (old) == PARM_DECL)
+	  && TREE_CODE (old) == PARM_DECL
+	  && !is_capture_proxy (decl))
 	{
 	  /* Go to where the parms should be and see if we find
 	 them there.  */
@@ -2665,6 +2667,21 @@ check_local_shadow (tree decl)
 	  return;
 	}
 	}
+  /* DR 2211: check that captures and parameters
+	 do not have the same name. */
+  else if (is_capture_proxy (decl))
+	{
+	  if (current_lambda_expr ()
+	  && DECL_CONTEXT (old) == lambda_function (current_lambda_expr ())
+	  && TREE_CODE (old) == PARM_DECL
+	  && DECL_NAME (decl) != this_identifier)
+	{
+	  error_at (DECL_SOURCE_LOCATION (old),
+			"lambda parameter %qD "
+			"previously declared as a capture", old);
+	}
+	  return;
+	}
 
   /* The local structure or class can't use parameters of
 	 the containing function anyway.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
new file mode 100644
index 000..8364321
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
@@ -0,0 +1,6 @@
+// { dg-do compile { target c++11 } }
+
+int main() {
+  int x = 42;
+  auto lambda = [x](int x) {}; // { dg-error "previously declared as a capture" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C
new file mode 100644
index 000..1eb9cce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++14 } }
+
+int main() {
+  int x = 42;
+  auto lambda2 = [x=x](int x) {}; // { dg-error "previously declared as a capture" }
+  auto lambda3 = [x](auto... x) {}; // { dg-error "previously declared as a capture" }
+  auto lambda4 = [](auto... x) {
+auto lambda5 = [x...](auto... x) {};  // { dg-error "previously declared as a capture" }
+auto lambda6 = [x...](int x) {};  // { dg-error "previously declared as a capture" }
+  };
+}


Re: [C++ PATCH] PR c++/79133

2018-08-07 Thread Ville Voutilainen
On 7 August 2018 at 13:12, Jason Merrill  wrote:
> Maybe put this block first rather than add !is_capture_proxy to the if
> condition?

Thus?
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 3aafb0f..0faf739 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2640,13 +2640,29 @@ check_local_shadow (tree decl)
 		  || TREE_CODE (decl) == TYPE_DECL)))
   && DECL_FUNCTION_SCOPE_P (old)
   && (!DECL_ARTIFICIAL (decl)
+	  || is_capture_proxy (decl)
 	  || DECL_IMPLICIT_TYPEDEF_P (decl)
 	  || (VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl
 {
   /* DECL shadows a local thing possibly of interest.  */
 
+  /* DR 2211: check that captures and parameters
+	 do not have the same name. */
+  if (is_capture_proxy (decl))
+	{
+	  if (current_lambda_expr ()
+	  && DECL_CONTEXT (old) == lambda_function (current_lambda_expr ())
+	  && TREE_CODE (old) == PARM_DECL
+	  && DECL_NAME (decl) != this_identifier)
+	{
+	  error_at (DECL_SOURCE_LOCATION (old),
+			"lambda parameter %qD "
+			"previously declared as a capture", old);
+	}
+	  return;
+	}
   /* Don't complain if it's from an enclosing function.  */
-  if (DECL_CONTEXT (old) == current_function_decl
+  else if (DECL_CONTEXT (old) == current_function_decl
 	  && TREE_CODE (decl) != PARM_DECL
 	  && TREE_CODE (old) == PARM_DECL)
 	{
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
new file mode 100644
index 000..8364321
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-shadow3.C
@@ -0,0 +1,6 @@
+// { dg-do compile { target c++11 } }
+
+int main() {
+  int x = 42;
+  auto lambda = [x](int x) {}; // { dg-error "previously declared as a capture" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C
new file mode 100644
index 000..1eb9cce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic18.C
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++14 } }
+
+int main() {
+  int x = 42;
+  auto lambda2 = [x=x](int x) {}; // { dg-error "previously declared as a capture" }
+  auto lambda3 = [x](auto... x) {}; // { dg-error "previously declared as a capture" }
+  auto lambda4 = [](auto... x) {
+auto lambda5 = [x...](auto... x) {};  // { dg-error "previously declared as a capture" }
+auto lambda6 = [x...](int x) {};  // { dg-error "previously declared as a capture" }
+  };
+}


Re: [C++ PATCH] PR c++/79133

2018-08-07 Thread Ville Voutilainen
On 7 August 2018 at 14:50, Jason Merrill  wrote:
> OK.

Trunk only, no backports, presumably. I asked about backports in the
second-to-last submission, but I am gravitating
away from backporting this, it's a non-regression that's dealing with
a fairly recent change, so I'm going to operate
with a trunk-only agenda. :)


Re: [PATCH] fix std::variant::swap for trivially-move-assignable types

2018-08-07 Thread Ville Voutilainen
On 7 August 2018 at 17:29, Jonathan Wakely  wrote:
> On 07/08/18 15:24 +0100, Jonathan Wakely wrote:
>>
>> This patch fixes the bug, but is it correct?
>>
>> IIUC the _M_destructive_move effects don't depend on whether move
>> assignment is trivial, so should be defined the same way in both
>> specializations. It also looks like we can use it in the non-trivial
>> move assignment.
>>
>> Should we define _M_destructive_move on _Move_ctor_base instead of
>> _Move_assign_base, so the duplication could be avoided?
>
>
> Or maybe into _Move_ctor_base as in the attached patch. That allows it
> to be used in _Copy_assign_base, and means we can omit the try-catch
> block when the move construction is trivial.
>

_Move_ctor_base seems fine to me. I plan to revamp our variant to
bring it up to the changes done before C++17
was done, to fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85517,
and I plan to do it shortly.


Re: Improve safe iterator move semantic

2018-08-10 Thread Ville Voutilainen
On 10 August 2018 at 13:47, Jonathan Wakely  wrote:
> Doing a test like this with TSan should be the absolute minimum
> required for any change to the mutex locking policy.

Agreed. Concurrency code is something that our test suite is not
well-equipped to test (because
it doesn't support TSan and such yet), so it would seem prudent to
stress-test such patches
via testsuite-external means.

> I'm not aware of people complaining about the performance of debug
> mode anyway. Everybody I speak to is happy to accept a performance hit
> in order to get checking.

Yep; while it's nice to have performance improvements in debug mode,
there are probably more
important and significant ways to improve it..

> I think https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86843 would be
> more helpful to our users, as it would allow some Debug Mode checks to
> be enabled in programs that can't currently use it (because
> recompiling the entire program is not possible).

..like this one, which would be a major usability improvement.


Re: [PATCH] Deprecate std::get_temporary_buffer

2018-08-14 Thread Ville Voutilainen
On 14 August 2018 at 23:34, Jonathan Wakely  wrote:
> This was deprecated in C++17, and has been removed from the current
> draft. This adds the dprecated attribute for C++17 and later.
>
> We can't actually remove it for C++2a because we use it (indirectly)
> in stl_algo.h. We could rename it to __get_temporary_buffer for our
> internal uses, and then add back get_temporary_buffer as a simple
> forwarding function guarded by:
>
> #if __cplusplus <= 201703L || _GLIBCXX_USE_DEPRECATED
>
> This patch doesn't do that though.
>
> Does anybody object to adding the deprecated attribute here?

Not me.

> Does anybody want to argue in favour of completely removing it for
> C++2a?

Not me.


Re: [PATCH] RFC: remove std::tuple partial specialization

2018-08-17 Thread Ville Voutilainen
On 17 August 2018 at 22:29, Jonathan Wakely  wrote:
> That was added by https://gcc.gnu.org/ml/libstdc++/2016-12/msg00122.html
> but I see no justification for that in the standard (and neither
> libc++ nor MSFTL does anything special here, so they fail the test
> too).
>
> Ville, I'm no longer convinced by your rationale. Why is that

You mean the part where I said "the variadic constructor doesn't run
into this problem"?
I may have been wrong about the variadic.

> constraint on the 2-tuple partial specialization when the standard
> doesn't say anything like "if sizeof...(Types)==2 this constructor
> shall not participate in overload resolution unless decay_t is
> not allocator_arg_t" for the tuple(_UTypes&&...) constructor?
>
> As far as I can tell, the standard says that the test is wrong.
>
> If we think the test is right, we should report a defect. Either way,
> I think this patch would be a nice simplification. We can either fix
> (or just remove) the test, or constrain the primary template.

I think the test is reasonable to the point of being obvious. If you
pass an allocator_arg
and an allocator, the intent is that uses-allocator construction is
always used, not that
it's used unless the element type is constructible from allocator_arg
and an allocator.
While the explicitness and presence of some tuple constructors depends
on the properties
of the element types, the semantics of the allocator constructors
should not depend on them
to decide whether to do uses-allocator construction or not - that
would be a vector again.


Re: [PATCH] RFC: remove std::tuple partial specialization

2018-08-17 Thread Ville Voutilainen
On 17 August 2018 at 22:46, Ville Voutilainen
 wrote:
>>
>> If we think the test is right, we should report a defect. Either way,
>> I think this patch would be a nice simplification. We can either fix
>> (or just remove) the test, or constrain the primary template.
>
> I think the test is reasonable to the point of being obvious. If you
> pass an allocator_arg
> and an allocator, the intent is that uses-allocator construction is
> always used, not that
> it's used unless the element type is constructible from allocator_arg
> and an allocator.
> While the explicitness and presence of some tuple constructors depends
> on the properties
> of the element types, the semantics of the allocator constructors
> should not depend on them
> to decide whether to do uses-allocator construction or not - that
> would be a vector again.

So yes, I strongly think we should report a defect.


Re: [PATCH] RFC: Refactor std::tuple constraints

2018-08-21 Thread Ville Voutilainen
On 21 August 2018 at 12:17, Jonathan Wakely  wrote:
> I think this is slightly simpler and easier to maintain, but I'd like
> to hear other views, especially from Ville who added most of these
> constraints and does most of the work to maintain std::tuple.

+1, OK.


Re: Relocation (= move+destroy)

2018-09-02 Thread Ville Voutilainen
On 2 September 2018 at 23:03, Jonathan Wakely  wrote:
> On 01/09/18 21:56 +0200, Marc Glisse wrote:
>>
>> On Sat, 1 Sep 2018, Marc Glisse wrote:
>>
>>> this patch passed bootstrap+regtest on powerpc64le-unknown-linux-gnu.
>>
>>
>> I realized afterwards that for a C++17-only feature, that's not testing
>> much... So I changed it to apply in C++14 and fixed a minor issue. There is
>> now a single regression:
>>
>> 23_containers/vector/modifiers/push_back/49836.cc
>>
>> The PR was about not using assignment for an operation that should only
>> use construction, and that's fine. But we ended up with a stricter testcase
>> using CopyConsOnlyType, where the type has a deleted move constructor which,
>> as far as I understand the standard, makes it an invalid type for use in
>> vector::push_back. Is that something we want to keep supporting, or may I
>> break it? What is happening is that
>
>
> I think you can break it. I'll look back over the history of the test
> case, but I don't think supporting deleted moves is intended.

We have supported those occasionally; I did so in std::any, but the
standard has explicitly
been moving towards a direction where deleted moves (if corresponding
copies are not
deleted) are not a supported thing, so I concur with the suggestion of
breaking such tests being okay.


[v3 PATCH] PR libstdc++/80675, PR libstdc++/80940

2017-06-09 Thread Ville Voutilainen
Tested on Linux-x64.

2017-06-10  Ville Voutilainen  

PR libstdc++/80675
PR libstdc++/80940
* include/std/istream:
(__is_convertible_to_basic_istream_test(basic_istream<_Ch, _Up>*)): New.
(__do_is_convertible_to_basic_istream_impl): Likewise.
(__is_convertible_to_basic_istream_impl): Likewise.
(__is_convertible_to_basic_istream): Use the new base.
(__rvalue_istream_type): New.
(operator>>(_Istream&&, _Tp&&)): Use the new helper alias
for the SFINAE check, convert to the helper alias type before
doing the actual extraction.
* include/std/ostream:
(__is_convertible_to_basic_ostream_test(basic_ostream<_Ch, _Up>*)): New.
(__do_is_convertible_to_basic_ostream_impl): Likewise.
(__is_convertible_to_basic_ostream_impl): Likewise.
(__is_convertible_to_basic_ostream): Use the new base.
(__rvalue_ostream_type): New.
(operator<<(_Ostream&&, const _Tp&)): Use the new helper alias
for the SFINAE check, convert to the helper alias type before
doing the actual insertion.
* testsuite/27_io/rvalue_streams-2.cc: Add new tests.
diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream
index 85c0a5a..86a5d03 100644
--- a/libstdc++-v3/include/std/istream
+++ b/libstdc++-v3/include/std/istream
@@ -908,20 +908,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 ws(basic_istream<_CharT, _Traits>& __is);
 
 #if __cplusplus >= 201103L
+  template
+basic_istream<_Ch, _Up>&
+__is_convertible_to_basic_istream_test(basic_istream<_Ch, _Up>*);
+
+  template
+struct __is_convertible_to_basic_istream_impl
+{
+  using __istream_type = void;
+};
 
   template
-struct __is_convertible_to_basic_istream
+using __do_is_convertible_to_basic_istream_impl =
+decltype(__is_convertible_to_basic_istream_test
+(declval::type*>()));
+
+  template
+struct __is_convertible_to_basic_istream_impl
+<_Tp,
+ __void_t<__do_is_convertible_to_basic_istream_impl<_Tp>>>
 {
-  template
-  static basic_istream<_Ch, _Up>& __check(basic_istream<_Ch, _Up>*);
+  using __istream_type =
+   __do_is_convertible_to_basic_istream_impl<_Tp>;
+};
 
-  static void __check(...);
+  template
+struct __is_convertible_to_basic_istream
+: __is_convertible_to_basic_istream_impl<_Tp>
+{
 public:
-  using istream_type =
-   decltype(__check(declval::type*>()));
-  using type = __not_>;
+  using type = __not_::__istream_type>>;
   constexpr static bool value = type::value;
-  };
+};
 
   template
 struct __is_extractable : false_type {};
@@ -932,6 +951,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  >> declval<_Tp>())>>
 : true_type {};
 
+  template
+using __rvalue_istream_type =
+  typename __is_convertible_to_basic_istream<
+   _Istream>::__istream_type;
+
   // [27.7.1.6] Rvalue stream extraction
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 2328. Rvalue stream extraction should use perfect forwarding
@@ -949,13 +973,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 inline
 typename enable_if<__and_<__not_>,
  __is_convertible_to_basic_istream<_Istream>,
- __is_extractable<_Istream&, _Tp&&>>::value,
-  typename __is_convertible_to_basic_istream<
-_Istream>::istream_type>::type
+ __is_extractable<
+   __rvalue_istream_type<_Istream>,
+   _Tp&&>>::value,
+  __rvalue_istream_type<_Istream>>::type
 operator>>(_Istream&& __is, _Tp&& __x)
 {
-  __is >> std::forward<_Tp>(__x);
-  return __is;
+  __rvalue_istream_type<_Istream> __ret_is = __is;
+  __ret_is >> std::forward<_Tp>(__x);
+  return __ret_is;
 }
 #endif // C++11
 
diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index 50b70a5..cffcd06 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -613,19 +613,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return __os.flush(); }
 
 #if __cplusplus >= 201103L
+  template
+basic_ostream<_Ch, _Up>&
+__is_convertible_to_basic_ostream_test(basic_ostream<_Ch, _Up>*);
+
+  template
+struct __is_convertible_to_basic_ostream_impl
+{
+  using __ostream_type = void;
+};
+
+  template
+using __do_is_convertible_to_basic_ostream_impl =
+decltype(__is_convertible_to_basic_ostream_test
+(declval::type*>()));
+
+  template
+struct __is_convertible_to_basic_ostream_impl
+

[C++ PATCH] Remove the null check from placement new in all modes

2017-11-09 Thread Ville Voutilainen
Tested manually on Linux-X64, finishing testing with the full suite on
Linux-PPC64.

I spent far too much time contemplating whether to add a compatibility switch
for this, but -fcheck-new *is* such a compatibility switch.

OK for trunk?

2017-11-10  Ville Voutilainen  

gcc/

Remove the null check from placement new in all modes
* cp/init.c (build_new_1): Don't do a null check for
a namespace-scope non-replaceable placement new
in any mode unless -fcheck-new is provided.

testsuite/

Remove the null check from placement new in all modes
* g++.dg/init/pr35878_1.C: Adjust.
* g++.dg/init/pr35878_4.C: New.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 9e6e3af..1fcd91d 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2758,7 +2758,7 @@ malloc_alignment ()
 static bool
 std_placement_new_fn_p (tree alloc_fn)
 {
-  if ((cxx_dialect > cxx14) && DECL_NAMESPACE_SCOPE_P (alloc_fn))
+  if (DECL_NAMESPACE_SCOPE_P (alloc_fn))
 {
   tree first_arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn)));
   if ((TREE_VALUE (first_arg) == ptr_type_node)
diff --git a/gcc/testsuite/g++.dg/init/pr35878_1.C 
b/gcc/testsuite/g++.dg/init/pr35878_1.C
index e2fc493..7fb3221 100644
--- a/gcc/testsuite/g++.dg/init/pr35878_1.C
+++ b/gcc/testsuite/g++.dg/init/pr35878_1.C
@@ -1,7 +1,7 @@
 // PR c++/35878
 // { dg-do compile }
 // { dg-options "-O2 -std=gnu++11 -fdump-tree-optimized" }
-// { dg-final { scan-tree-dump-times "v_\[0-9]+\\(D\\) \[=!]= 0" 1 "optimized" 
} }
+// { dg-final { scan-tree-dump-not "v_\[0-9]+\\(D\\) \[=!]= 0" "optimized" } }
 
 #include 
 #include 
diff --git a/gcc/testsuite/g++.dg/init/pr35878_4.C 
b/gcc/testsuite/g++.dg/init/pr35878_4.C
new file mode 100644
index 000..bd27565
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/pr35878_4.C
@@ -0,0 +1,23 @@
+// PR c++/35878
+// { dg-do compile }
+// { dg-options "-O2 -std=gnu++11 -fcheck-new -fdump-tree-optimized" }
+// { dg-final { scan-tree-dump-times "v_\[0-9]+\\(D\\) \[=!]= 0" 1 "optimized" 
} }
+
+#include 
+#include 
+
+struct s1{
+  int a;
+  int b;
+  int c;
+};
+
+void f1 (s1 * v, s1&& s)
+{
+   new (v) s1(std::move(s));
+}
+
+void f2 (s1 * v, s1&& s)
+{
+   *v = std::move(s);
+}


Re: [C++ PATCH] Remove the null check from placement new in all modes

2017-11-10 Thread Ville Voutilainen
On 10 November 2017 at 18:19, Jason Merrill  wrote:
> OK.


I see non-obvious testsuite failures, I'll see if adding -fcheck-new
to those cases
cures the problem. Please stay tuned. :)


Re: [C++ PATCH] Remove the null check from placement new in all modes

2017-11-13 Thread Ville Voutilainen
On 10 November 2017 at 18:55, Ville Voutilainen
 wrote:
> On 10 November 2017 at 18:19, Jason Merrill  wrote:
>> OK.
>
>
> I see non-obvious testsuite failures, I'll see if adding -fcheck-new
> to those cases
> cures the problem. Please stay tuned. :)

Here. Tested on Linux-PPC64 and Linux-x64.

2017-11-13  Ville Voutilainen  

gcc/

Remove the null check from placement new in all modes
* cp/init.c (build_new_1): Don't do a null check for
a namespace-scope non-replaceable placement new
in any mode unless -fcheck-new is provided.

testsuite/

Remove the null check from placement new in all modes
* g++.dg/init/pr35878_1.C: Adjust.
* g++.dg/init/pr35878_4.C: New.
* g++.dg/torture/pr48695.C: Adjust.
* g++.dg/tree-ssa/pr31146-2.C: Likewise.
* g++.dg/tree-ssa/pr31146-3.C: New.
* g++.dg/tree-ssa/pr41428-2.C: Likewise.
* g++.dg/tree-ssa/pr41428.C: Adjust.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 9e6e3af..1fcd91d 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2758,7 +2758,7 @@ malloc_alignment ()
 static bool
 std_placement_new_fn_p (tree alloc_fn)
 {
-  if ((cxx_dialect > cxx14) && DECL_NAMESPACE_SCOPE_P (alloc_fn))
+  if (DECL_NAMESPACE_SCOPE_P (alloc_fn))
 {
   tree first_arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn)));
   if ((TREE_VALUE (first_arg) == ptr_type_node)
diff --git a/gcc/testsuite/g++.dg/init/pr35878_1.C 
b/gcc/testsuite/g++.dg/init/pr35878_1.C
index e2fc493..7fb3221 100644
--- a/gcc/testsuite/g++.dg/init/pr35878_1.C
+++ b/gcc/testsuite/g++.dg/init/pr35878_1.C
@@ -1,7 +1,7 @@
 // PR c++/35878
 // { dg-do compile }
 // { dg-options "-O2 -std=gnu++11 -fdump-tree-optimized" }
-// { dg-final { scan-tree-dump-times "v_\[0-9]+\\(D\\) \[=!]= 0" 1 "optimized" 
} }
+// { dg-final { scan-tree-dump-not "v_\[0-9]+\\(D\\) \[=!]= 0" "optimized" } }
 
 #include 
 #include 
diff --git a/gcc/testsuite/g++.dg/init/pr35878_4.C 
b/gcc/testsuite/g++.dg/init/pr35878_4.C
new file mode 100644
index 000..bd27565
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/pr35878_4.C
@@ -0,0 +1,23 @@
+// PR c++/35878
+// { dg-do compile }
+// { dg-options "-O2 -std=gnu++11 -fcheck-new -fdump-tree-optimized" }
+// { dg-final { scan-tree-dump-times "v_\[0-9]+\\(D\\) \[=!]= 0" 1 "optimized" 
} }
+
+#include 
+#include 
+
+struct s1{
+  int a;
+  int b;
+  int c;
+};
+
+void f1 (s1 * v, s1&& s)
+{
+   new (v) s1(std::move(s));
+}
+
+void f2 (s1 * v, s1&& s)
+{
+   *v = std::move(s);
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr48695.C 
b/gcc/testsuite/g++.dg/torture/pr48695.C
index 44e6c77..2f2953d 100644
--- a/gcc/testsuite/g++.dg/torture/pr48695.C
+++ b/gcc/testsuite/g++.dg/torture/pr48695.C
@@ -1,4 +1,5 @@
 // { dg-do run }
+/* { dg-options "-fcheck-new" } */
 
 typedef __SIZE_TYPE__ size_t;
 
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C
index 500d8b6..8c94423 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C
@@ -20,6 +20,6 @@ double foo (void)
   return v.a[2];
 }
 
-/* -std=c++17 and above doesn't emit operator new () != NULL, so there is
+/* GCC 8 doesn't emit operator new () != NULL, so there is
nothing to fold anymore.  */
-/* { dg-final { scan-tree-dump "Replaced .* != 0B. with .1" "forwprop1" { 
target c++14_down } } } */
+/* { dg-final { scan-tree-dump-not "Replaced .* != 0B. with .1" "forwprop1" } 
} */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr31146-3.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr31146-3.C
new file mode 100644
index 000..9fb5dc1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr31146-3.C
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fcheck-new -fno-tree-vrp -fdump-tree-forwprop1" } */
+
+#include 
+
+template 
+struct Vec
+{
+  Vec()
+  {
+for (int i=0; i<3; ++i)
+  new (&a[i]) T(0);
+  }
+  T a[3];
+};
+
+double foo (void)
+{
+  Vec v;
+  return v.a[2];
+}
+
+/* GCC 8 emits operator new () != NULL with -fcheck-new. */
+/* { dg-final { scan-tree-dump "Replaced .* != 0B. with .1" "forwprop1" } } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr41428-2.C 
b/gcc/testsuite/g++.dg/tree-ssa/pr41428-2.C
new file mode 100644
index 000..7aff519
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr41428-2.C
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fcheck-new -fdump-tree-ccp1-details" } */
+
+extern "C" void abort (void);
+inline void *operator new (__SIZE_TYPE__, void *__p) throw () { return __p; }
+
+int foo(void)
+{
+  float f = 0;
+  int *i = new (&f) int (1);
+  return *(int *)&f;
+}
+
+/* GCC 8 emits operator new () != NULL with -fcheck-new. */
+/* { dg-final { scan-tree-dump "Folded 

Re: [C++ PATCH] Remove the null check from placement new in all modes

2017-11-13 Thread Ville Voutilainen
On 13 November 2017 at 14:17, Eric Botcazou  wrote:
>> 2017-11-13  Ville Voutilainen  
>>
>> gcc/
>>
>> Remove the null check from placement new in all modes
>> * cp/init.c (build_new_1): Don't do a null check for
>> a namespace-scope non-replaceable placement new
>> in any mode unless -fcheck-new is provided.
>
> Incorrect entry, it should go in gcc/cp/ChangeLog without the cp/ prefix:
>
> * init.c (build_new_1): Don't do a null check for
> a namespace-scope non-replaceable placement new
> in any mode unless -fcheck-new is provided.


Yes, I know. It'll look more like this:

2017-11-13  Ville Voutilainen  

gcc/cp

Remove the null check from placement new in all modes
* init.c (build_new_1): Don't do a null check for
a namespace-scope non-replaceable placement new
in any mode unless -fcheck-new is provided.

testsuite/

Remove the null check from placement new in all modes
* g++.dg/init/pr35878_1.C: Adjust.
* g++.dg/init/pr35878_4.C: New.
* g++.dg/torture/pr48695.C: Adjust.
* g++.dg/tree-ssa/pr31146-2.C: Likewise.
* g++.dg/tree-ssa/pr31146-3.C: New.
* g++.dg/tree-ssa/pr41428-2.C: Likewise.
* g++.dg/tree-ssa/pr41428.C: Adjust.

..except that I won't modify the testsuite's changelog, because we
don't tend to do that.


[v3 PATCH] Implement LWG 2733 and LWG 2759

2017-11-14 Thread Ville Voutilainen
Tested on Linux-x64.

2017-11-14  Ville Voutilainen  

Implement LWG 2733 and LWG 2759
* include/experimental/numeric (gcd): Reject cv-qualified bool.
(lcm): Likewise.
* include/std/numeric (gcd): Likewise.
(lcm): Likewise.
* testsuite/26_numerics/gcd/gcd_neg.cc: Add tests and adjust.
* testsuite/26_numerics/lcm/lcm_neg.cc: Likewise.
diff --git a/libstdc++-v3/include/experimental/numeric 
b/libstdc++-v3/include/experimental/numeric
index c8597fc..6a48c72 100644
--- a/libstdc++-v3/include/experimental/numeric
+++ b/libstdc++-v3/include/experimental/numeric
@@ -57,8 +57,10 @@ inline namespace fundamentals_v2
 {
   static_assert(is_integral<_Mn>::value, "gcd arguments are integers");
   static_assert(is_integral<_Nn>::value, "gcd arguments are integers");
-  static_assert(!is_same<_Mn, bool>::value, "gcd arguments are not bools");
-  static_assert(!is_same<_Nn, bool>::value, "gcd arguments are not bools");
+  static_assert(!is_same::type, bool>::value,
+   "gcd arguments are not bools");
+  static_assert(!is_same::type, bool>::value,
+   "gcd arguments are not bools");
   return std::__detail::__gcd(__m, __n);
 }
 
@@ -69,8 +71,10 @@ inline namespace fundamentals_v2
 {
   static_assert(is_integral<_Mn>::value, "lcm arguments are integers");
   static_assert(is_integral<_Nn>::value, "lcm arguments are integers");
-  static_assert(!is_same<_Mn, bool>::value, "lcm arguments are not bools");
-  static_assert(!is_same<_Nn, bool>::value, "lcm arguments are not bools");
+  static_assert(!is_same::type, bool>::value,
+   "lcm arguments are not bools");
+  static_assert(!is_same::type, bool>::value,
+   "lcm arguments are not bools");
   return std::__detail::__lcm(__m, __n);
 }
 } // namespace fundamentals_v2
diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric
index 2b80419..e3276e4 100644
--- a/libstdc++-v3/include/std/numeric
+++ b/libstdc++-v3/include/std/numeric
@@ -133,8 +133,10 @@ namespace __detail
 {
   static_assert(is_integral<_Mn>::value, "gcd arguments are integers");
   static_assert(is_integral<_Nn>::value, "gcd arguments are integers");
-  static_assert(!is_same<_Mn, bool>::value, "gcd arguments are not bools");
-  static_assert(!is_same<_Nn, bool>::value, "gcd arguments are not bools");
+  static_assert(!is_same::type, bool>::value,
+   "gcd arguments are not bools");
+  static_assert(!is_same::type, bool>::value,
+   "gcd arguments are not bools");
   return __detail::__gcd(__m, __n);
 }
 
@@ -145,8 +147,10 @@ namespace __detail
 {
   static_assert(is_integral<_Mn>::value, "lcm arguments are integers");
   static_assert(is_integral<_Nn>::value, "lcm arguments are integers");
-  static_assert(!is_same<_Mn, bool>::value, "lcm arguments are not bools");
-  static_assert(!is_same<_Nn, bool>::value, "lcm arguments are not bools");
+  static_assert(!is_same::type, bool>::value,
+   "lcm arguments are not bools");
+  static_assert(!is_same::type, bool>::value,
+   "lcm arguments are not bools");
   return __detail::__lcm(__m, __n);
 }
 
diff --git a/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc 
b/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc
index 30524a1b..d5de28f 100644
--- a/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc
+++ b/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc
@@ -26,6 +26,20 @@ test01()
   std::gcd(true, 1);// { dg-error "from here" }
   std::gcd(1, true);// { dg-error "from here" }
   std::gcd(true, true); // { dg-error "from here" }
+  std::gcd(true, 1);// { dg-error "from here" }
+  std::gcd(1, true);// { dg-error "from here" }
+  std::gcd(true, true); // { dg-error "from here" }
+  std::gcd(true, 1);// { dg-error "from here" }
+  std::gcd(1, true);// { dg-error "from here" }
+  std::gcd(true, true); // { dg-error "from here" }
+  std::gcd(true, 1);// { dg-error "from here" }
+  std::gcd(1, true);// { dg-error "from here" }
+  std::gcd(true, true); // { dg-error "from here" }
+  std::gcd(true, 1);// { dg-error "from here" }
+  std::gcd(1, true);// { dg-error "from here" }
+  std::gcd(true, true); // { dg-error "from here" }
   std::gcd(0.1, 1); // { dg-error "from here" }
   std::gcd(1, 0.1);

Re: [v3 PATCH] Implement LWG 2733 and LWG 2759

2017-11-14 Thread Ville Voutilainen
On 14 November 2017 at 19:06, Jonathan Wakely  wrote:
> Both files can use remove_cv_t instead of remove_cv::type (and there's
> no need to std-qualify it in std::gcd).
>
> They could also use is_integral_v and is_same_v but that's
> pre-existing, and less important because there's no 'typename' that
> can be avoided by changing it.

Here's round 2.
diff --git a/libstdc++-v3/include/experimental/numeric 
b/libstdc++-v3/include/experimental/numeric
index c8597fc..f037d8e 100644
--- a/libstdc++-v3/include/experimental/numeric
+++ b/libstdc++-v3/include/experimental/numeric
@@ -55,10 +55,12 @@ inline namespace fundamentals_v2
 constexpr common_type_t<_Mn, _Nn>
 gcd(_Mn __m, _Nn __n)
 {
-  static_assert(is_integral<_Mn>::value, "gcd arguments are integers");
-  static_assert(is_integral<_Nn>::value, "gcd arguments are integers");
-  static_assert(!is_same<_Mn, bool>::value, "gcd arguments are not bools");
-  static_assert(!is_same<_Nn, bool>::value, "gcd arguments are not bools");
+  static_assert(is_integral_v<_Mn>, "gcd arguments are integers");
+  static_assert(is_integral_v<_Nn>, "gcd arguments are integers");
+  static_assert(!is_same_v, bool>,
+   "gcd arguments are not bools");
+  static_assert(!is_same_v, bool>,
+   "gcd arguments are not bools");
   return std::__detail::__gcd(__m, __n);
 }
 
@@ -67,10 +69,12 @@ inline namespace fundamentals_v2
 constexpr common_type_t<_Mn, _Nn>
 lcm(_Mn __m, _Nn __n)
 {
-  static_assert(is_integral<_Mn>::value, "lcm arguments are integers");
-  static_assert(is_integral<_Nn>::value, "lcm arguments are integers");
-  static_assert(!is_same<_Mn, bool>::value, "lcm arguments are not bools");
-  static_assert(!is_same<_Nn, bool>::value, "lcm arguments are not bools");
+  static_assert(is_integral_v<_Mn>, "lcm arguments are integers");
+  static_assert(is_integral_v<_Nn>, "lcm arguments are integers");
+  static_assert(!is_same_v, bool>,
+   "lcm arguments are not bools");
+  static_assert(!is_same_v, bool>,
+   "lcm arguments are not bools");
   return std::__detail::__lcm(__m, __n);
 }
 } // namespace fundamentals_v2
diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric
index 2b80419..a3a447d 100644
--- a/libstdc++-v3/include/std/numeric
+++ b/libstdc++-v3/include/std/numeric
@@ -131,10 +131,12 @@ namespace __detail
 constexpr common_type_t<_Mn, _Nn>
 gcd(_Mn __m, _Nn __n)
 {
-  static_assert(is_integral<_Mn>::value, "gcd arguments are integers");
-  static_assert(is_integral<_Nn>::value, "gcd arguments are integers");
-  static_assert(!is_same<_Mn, bool>::value, "gcd arguments are not bools");
-  static_assert(!is_same<_Nn, bool>::value, "gcd arguments are not bools");
+  static_assert(is_integral_v<_Mn>, "gcd arguments are integers");
+  static_assert(is_integral_v<_Nn>, "gcd arguments are integers");
+  static_assert(!is_same_v, bool>,
+   "gcd arguments are not bools");
+  static_assert(!is_same_v, bool>,
+   "gcd arguments are not bools");
   return __detail::__gcd(__m, __n);
 }
 
@@ -143,10 +145,12 @@ namespace __detail
 constexpr common_type_t<_Mn, _Nn>
 lcm(_Mn __m, _Nn __n)
 {
-  static_assert(is_integral<_Mn>::value, "lcm arguments are integers");
-  static_assert(is_integral<_Nn>::value, "lcm arguments are integers");
-  static_assert(!is_same<_Mn, bool>::value, "lcm arguments are not bools");
-  static_assert(!is_same<_Nn, bool>::value, "lcm arguments are not bools");
+  static_assert(is_integral_v<_Mn>, "lcm arguments are integers");
+  static_assert(is_integral_v<_Nn>, "lcm arguments are integers");
+  static_assert(!is_same_v, bool>,
+   "lcm arguments are not bools");
+  static_assert(!is_same_v, bool>,
+   "lcm arguments are not bools");
   return __detail::__lcm(__m, __n);
 }
 
diff --git a/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc 
b/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc
index 30524a1b..63a8afa 100644
--- a/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc
+++ b/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc
@@ -26,14 +26,29 @@ test01()
   std::gcd(true, 1);// { dg-error "from here" }
   std::gcd(1, true);// { dg-error "from here" }
   std::gcd(true, true); // { dg-error "from here" }
+  std::gcd(true, 1);// { dg-error "from here" }
+  std::gcd(1, true);// { dg-error "from here" }
+  std::gcd(true, true); // { dg-error "from here" }
+  std::gcd(true, 1);// { dg-error "from here" }
+  std::gcd(1, true);// { dg-error "from here" }
+  std::gcd(true, true); // { dg-error "from here" }
+  std::gcd(true, 1);// { dg-error "from here" }
+  std::gcd(1, true);// { dg-error "from here" }
+  std::gcd(true, true); // { dg-error "from here" }
+  std::gcd(

[v3 PATCH] Implement LWG 2353

2017-11-18 Thread Ville Voutilainen
The issue submission talks about ranges that have InputIterators
as their iterator type. Even without any such range types, the added
test more or less shows that it's draconian to require a ForwardIterator
in std::next, since it seems perfectly reasonable to be able to std::next()
an iterator of an istream.

Testing on Linux-PPC64, ok for trunk if the full suite passes?

2017-11-19  Ville Voutilainen  

Implement LWG 2353
* include/bits/stl_iterator_base_funcs.h (next):
Use InputIterator instead of ForwardIterator.
* testsuite/24_iterators/operations/lwg2353.cc: New.
* testsuite/24_iterators/operations/next_neg.cc: Remove.
diff --git a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h 
b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
index 86a93d3..ad84b39 100644
--- a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
+++ b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h
@@ -208,14 +208,13 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
 
 #if __cplusplus >= 201103L
 
-  template
-inline _GLIBCXX17_CONSTEXPR _ForwardIterator
-next(_ForwardIterator __x, typename
-iterator_traits<_ForwardIterator>::difference_type __n = 1)
+  template
+inline _GLIBCXX17_CONSTEXPR _InputIterator
+next(_InputIterator __x, typename
+iterator_traits<_InputIterator>::difference_type __n = 1)
 {
   // concept requirements
-  __glibcxx_function_requires(_ForwardIteratorConcept<
- _ForwardIterator>)
+  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
   std::advance(__x, __n);
   return __x;
 }
diff --git a/libstdc++-v3/testsuite/24_iterators/operations/lwg2353.cc 
b/libstdc++-v3/testsuite/24_iterators/operations/lwg2353.cc
new file mode 100644
index 000..4ce4077
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/operations/lwg2353.cc
@@ -0,0 +1,26 @@
+// { dg-options "-D_GLIBCXX_CONCEPT_CHECKS" }
+// { dg-do run { target c++11 } }
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+template
+auto
+drop(Distance n, InputRange& rng)
+{
+  return std::make_pair(std::next(std::istream_iterator(rng), n),
+   std::istream_iterator()
+   );
+}
+
+int main()
+{
+std::stringstream x("let let there be rock");
+x << std::noskipws;
+auto y = drop(4, x);
+std::string z(y.first, y.second);
+VERIFY(z == "let there be rock");
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/operations/next_neg.cc 
b/libstdc++-v3/testsuite/24_iterators/operations/next_neg.cc
deleted file mode 100644
index f3c20a1..000
--- a/libstdc++-v3/testsuite/24_iterators/operations/next_neg.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (C) 2015-2017 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
-// <http://www.gnu.org/licenses/>.
-
-// { dg-options "-D_GLIBCXX_CONCEPT_CHECKS" }
-// { dg-do compile { target c++11 } }
-
-#include 
-
-struct X {};
-
-namespace std
-{
-  template<>
-struct iterator_traits : iterator_traits
-{
-  using iterator_category = input_iterator_tag;
-  using reference = const X&;
-  using pointer = const X*;
-};
-}
-
-void
-test01()
-{
-  const X array[1] = { };
-  std::next(array);
-  // { dg-error "input_iterator" "" { target *-*-* } 220 }
-}


Re: [v3 PATCH] Implement LWG 2353

2017-11-18 Thread Ville Voutilainen
On 19 November 2017 at 02:40, Ville Voutilainen
 wrote:
> The issue submission talks about ranges that have InputIterators
> as their iterator type. Even without any such range types, the added
> test more or less shows that it's draconian to require a ForwardIterator
> in std::next, since it seems perfectly reasonable to be able to std::next()
> an iterator of an istream.
>
> Testing on Linux-PPC64, ok for trunk if the full suite passes?

The test run is squeaky clean and verified to have run the added test.


[v3 PATCH] Implement LWG 2221, No formatted output operator for nullptr

2017-12-03 Thread Ville Voutilainen
Tested on Linux-x64.

2017-11-14  Ville Voutilainen  

Implement LWG 2221
* include/std/ostream (operator<<(nullptr_t)): New.
* testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc: New.
diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index f7cab03..18011bc 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -245,6 +245,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   operator<<(const void* __p)
   { return _M_insert(__p); }
 
+#if __cplusplus > 201402L
+  __ostream_type&
+  operator<<(nullptr_t)
+  { return *this << "nullptr"; }
+#endif
+
   /**
*  @brief  Extracting from another streambuf.
*  @param  __sb  A pointer to a streambuf
diff --git 
a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc 
b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc
new file mode 100644
index 000..1ffacb3
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/lwg2221.cc
@@ -0,0 +1,9 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+#include 
+
+int main()
+{
+  std::cout << nullptr << std::endl;
+}


[v3 PATCH] PR libstdc++/68430

2017-12-16 Thread Ville Voutilainen
The compiler-powered is_constructible that we have in gcc 8 is powerful
enough to give the right answer to an is_constructible question
that would be hard for a pure-library implementation to get right
in a well-formed fashion. This is just adding a test for it. Tested
on Linux-PPC64, OK for trunk?

2017-12-16  Ville Voutilainen  

PR libstdc++/68430
* testsuite/20_util/is_constructible/68430.cc: New.
diff --git a/libstdc++-v3/testsuite/20_util/is_constructible/68430.cc 
b/libstdc++-v3/testsuite/20_util/is_constructible/68430.cc
new file mode 100644
index 000..3f880b3
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_constructible/68430.cc
@@ -0,0 +1,6 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+template struct Foo { Foo(T = nullptr) {} };
+static_assert(!std::is_constructible>::value, "");


[v3 PATCH] Make optional conditionally trivially_{copy,move}_{constructible,assignable}

2017-12-25 Thread Ville Voutilainen
In the midst of the holiday season, the king and ruler of all elves, otherwise
known as The Elf, was told by little elves that users are complaining how
stlstl and libc++ make optional's copy and move operations conditionally
trivial, but libstdc++ doesn't. This made The Elf fairly angry, and he spoke
"this will not stand".

Tested on Linux-PPC64. The change is an ABI break due to changing
optional to a trivially copyable type. It's perhaps
better to get that ABI break in now rather than later.

So here you go (ho ho ho):

2017-12-25  Ville Voutilainen  

Make optional conditionally
trivially_{copy,move}_{constructible,assignable}
* include/std/optional (_Optional_payload): Fix the comment in
the class head and turn into a primary and one specialization.
(_Optional_payload::_M_engaged): Strike the NSDMI.
(_Optional_payload<_Tp, false>::operator=(const _Optional_payload&)):
New.
(_Optional_payload<_Tp, false>::operator=(_Optional_payload&&)):
Likewise.
(_Optional_payload<_Tp, false>::_M_get): Likewise.
(_Optional_payload<_Tp, false>::_M_reset): Likewise.
(_Optional_base_impl): Likewise.
(_Optional_base): Turn into a primary and three specializations.
(optional(nullopt)): Change the base init.
* testsuite/20_util/optional/assignment/8.cc: New.
* testsuite/20_util/optional/cons/trivial.cc: Likewise.
* testsuite/20_util/optional/cons/value_neg.cc: Adjust.
diff --git a/libstdc++-v3/include/std/optional 
b/libstdc++-v3/include/std/optional
index e017eed..9d1e625 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -100,15 +100,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Payload for constexpr optionals.
   template ::value
- && is_trivially_move_constructible<_Tp>::value,
-   bool /*_ShouldProvideDestructor*/ =
+   bool /*_HasTrivialDestructor*/ =
  is_trivially_destructible<_Tp>::value>
 struct _Optional_payload
 {
   constexpr _Optional_payload()
-   : _M_empty() {}
+   : _M_empty(), _M_engaged(false) {}
 
   template
   constexpr _Optional_payload(in_place_t, _Args&&... __args)
@@ -131,7 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {}
 
   constexpr _Optional_payload(__ctor_tag)
-   : _M_empty()
+   : _M_empty(), _M_engaged(false)
   {}
 
   constexpr _Optional_payload(__ctor_tag, _Tp&& __other)
@@ -161,12 +158,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _Empty_byte _M_empty;
   _Stored_type _M_payload;
   };
-  bool _M_engaged = false;
+  bool _M_engaged;
 };
 
-  // Payload for non-constexpr optionals with non-trivial destructor.
+  // Payload for optionals with non-trivial destructor.
   template 
-struct _Optional_payload<_Tp, false, false>
+struct _Optional_payload<_Tp, false>
 {
   constexpr _Optional_payload()
: _M_empty() {}
@@ -203,6 +200,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  this->_M_construct(std::move(__other._M_payload));
   }
 
+  _Optional_payload&
+  operator=(const _Optional_payload& __other)
+  {
+if (this->_M_engaged && __other._M_engaged)
+  this->_M_get() = __other._M_get();
+else
+ {
+   if (__other._M_engaged)
+ this->_M_construct(__other._M_get());
+   else
+ this->_M_reset();
+ }
+
+return *this;
+  }
+
+  _Optional_payload&
+  operator=(_Optional_payload&& __other)
+  noexcept(__and_,
+ is_nothrow_move_assignable<_Tp>>())
+  {
+   if (this->_M_engaged && __other._M_engaged)
+ this->_M_get() = std::move(__other._M_get());
+   else
+ {
+   if (__other._M_engaged)
+ this->_M_construct(std::move(__other._M_get()));
+   else
+ this->_M_reset();
+ }
+   return *this;
+  }
+
   using _Stored_type = remove_const_t<_Tp>;
   struct _Empty_byte { };
   union {
@@ -226,95 +256,86 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _Stored_type(std::forward<_Args>(__args)...);
   this->_M_engaged = true;
 }
-};
-
-  // Payload for non-constexpr optionals with trivial destructor.
-  template 
-struct _Optional_payload<_Tp, false, true>
-{
-  constexpr _Optional_payload()
-   : _M_empty() {}
-
-  template 
-  constexpr _Optional_payload(in_place_t, _Args&&... __args)
-   : _M_payload(std::forward<_Args>(__args)...),
- _M_engaged(true) {}
-
-  template
-  constexpr _Optional_payload(std::initializer_list<_Up> __il,
- _Args&&... __args)
-   : _M_payload(__il, std::forward<_

[v3 PATCH] Protect optional's deduction guide with the feature macro

2018-01-03 Thread Ville Voutilainen
Tested partially on Linux-x64, finishing testing the full suite on
Linux-PPC64. Ok for trunk?

2018-01-03  Ville Voutilainen  

Protect optional's deduction guide with the feature macro
* include/std/optional: Use the feature macro.
diff --git a/libstdc++-v3/include/std/optional 
b/libstdc++-v3/include/std/optional
index e017eed..f7c72b5 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -1038,7 +1038,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// @}
 
+#if __cpp_deduction_guides >= 201606
   template  optional(_Tp) -> optional<_Tp>;
+#endif
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std


Re: [C++ PATCH] Do not warn about zero-as-null when NULL is used.

2018-05-25 Thread Ville Voutilainen
On 25 May 2018 at 20:27, Jason Merrill  wrote:
> On Thu, May 24, 2018 at 8:04 PM, Ville Voutilainen
>  wrote:
>> I smacked my head against conversion_null_warnings for a while,
>> and then I realized that we could just stop convert_like_real from
>> changing the node type for null_node.
>
> Won't that sometimes mean that the result has the wrong type?  If we
> convert NULL to short, we want the result to have type short.

None of our tests revealed any regressions with the change; the change passes
the full suite. And apparently the removed code in convert_like_real doesn't
affect that; implicit and explicit conversions from NULL to short still convert
to short, and code like auto x = NULL; still converts to unsigned long.


Re: [C++ PATCH] Do not warn about zero-as-null when NULL is used.

2018-05-25 Thread Ville Voutilainen
On 25 May 2018 at 20:38, Ville Voutilainen  wrote:
> On 25 May 2018 at 20:27, Jason Merrill  wrote:
>> On Thu, May 24, 2018 at 8:04 PM, Ville Voutilainen
>>  wrote:
>>> I smacked my head against conversion_null_warnings for a while,
>>> and then I realized that we could just stop convert_like_real from
>>> changing the node type for null_node.
>>
>> Won't that sometimes mean that the result has the wrong type?  If we
>> convert NULL to short, we want the result to have type short.
>
> None of our tests revealed any regressions with the change; the change passes
> the full suite. And apparently the removed code in convert_like_real doesn't
> affect that; implicit and explicit conversions from NULL to short still 
> convert
> to short, and code like auto x = NULL; still converts to unsigned long.

As far as I can see, cp_convert_to_pointer does convert NULL to the "right" kind
of integer constant, it's just that convert_like_real doesn't do it
earlier. The earlier
conversion caused the inability to diagnose the conversion properly in
cp_convert_to_pointer,
but that earlier conversion doesn't seem to have other effects.


Re: Simplify _Rb_tree instantiation

2018-05-25 Thread Ville Voutilainen
On 25 May 2018 at 19:50, François Dumont  wrote:
> Hi
>
> As we are at working on associative containers I'd like to propose this last
> patch to remove the copy constructible constraint on the _Compare functor
> when it is supposed to be default constructed.
>
> This way the _Compare is built directly at its final place.

Why is this patch removing _Compare() calls? That changes the initialization
of _Compare from value-initialization to default-initialization, which
is a breaking change.


Re: Simplify _Rb_tree instantiation

2018-05-25 Thread Ville Voutilainen
On 25 May 2018 at 22:16, Jonathan Wakely  wrote:
>> Why is this patch removing _Compare() calls? That changes the
>> initialization
>> of _Compare from value-initialization to default-initialization, which
>> is a breaking change.
>
>
> The _Rb_tree_key_compare base class will still value-initialize it:
>
>  _Rb_tree_key_compare()
>  _GLIBCXX_NOEXCEPT_IF(
> is_nothrow_default_constructible<_Key_compare>::value)
>  : _M_key_compare()
>  { }

Okay, no problem then.


  1   2   3   4   5   6   7   >