Re: [PATCH] c++/contracts: ICE in C++ Contracts with '-fno-exceptions' [PR 110159]

2024-07-16 Thread Nina Dinka Ranns
On Tue, 16 Jul 2024 at 15:55, Jason Merrill  wrote:

> On 7/16/24 5:03 AM, Nina Dinka Ranns wrote:
> > Hello,
> >
> > We currently only initialise terminate_fn if exceptions are enabled.
> > However, contract handling requires terminate_fn when building the
> > contract as a contract failure may result in std::terminate call
> > regardless of whether the exceptions are enabled. Added possible
> > initialisation of terminate_fn if contracts are enabled. Minor
> refactoring
> > of the init_exception_processing to reuse the terminate_fn
> initialisation.
> >
> > Tested on x86_64-pc-linux-gnu.
> >
> > Patch attached to the email in hope of it being a workable solution for
> > my email client.
> >
> > "OK for trunk?" :)
>
> git gcc-style:


> === ERROR type #1: dot, space, space, end of comment (1 error(s)) ===
> gcc/cp/except.cc:46:33:  handling and contract handling.█*/
>
> === ERROR type #2: there should be exactly one space between function
> name and parenthesis (3 error(s)) ===
> gcc/cp/cp-tree.h:7197:31:extern void init_terminate_fn  (void);
> gcc/cp/decl.cc:5176:21:init_terminate_fn();
> gcc/cp/except.cc:76:19:  init_terminate_fn();
>
> Note that gcc-style has frequent false positives, such as the cp-tree.h
> "error" which is actually fine.  But the others should be corrected.
>

Applied all the changes except the `gcc/cp/cp-tree.h:7197:31` one
New patch attached.

Best,
Nina


>
> Jason
>
>
From 98a0d5341289e62d58be91ef38b4e9910e4cd3a7 Mon Sep 17 00:00:00 2001
From: Nina Ranns 
Date: Thu, 11 Jul 2024 17:47:34 +0100
Subject: [PATCH] c++/contracts: ICE in C++ Contracts with '-fno-exceptions'
 [PR 110159]

We currently only initialise terminate_fn if exceptions are enabled.
However, contract handling requires terminate_fn when building the
contract because a contract failure may result in std::terminate call
regardless of whether the exceptions are enabled. Refactored
init_exception_processing to extract the initialisation of
terminate_fn. New function init_terminate_fn added that initialises
terminate_fn if it hasn't already been initialised. Call to terminate_fn
added in cxx_init_decl_processing if contracts are enabled.

	PR c++/110159

gcc/cp/ChangeLog:

	* cp-tree.h (init_terminate_fn): Declaration of a new function.
	* decl.cc (cxx_init_decl_processing): If contracts are enabled,
	call init_terminate_fn.
	* except.cc (init_exception_processing): Function refactored to
	call init_terminate_fn.
	(init_terminate_fn): Added new function that initializes
	terminate_fn if	it hasn't already been initialised.

gcc/testsuite/ChangeLog:

	* g++.dg/contracts/pr110159.C: New test.

Signed-off-by: Nina Ranns 
---
 gcc/cp/cp-tree.h  |  1 +
 gcc/cp/decl.cc|  3 +++
 gcc/cp/except.cc  | 23 +++
 gcc/testsuite/g++.dg/contracts/pr110159.C | 27 +++
 4 files changed, 50 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/contracts/pr110159.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f270b0b1077..c394b52c0d5 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7202,6 +7202,7 @@ extern void qualified_name_lookup_error		(tree, tree, tree,
 		 location_t);
 
 /* in except.cc */
+extern void init_terminate_fn			(void);
 extern void init_exception_processing		(void);
 extern tree expand_start_catch_block		(tree);
 extern void expand_end_catch_block		(void);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index edf4c155bf7..73eae9ddd1c 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -5167,6 +5167,9 @@ cxx_init_decl_processing (void)
   if (flag_exceptions)
 init_exception_processing ();
 
+  if (flag_contracts)
+init_terminate_fn ();
+
   if (modules_p ())
 init_modules (parse_in);
 
diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc
index 1eb3ba53b4b..3c69ab69502 100644
--- a/gcc/cp/except.cc
+++ b/gcc/cp/except.cc
@@ -42,15 +42,17 @@ static tree wrap_cleanups_r (tree *, int *, void *);
 static bool is_admissible_throw_operand_or_catch_parameter (tree, bool,
 			tsubst_flags_t);
 
-/* Sets up all the global eh stuff that needs to be initialized at the
-   start of compilation.  */
+/* Initializes the node to std::terminate, which is used in exception
+  handling and contract handling.  */
 
 void
-init_exception_processing (void)
+init_terminate_fn (void)
 {
+  if (terminate_fn)
+return;
+
   tree tmp;
 
-  /* void std::terminate (); */
   push_nested_namespace (std_node);
   tmp = build_function_type_list (void_type_node, NULL_TREE);
   terminate_fn = build_cp_library_fn_ptr ("terminate", tmp,
@@ -60,6 +62,19 @@ init_exception_processing (void)
 		   && TREE_NOTHROW (terminate_fn));
   pop_nested_namespace (std_node);
 
+}
+
+/* Sets up all the glob

Re: [PATCH] c++/contracts: ICE in C++ Contracts with '-fno-exceptions' [PR 110159]

2024-07-16 Thread Nina Dinka Ranns
It would help if I attached the patch

Apologies,
Nina

On Tue, 16 Jul 2024 at 10:03, Nina Dinka Ranns 
wrote:

> Hello,
>
> We currently only initialise terminate_fn if exceptions are enabled.
> However, contract handling requires terminate_fn when building the
> contract as a contract failure may result in std::terminate call
> regardless of whether the exceptions are enabled. Added possible
> initialisation of terminate_fn if contracts are enabled. Minor refactoring
> of the init_exception_processing to reuse the terminate_fn initialisation.
>
> Tested on x86_64-pc-linux-gnu.
>
> Patch attached to the email in hope of it being a workable solution for my
> email client.
>
> "OK for trunk?" :)
>
> Best,
> Nina
>
From 336d723a384f4413610e2e95b0588e7fbb235e5a Mon Sep 17 00:00:00 2001
From: Nina Ranns 
Date: Thu, 11 Jul 2024 17:47:34 +0100
Subject: [PATCH] c++/contracts: ICE in C++ Contracts with '-fno-exceptions'
 [PR 110159]

We currently only initialise terminate_fn if exceptions are enabled.
However, contract handling requires terminate_fn when building the
contract because a contract failure may result in std::terminate call
regardless of whether the exceptions are enabled. Refactored
init_exception_processing to extract the initialisation of
terminate_fn. New function init_terminate_fn added that initialises
terminate_fn if it hasn't already been initialised. Call to terminate_fn
added in cxx_init_decl_processing if contracts are enabled.

	PR c++/110159

gcc/cp/ChangeLog:

	* cp-tree.h (init_terminate_fn): Declaration of a new function.
	* decl.cc (cxx_init_decl_processing): If contracts are enabled,
	call init_terminate_fn.
	* except.cc (init_exception_processing): Function refactored to
	call init_terminate_fn.
	(init_terminate_fn): Added new function that initializes
	terminate_fn if	it hasn't already been initialised.

gcc/testsuite/ChangeLog:

	* g++.dg/contracts/pr110159.C: New test.

Signed-off-by: Nina Ranns 
---
 gcc/cp/cp-tree.h  |  1 +
 gcc/cp/decl.cc|  3 +++
 gcc/cp/except.cc  | 23 +++
 gcc/testsuite/g++.dg/contracts/pr110159.C | 27 +++
 4 files changed, 50 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/contracts/pr110159.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f270b0b1077..7f9791a64d0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7202,6 +7202,7 @@ extern void qualified_name_lookup_error		(tree, tree, tree,
 		 location_t);
 
 /* in except.cc */
+extern void init_terminate_fn		(void);
 extern void init_exception_processing		(void);
 extern tree expand_start_catch_block		(tree);
 extern void expand_end_catch_block		(void);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index edf4c155bf7..7ff873e229e 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -5167,6 +5167,9 @@ cxx_init_decl_processing (void)
   if (flag_exceptions)
 init_exception_processing ();
 
+  if (flag_contracts)
+init_terminate_fn();
+
   if (modules_p ())
 init_modules (parse_in);
 
diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc
index 1eb3ba53b4b..87f06bd1663 100644
--- a/gcc/cp/except.cc
+++ b/gcc/cp/except.cc
@@ -42,15 +42,17 @@ static tree wrap_cleanups_r (tree *, int *, void *);
 static bool is_admissible_throw_operand_or_catch_parameter (tree, bool,
 			tsubst_flags_t);
 
-/* Sets up all the global eh stuff that needs to be initialized at the
-   start of compilation.  */
+/* Initializes the node to std::terminate, which is used in exception
+  handling and contract handling. */
 
 void
-init_exception_processing (void)
+init_terminate_fn (void)
 {
+  if (terminate_fn)
+return;
+
   tree tmp;
 
-  /* void std::terminate (); */
   push_nested_namespace (std_node);
   tmp = build_function_type_list (void_type_node, NULL_TREE);
   terminate_fn = build_cp_library_fn_ptr ("terminate", tmp,
@@ -60,6 +62,19 @@ init_exception_processing (void)
 		   && TREE_NOTHROW (terminate_fn));
   pop_nested_namespace (std_node);
 
+}
+
+/* Sets up all the global eh stuff that needs to be initialized at the
+   start of compilation.  */
+
+void
+init_exception_processing (void)
+{
+  tree tmp;
+
+  /* void std::terminate (); */
+  init_terminate_fn();
+
   /* void __cxa_call_unexpected(void *); */
   tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
   call_unexpected_fn
diff --git a/gcc/testsuite/g++.dg/contracts/pr110159.C b/gcc/testsuite/g++.dg/contracts/pr110159.C
new file mode 100644
index 000..614b466b1a3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/pr110159.C
@@ -0,0 +1,27 @@
+// check that contracts can be handled even when exceptions are disabled
+// { dg-do run }
+// { dg-options "-std=c++2a -fcontracts -fno-exceptions " }
+// { dg-output "contract violation in function f at .* a<5" }
+

[PATCH] c++/contracts: ICE in C++ Contracts with '-fno-exceptions' [PR 110159]

2024-07-16 Thread Nina Dinka Ranns
Hello,

We currently only initialise terminate_fn if exceptions are enabled.
However, contract handling requires terminate_fn when building the
contract as a contract failure may result in std::terminate call
regardless of whether the exceptions are enabled. Added possible
initialisation of terminate_fn if contracts are enabled. Minor refactoring
of the init_exception_processing to reuse the terminate_fn initialisation.

Tested on x86_64-pc-linux-gnu.

Patch attached to the email in hope of it being a workable solution for my
email client.

"OK for trunk?" :)

Best,
Nina


Re: [PATCH] c++, contracts: Fix ICE in create_tmp_var [PR113968]

2024-07-10 Thread Nina Dinka Ranns
On Tue, 9 Jul 2024 at 22:50, Jason Merrill  wrote:

> On 7/9/24 6:41 AM, Nina Dinka Ranns wrote:
> > On Mon, 8 Jul 2024 at 16:01, Jason Merrill  > <mailto:ja...@redhat.com>> wrote:
> >
> >     On 7/8/24 7:47 AM, Nina Dinka Ranns wrote:
> >  > HI Jason,
> >  >
> >  > On Fri, 5 Jul 2024 at 17:31, Jason Merrill  > <mailto:ja...@redhat.com>> wrote:
> >  >>
> >  >> On 7/5/24 10:25 AM, Nina Dinka Ranns wrote:
> >  >>> Certain places in contract parsing currently do not check for
> > errors.
> >  >>> This results in contracts
> >  >>> with embedded errors which eventually confuse gimplify. Checks
> for
> >  >>> errors added in
> >  >>> grok_contract() and cp_parser_contract_attribute_spec() to exit
> > early
> >  >>> if an error is encountered.
> >  >>
> >  >> Thanks for the patch!
> >  >>
> >  >>> Tested on x86_64-pc-linux-gnu
> >  >>> ---
> >  >>>
> >  >>>   PR c++/113968
> >  >>>
> >  >>> gcc/cp/ChangeLog:
> >  >>>
> >  >>>   * contracts.cc (grok_contract): Check for
> > error_mark_node early
> >  >>> exit
> >  >>
> >  >> These hunks are OK.
> >  >>
> >  >>>   * parser.cc (cp_parser_contract_attribute_spec):
> > Check for
> >  >>> error_mark_node early exit
> >  >>
> >  >> This seems redundant, since finish_contract_attribute already
> > checks for
> >  >> error_mark_node and we're returning its result unchanged.
> >  >
> >  > good catch, removed.
> >  >
> >  >>
> >  >> Also, the convention is for wrapped lines in ChangeLog entries
> > to line
> >  >> up with the *, and to finish sentences with a period.
> >  >
> >  > done.
> >  >
> >  > Tests re-run on x86_64-pc-linux-gnu , no change.
> >
> > This looks good, but the patch doesn't apply due to word wrap.  To
> > avoid
> > that, I tend to use git send-email; sending the patch as an
> attachment
> > is also OK.  Or see
> >
> > https://www.kernel.org/doc/html/latest/process/email-clients.html
> > <https://www.kernel.org/doc/html/latest/process/email-clients.html>
> >
> > for tips on getting various email clients to leave patches alone.
> >
> >
> > ack, thank you for your patience.
> > This time, patch attached to the email.
>
> It looks like the attached patch reverted to older ChangeLog entries,
> without the periods, and with the dropped parser.cc change?
>
> git gcc-verify also complains
>
> > ERR: line should start with a tab: "* contracts.cc
> (grok_contract): Check for error_mark_node early"
> > ERR: line should start with a tab: "  exit"
> > ERR: line should start with a tab: "* parser.cc
> (cp_parser_contract_attribute_spec): Check for"
> > ERR: line should start with a tab: "  error_mark_node early exit"
> > ERR: line should start with a tab: "*
> g++.dg/contracts/pr113968.C: New test."
> > ERR: PR 113968 in subject but not in changelog: "c++, contracts: Fix ICE
> in create_tmp_var [PR113968]"
>
> Jason
>
>
Apologies. I must have copy pasted something wrong. I've setup gcc-verify
and that passes.
Let's try again. Patch attached.

Thank you,
Nina
From f529ffd1c3abb2229ff715e5de123a0bfed9ff2a Mon Sep 17 00:00:00 2001
From: Nina Ranns 
Date: Thu, 4 Jul 2024 17:08:58 +0100
Subject: [PATCH] c++, contracts: Fix ICE in create_tmp_var [PR113968]

During contract parsing, in grok_contract(), we proceed even if the
condition contains errors. This results in contracts with embedded errors
which eventually confuse gimplify. Checks for errors have been added in
grok_contract() to exit early if an error is encountered.

	PR c++/113968

gcc/cp/ChangeLog:

	* contracts.cc (grok_contract): Check for error_mark_node early
	exit.

gcc/testsuite/ChangeLog:

	* g++.dg/contracts/pr113968.C: New test.

Signed-off-by: Nina Ranns 
---
 gcc/cp/contracts.cc   |  7 ++
 gcc/testsuite/g++.dg/contracts/pr113968.C | 29 +++
 2 files changed, 36 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/contracts/pr113968.C


Re: [PATCH] c++, contracts: Fix ICE in create_tmp_var [PR113968]

2024-07-09 Thread Nina Dinka Ranns
Hi Jason,


On Mon, 8 Jul 2024 at 16:01, Jason Merrill  wrote:

> On 7/8/24 7:47 AM, Nina Dinka Ranns wrote:
> > HI Jason,
> >
> > On Fri, 5 Jul 2024 at 17:31, Jason Merrill  wrote:
> >>
> >> On 7/5/24 10:25 AM, Nina Dinka Ranns wrote:
> >>> Certain places in contract parsing currently do not check for errors.
> >>> This results in contracts
> >>> with embedded errors which eventually confuse gimplify. Checks for
> >>> errors added in
> >>> grok_contract() and cp_parser_contract_attribute_spec() to exit early
> >>> if an error is encountered.
> >>
> >> Thanks for the patch!
> >>
> >>> Tested on x86_64-pc-linux-gnu
> >>> ---
> >>>
> >>>   PR c++/113968
> >>>
> >>> gcc/cp/ChangeLog:
> >>>
> >>>   * contracts.cc (grok_contract): Check for error_mark_node
> early
> >>> exit
> >>
> >> These hunks are OK.
> >>
> >>>   * parser.cc (cp_parser_contract_attribute_spec): Check for
> >>> error_mark_node early exit
> >>
> >> This seems redundant, since finish_contract_attribute already checks for
> >> error_mark_node and we're returning its result unchanged.
> >
> > good catch, removed.
> >
> >>
> >> Also, the convention is for wrapped lines in ChangeLog entries to line
> >> up with the *, and to finish sentences with a period.
> >
> > done.
> >
> > Tests re-run on x86_64-pc-linux-gnu , no change.
>
> This looks good, but the patch doesn't apply due to word wrap.  To avoid
> that, I tend to use git send-email; sending the patch as an attachment
> is also OK.  Or see
>
> https://www.kernel.org/doc/html/latest/process/email-clients.html
>
> for tips on getting various email clients to leave patches alone.
>

ack, thank you for your patience.
This time, patch attached to the email.

Best,
Nina
From 2e80ff94b7920f16239d5953c9609fc5f142c1fb Mon Sep 17 00:00:00 2001
From: Nina Ranns 
Date: Thu, 4 Jul 2024 17:08:58 +0100
Subject: [PATCH] c++, contracts: Fix ICE in create_tmp_var [PR113968]

Certain places in contract parsing currently do not check for errors.
This results in contracts with embedded errors which eventually
confuse  gimplify. Checks for errors added in grok_contract() and
cp_parser_contract_attribute_spec() to exit early if an error is
encountered.

gcc/cp/ChangeLog:

* contracts.cc (grok_contract): Check for error_mark_node early
  exit
* parser.cc (cp_parser_contract_attribute_spec): Check for
  error_mark_node early exit

gcc/testsuite/ChangeLog:

* g++.dg/contracts/pr113968.C: New test.

Signed-off-by: Nina Ranns 
---
 gcc/cp/contracts.cc   |  7 ++
 gcc/testsuite/g++.dg/contracts/pr113968.C | 29 +++
 2 files changed, 36 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/contracts/pr113968.C

diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
index 634e3cf4fa9..a7d0fdacf6e 100644
--- a/gcc/cp/contracts.cc
+++ b/gcc/cp/contracts.cc
@@ -750,6 +750,9 @@ tree
 grok_contract (tree attribute, tree mode, tree result, cp_expr condition,
 	   location_t loc)
 {
+  if (condition == error_mark_node)
+return error_mark_node;
+
   tree_code code;
   if (is_attribute_p ("assert", attribute))
 code = ASSERTION_STMT;
@@ -785,6 +788,10 @@ grok_contract (tree attribute, tree mode, tree result, cp_expr condition,
 
   /* The condition is converted to bool.  */
   condition = finish_contract_condition (condition);
+
+  if (condition == error_mark_node)
+return error_mark_node;
+
   CONTRACT_CONDITION (contract) = condition;
 
   return contract;
diff --git a/gcc/testsuite/g++.dg/contracts/pr113968.C b/gcc/testsuite/g++.dg/contracts/pr113968.C
new file mode 100644
index 000..fbaad1c930d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/pr113968.C
@@ -0,0 +1,29 @@
+// check that an invalid contract condition doesn't cause an ICE
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts " }
+
+struct A
+{
+  A (A&);
+};
+struct S
+{
+  void f(A a)
+[[ pre : a]] // { dg-error "could not convert" }
+[[ pre : a.b]]// { dg-error "has no member" }
+{
+
+}
+};
+void f(A a)
+  [[ pre : a]] // { dg-error "could not convert" }
+  [[ pre : a.b]]// { dg-error "has no member" }
+  {
+[[ assert : a ]]; // { dg-error "could not convert" }
+[[ assert : a.b ]];// { dg-error "has no member" }
+  }
+
+int
+main ()
+{
+}
-- 
2.45.2



Re: [PATCH] c++, contracts: Fix ICE in create_tmp_var [PR113968]

2024-07-08 Thread Nina Dinka Ranns
HI Jason,

On Fri, 5 Jul 2024 at 17:31, Jason Merrill  wrote:
>
> On 7/5/24 10:25 AM, Nina Dinka Ranns wrote:
> > Certain places in contract parsing currently do not check for errors.
> > This results in contracts
> > with embedded errors which eventually confuse gimplify. Checks for
> > errors added in
> > grok_contract() and cp_parser_contract_attribute_spec() to exit early
> > if an error is encountered.
>
> Thanks for the patch!
>
> > Tested on x86_64-pc-linux-gnu
> > ---
> >
> >  PR c++/113968
> >
> > gcc/cp/ChangeLog:
> >
> >  * contracts.cc (grok_contract): Check for error_mark_node early
> >exit
>
> These hunks are OK.
>
> >  * parser.cc (cp_parser_contract_attribute_spec): Check for
> >error_mark_node early exit
>
> This seems redundant, since finish_contract_attribute already checks for
> error_mark_node and we're returning its result unchanged.

good catch, removed.

>
> Also, the convention is for wrapped lines in ChangeLog entries to line
> up with the *, and to finish sentences with a period.

done.

Tests re-run on x86_64-pc-linux-gnu , no change.


---
PR C++/113968

gcc/cp/ChangeLog:

* contracts.cc (grok_contract):  Check for error_mark_node early
exit.

gcc/testsuite/ChangeLog:

* g++.dg/contracts/pr113968.C: New test.

Signed-off-by: Nina Ranns 

---

 gcc/cp/contracts.cc   |  7 ++
 gcc/testsuite/g++.dg/contracts/pr113968.C | 29 +++
 2 files changed, 36 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/contracts/pr113968.C

diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
index 634e3cf4fa9..a7d0fdacf6e 100644
--- a/gcc/cp/contracts.cc
+++ b/gcc/cp/contracts.cc
@@ -750,6 +750,9 @@ tree
 grok_contract (tree attribute, tree mode, tree result, cp_expr condition,
 location_t loc)
 {
+  if (condition == error_mark_node)
+return error_mark_node;
+
   tree_code code;
   if (is_attribute_p ("assert", attribute))
 code = ASSERTION_STMT;
@@ -785,6 +788,10 @@ grok_contract (tree attribute, tree mode, tree
result, cp_expr condition,

   /* The condition is converted to bool.  */
   condition = finish_contract_condition (condition);
+
+  if (condition == error_mark_node)
+return error_mark_node;
+
   CONTRACT_CONDITION (contract) = condition;

   return contract;
diff --git a/gcc/testsuite/g++.dg/contracts/pr113968.C
b/gcc/testsuite/g++.dg/contracts/pr113968.C
new file mode 100644
index 000..fbaad1c930d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/pr113968.C
@@ -0,0 +1,29 @@
+// check that an invalid contract condition doesn't cause an ICE
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts " }
+
+struct A
+{
+  A (A&);
+};
+struct S
+{
+  void f(A a)
+[[ pre : a]] // { dg-error "could not convert" }
+[[ pre : a.b]]// { dg-error "has no member" }
+{
+
+}
+};
+void f(A a)
+  [[ pre : a]] // { dg-error "could not convert" }
+  [[ pre : a.b]]// { dg-error "has no member" }
+  {
+[[ assert : a ]]; // { dg-error "could not convert" }
+[[ assert : a.b ]];// { dg-error "has no member" }
+  }
+
+int
+main ()
+{
+}
--
2.45.2


[PATCH] c++, contracts: Fix ICE in create_tmp_var [PR113968]

2024-07-05 Thread Nina Dinka Ranns
Certain places in contract parsing currently do not check for errors.
This results in contracts
with embedded errors which eventually confuse gimplify. Checks for
errors added in
grok_contract() and cp_parser_contract_attribute_spec() to exit early
if an error is encountered.

Tested on x86_64-pc-linux-gnu
---

PR c++/113968

gcc/cp/ChangeLog:

* contracts.cc (grok_contract): Check for error_mark_node early
  exit
* parser.cc (cp_parser_contract_attribute_spec): Check for
  error_mark_node early exit

gcc/testsuite/ChangeLog:

* g++.dg/contracts/pr113968.C: New test.

Signed-off-by: Nina Ranns 


---
 gcc/cp/contracts.cc   |  7 ++
 gcc/cp/parser.cc  |  3 +++
 gcc/testsuite/g++.dg/contracts/pr113968.C | 29 +++
 3 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/contracts/pr113968.C

diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
index 634e3cf4fa9..a7d0fdacf6e 100644
--- a/gcc/cp/contracts.cc
+++ b/gcc/cp/contracts.cc
@@ -750,6 +750,9 @@ tree
 grok_contract (tree attribute, tree mode, tree result, cp_expr condition,
location_t loc)
 {
+  if (condition == error_mark_node)
+return error_mark_node;
+
   tree_code code;
   if (is_attribute_p ("assert", attribute))
 code = ASSERTION_STMT;
@@ -785,6 +788,10 @@ grok_contract (tree attribute, tree mode, tree
result, cp_expr condition,

   /* The condition is converted to bool.  */
   condition = finish_contract_condition (condition);
+
+  if (condition == error_mark_node)
+return error_mark_node;
+
   CONTRACT_CONDITION (contract) = condition;

   return contract;
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 31ae9c2fb54..22c5e760aee 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -30835,6 +30835,9 @@ cp_parser_contract_attribute_spec (cp_parser
*parser, tree attribute)
   return error_mark_node;
 }

+  if (contract == error_mark_node)
+return error_mark_node;
+
   return finish_contract_attribute (attribute, contract);
 }

diff --git a/gcc/testsuite/g++.dg/contracts/pr113968.C
b/gcc/testsuite/g++.dg/contracts/pr113968.C
new file mode 100644
index 000..fbaad1c930d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/contracts/pr113968.C
@@ -0,0 +1,29 @@
+// check that an invalid contract condition doesn't cause an ICE
+// { dg-do compile }
+// { dg-options "-std=c++2a -fcontracts " }
+
+struct A
+{
+  A (A&);
+};
+struct S
+{
+  void f(A a)
+[[ pre : a]] // { dg-error "could not convert" }
+[[ pre : a.b]]// { dg-error "has no member" }
+{
+
+}
+};
+void f(A a)
+  [[ pre : a]] // { dg-error "could not convert" }
+  [[ pre : a.b]]// { dg-error "has no member" }
+  {
+[[ assert : a ]]; // { dg-error "could not convert" }
+[[ assert : a.b ]];// { dg-error "has no member" }
+  }
+
+int
+main ()
+{
+}
-- 
2.45.2


Re: PR C++/63149

2019-06-05 Thread Nina Dinka Ranns
On Wed, 5 Jun 2019 at 19:19, Jason Merrill  wrote:

> On 6/5/19 1:29 PM, Nina Dinka Ranns wrote:
> > Ack. Amended change log is below. Changes are :
> > * changed C++ -> c++
> > * fixed the name of added test
> >
> > There are no changes in the diff, but I attached it to this e-mail for
> > reference.
>
> Applied, thanks!
>
> For future reference it's also customary to add a bit of discussion of
> the rationale for the patch.  Also, please include the word "PATCH" on
> the subject line.


Noted.
Thank you,
Nina


>
> Jason
>


Re: PR C++/63149

2019-06-05 Thread Nina Dinka Ranns
Ack. Amended change log is below. Changes are :
* changed C++ -> c++
* fixed the name of added test

There are no changes in the diff, but I attached it to this e-mail for
reference.

Thanks,
Nina

2019-06-04  Nina Dinka Ranns  
gcc/cp

PR c++/63149
* pt.c (listify_autos): Use non cv qualified auto_node in
std::initializer_list.

testsuite/

PR c++/63149
* g++.dg/cpp0x/initlist-deduce2.C: New test.





On Wed, 5 Jun 2019 at 13:59, Marek Polacek  wrote:
>
> On Wed, Jun 05, 2019 at 02:50:54PM +0200, Jakub Jelinek wrote:
> > On Wed, Jun 05, 2019 at 08:39:56AM -0400, Marek Polacek wrote:
> > > On Wed, Jun 05, 2019 at 10:34:05AM +0100, Nina Dinka Ranns wrote:
> > > > > PR C++/63149
> > > > > * pt.c (listify_autos): Use non cv qualified auto_node in
> > > > > std::initializer_list.
> > > > >
> > > > > testsuite/
> > > > >
> > > > > PR C++/63149
> > >
> > > "c++" instead of "C++", thought I don't think anyone would mind.
> >
> > I would, I have scripts that grab the PR strings from ChangeLog entries
> > and need to fix stuff by hand if it is incorrect like this (or if people
> > forget to use the component/ part altogether).
>
> Fair enough.  Nina, please adjust that too, then.
>
> Marek
Index: gcc/cp/pt.c
===
--- gcc/cp/pt.c	(revision 271709)
+++ gcc/cp/pt.c	(working copy)
@@ -26836,7 +26836,7 @@
 static tree
 listify_autos (tree type, tree auto_node)
 {
-  tree init_auto = listify (auto_node);
+  tree init_auto = listify (strip_top_quals (auto_node));
   tree argvec = make_tree_vec (1);
   TREE_VEC_ELT (argvec, 0) = init_auto;
   if (processing_template_decl)
Index: gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C
===
--- gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C	(working copy)
@@ -0,0 +1,8 @@
+// Test for PR63149
+// { dg-do compile { target c++11 } }
+
+#include 
+
+const auto r = { 1, 2, 3 };
+using X = decltype(r);
+using X = const std::initializer_list;


Re: PR C++/63149

2019-06-05 Thread Nina Dinka Ranns
yes, I forgot to attach the latest patch. :)

On Wed, 5 Jun 2019 at 10:24, Nina Dinka Ranns  wrote:
>
> Hi both,
> Addressing all comments in this e-mail, as some are duplicate.
>
> On Tue, 4 Jun 2019 at 20:45, Paolo Carlini  wrote:
> >
> > Hi,
> >
> > On 04/06/19 21:26, Nina Dinka Ranns wrote:
> >
> > Good point, dg-do compile is sufficient to demonstrate the issue.
> >
> > I agree.
> >
> > A couple of additional nits, sorry for mentioning only now.
> >
> >
> > C++63149_2.diff
> >
> > Index: gcc/cp/pt.c
> > ===
> > --- gcc/cp/pt.c (revision 271709)
> > +++ gcc/cp/pt.c (working copy)
> > @@ -26836,7 +26836,7 @@
> >  static tree
> >  listify_autos (tree type, tree auto_node)
> >  {
> > -  tree init_auto = listify (auto_node);
> > +  tree init_auto = listify (strip_top_quals(auto_node));
> >
> > You want a space after strip_top_quals.
>
> fixed.
>
> >
> >tree argvec = make_tree_vec (1);
> >TREE_VEC_ELT (argvec, 0) = init_auto;
> >if (processing_template_decl)
> > Index: gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C
> > ===
> > --- gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C (nonexistent)
> > +++ gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C (working copy)
> > @@ -0,0 +1,12 @@
> > +// Test for PR63149
> > +// { dg-do compile { target c++11 } }
> > +
> > +#include 
> > +
> > +const auto r = { 1, 2, 3 };
> > +using X = decltype(r);
> > +using X = const std::initializer_list;
> > +
> > +int main()
> > +{
> > +}
> >
> > With dg-do compile you don't need a main anymore.
> >
> fixed
>
> > I seem to remember also a couple of minor formatting issues in the 
> > ChangeLog entry: just harmonize the format with everything else you find in 
> > the ChangeLog, in terms of the usual trivial details: upper cases, line 
> > lenghts and line wraps, etc.
> >
>
> Below is the amended change log. If there is anything else off, I
> would need specifics as I've made all the changes I could spot myself.
> :)
>
> Thanks,
> Nina
>
> 2019-06-04  Nina Dinka Ranns  
> gcc/cp
>
> PR C++/63149
> * pt.c (listify_autos): Use non cv qualified auto_node in
> std::initializer_list.
>
> testsuite/
>
> PR C++/63149
> * g++.dg/cpp0x/initlist-deduce.C: New test.
Index: gcc/cp/pt.c
===
--- gcc/cp/pt.c	(revision 271709)
+++ gcc/cp/pt.c	(working copy)
@@ -26836,7 +26836,7 @@
 static tree
 listify_autos (tree type, tree auto_node)
 {
-  tree init_auto = listify (auto_node);
+  tree init_auto = listify (strip_top_quals (auto_node));
   tree argvec = make_tree_vec (1);
   TREE_VEC_ELT (argvec, 0) = init_auto;
   if (processing_template_decl)
Index: gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C
===
--- gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C	(working copy)
@@ -0,0 +1,8 @@
+// Test for PR63149
+// { dg-do compile { target c++11 } }
+
+#include 
+
+const auto r = { 1, 2, 3 };
+using X = decltype(r);
+using X = const std::initializer_list;


Re: PR C++/63149

2019-06-05 Thread Nina Dinka Ranns
Hi both,
Addressing all comments in this e-mail, as some are duplicate.

On Tue, 4 Jun 2019 at 20:45, Paolo Carlini  wrote:
>
> Hi,
>
> On 04/06/19 21:26, Nina Dinka Ranns wrote:
>
> Good point, dg-do compile is sufficient to demonstrate the issue.
>
> I agree.
>
> A couple of additional nits, sorry for mentioning only now.
>
>
> C++63149_2.diff
>
> Index: gcc/cp/pt.c
> ===
> --- gcc/cp/pt.c (revision 271709)
> +++ gcc/cp/pt.c (working copy)
> @@ -26836,7 +26836,7 @@
>  static tree
>  listify_autos (tree type, tree auto_node)
>  {
> -  tree init_auto = listify (auto_node);
> +  tree init_auto = listify (strip_top_quals(auto_node));
>
> You want a space after strip_top_quals.

fixed.

>
>tree argvec = make_tree_vec (1);
>TREE_VEC_ELT (argvec, 0) = init_auto;
>if (processing_template_decl)
> Index: gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C
> ===
> --- gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C (nonexistent)
> +++ gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C (working copy)
> @@ -0,0 +1,12 @@
> +// Test for PR63149
> +// { dg-do compile { target c++11 } }
> +
> +#include 
> +
> +const auto r = { 1, 2, 3 };
> +using X = decltype(r);
> +using X = const std::initializer_list;
> +
> +int main()
> +{
> +}
>
> With dg-do compile you don't need a main anymore.
>
fixed

> I seem to remember also a couple of minor formatting issues in the ChangeLog 
> entry: just harmonize the format with everything else you find in the 
> ChangeLog, in terms of the usual trivial details: upper cases, line lenghts 
> and line wraps, etc.
>

Below is the amended change log. If there is anything else off, I
would need specifics as I've made all the changes I could spot myself.
:)

Thanks,
Nina

2019-06-04  Nina Dinka Ranns  
gcc/cp

PR C++/63149
* pt.c (listify_autos): Use non cv qualified auto_node in
std::initializer_list.

testsuite/

PR C++/63149
* g++.dg/cpp0x/initlist-deduce.C: New test.


Re: PR C++/63149

2019-06-04 Thread Nina Dinka Ranns
Good point, dg-do compile is sufficient to demonstrate the issue.
Amended, new patch attached.
Thanks,
Nina

On Tue, 4 Jun 2019 at 17:53, Paolo Carlini  wrote:
>
> Hi,
>
> On 04/06/19 18:36, Nina Dinka Ranns wrote:
> > +// Test for PR63149
> > +// { dg-do run { target c++11 } }
>
> Are you sure you want a dg-do run?
>
> Paolo.
>
>
Index: gcc/cp/pt.c
===
--- gcc/cp/pt.c	(revision 271709)
+++ gcc/cp/pt.c	(working copy)
@@ -26836,7 +26836,7 @@
 static tree
 listify_autos (tree type, tree auto_node)
 {
-  tree init_auto = listify (auto_node);
+  tree init_auto = listify (strip_top_quals(auto_node));
   tree argvec = make_tree_vec (1);
   TREE_VEC_ELT (argvec, 0) = init_auto;
   if (processing_template_decl)
Index: gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C
===
--- gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C	(working copy)
@@ -0,0 +1,12 @@
+// Test for PR63149
+// { dg-do compile { target c++11 } }
+
+#include 
+
+const auto r = { 1, 2, 3 };
+using X = decltype(r);
+using X = const std::initializer_list;
+
+int main()
+{
+}


PR C++/63149

2019-06-04 Thread Nina Dinka Ranns
Tested on Linux x86_64

2019-06-04  Nina Dinka Ranns  
gcc/cp

 PR c++/63149
* pt.c (listify_autos): use non cv qualified auto_node in
std::initializer_list

 testsuite/

 PR c++/63149
* g++.dg/cpp0x/initlist-deduce.C: New
Index: gcc/cp/pt.c
===
--- gcc/cp/pt.c	(revision 271709)
+++ gcc/cp/pt.c	(working copy)
@@ -26836,7 +26836,7 @@
 static tree
 listify_autos (tree type, tree auto_node)
 {
-  tree init_auto = listify (auto_node);
+  tree init_auto = listify (strip_top_quals(auto_node));
   tree argvec = make_tree_vec (1);
   TREE_VEC_ELT (argvec, 0) = init_auto;
   if (processing_template_decl)
Index: gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C
===
--- gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/initlist-deduce2.C	(working copy)
@@ -0,0 +1,12 @@
+// Test for PR63149
+// { dg-do run { target c++11 } }
+
+#include 
+
+const auto r = { 1, 2, 3 };
+using X = decltype(r);
+using X = const std::initializer_list;
+
+int main()
+{
+}


[v3 PATCH] basic_string spurious use of a default constructible allocator - LWG2788

2019-05-27 Thread Nina Dinka Ranns
Tested on Linux x86_64
basic_string spurious use of a default constructible allocator - LWG2788

2019-05-27  Nina Dinka Ranns  
basic_string spurious use of a default constructible allocator - LWG2788
* bits/basic_string.tcc:
(_M_replace_dispatch()): string temporary now constructed with
the current allocator
* testsuite/21_strings/basic_string/allocator/char/lwg2788.cc: New
* testsuite/21_strings/basic_string/allocator/wchar_t/lwg2788.cc: New
Index: libstdc++-v3/include/bits/basic_string.tcc
===
--- libstdc++-v3/include/bits/basic_string.tcc	(revision 271509)
+++ libstdc++-v3/include/bits/basic_string.tcc	(working copy)
@@ -381,7 +381,9 @@
 			  _InputIterator __k1, _InputIterator __k2,
 			  std::__false_type)
   {
-	const basic_string __s(__k1, __k2);
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// 2788. unintentionally require a default constructible allocator
+	const basic_string __s(__k1, __k2, this->get_allocator());
 	const size_type __n1 = __i2 - __i1;
 	return _M_replace(__i1 - begin(), __n1, __s._M_data(),
 			  __s.size());
Index: libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc
===
--- libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc	(revision 271509)
+++ libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc	(nonexistent)
@@ -1,39 +0,0 @@
-// 2019-05-14  Nina Dinka Ranns  
-// Copyright (C) 2019 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3.  If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-do compile { target c++14 } }
-
-#include 
-// Example taken from LWG2960
-
-using std::__nonesuch;
-struct such {};
-void f(const such&){};
-void f(const std::__nonesuch&);
-
-int main(){
- static_assert(!std::is_default_constructible<__nonesuch>::value,
-		 "__nonesuch is default constructible");
- static_assert(!std::is_copy_constructible<__nonesuch>::value,
-		 "__nonesuch is copy constructible");
- static_assert(!std::is_assignable<__nonesuch, __nonesuch>::value,
-		 "__nonesuch is assignable");
- static_assert(!std::is_destructible<__nonesuch>::value,
-		 "__nonesuch is destructible");
- f({});
-}
Index: libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/lwg2788.cc
===
--- libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/lwg2788.cc	(nonexistent)
+++ libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/lwg2788.cc	(working copy)
@@ -0,0 +1,84 @@
+//{ dg-do run { target c++11 } }
+
+// 2019-05-27  Nina Dinka Ranns  
+//
+// Copyright (C) 2015-2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+ 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+ 
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include 
+#include 
+
+using C = char;
+using traits = std::char_traits;
+int constructCount = 0;
+
+static void resetCounter()
+{
+ constructCount = 0;
+}
+
+template 
+struct TestAllocator
+{
+  typedef Tp value_type;
+  using size_type = unsigned;
+
+  TestAllocator() noexcept { constructCount++; }
+
+  template 
+  TestAllocator(const TestAllocator&) {}
+
+  Tp *allocate(std::size_t n)
+  { return std::allocator().allocate(n); }
+
+  void deallocate(Tp *p, std::size_t n)
+  { std::allocator().deallocate(p, n); }
+
+};
+
+template 
+bool operator==(const TestAllocator&, const TestAllocator&)
+{ return true; }
+template 
+bool operator!=(const TestAllocator&, const TestAllocator&)
+{ return false; }
+
+void test01()
+{
+  typedef TestAllocator alloc_type;
+  typedef std::basic_string test_t

Re: [v3 PATCH] nonesuch is insufficiently useless (lwg2996)

2019-05-14 Thread Nina Dinka Ranns
That was fast :)
I’ll check the changelog for future reference.
Thanks,
Nina

On Tue, 14 May 2019 at 16:50, Jonathan Wakely  wrote:

> On 14/05/19 15:43 +0100, Nina Dinka Ranns wrote:
> >Tested on Linux x86_64
> >nonesuch is insufficiently useless (lwg2996)
> >
> >2019-05-14  Nina Dinka Ranns  
> >nonesuch is insufficiently useless (lwg2996)
> >* include/std/type_traits
> >struct __nonesuch: added private base class to make __nonesuch
> >not an aggregate and removed deleted default constructor
> >* include/bits/stl_pair.h:
> >struct __nonesuch_no_braces: Removed
> >(operator=(const pair&)): Use __nonesuch instead of
> >__nonesuch_no_braces.
> >(operator=(pair&&)): Likewise
> >* include/std/tuple
> >(operator=(const tuple&)): Use __nonesuch instead of
> >__nonesuch_no_braces.
> >(operator=(tuple&&)): Likewise
> >* include/experimental/type_traits
> > struct nonesuch: added private base class to make nonesuch
> >not an aggregate and removed deleted default constructor
> >* testsuite/20_util/nonesuch/nonesuch.cc: New
> >* testsuite/experimental/type_traits/nonesuch.cc: New
>
> Thanks!
>
> Tested and committed, again with some changelog edits, and some whitespace
> before the opening braces here ...
>
> >@@ -2769,8 +2769,8 @@
> >  __call_is_nothrow_<_Fn, _Args...>>::type
> > { };
> >
> >-  struct __nonesuch {
> >-__nonesuch() = delete;
> >+  struct __nonesuchbase{};
> >+  struct __nonesuch : private __nonesuchbase{
>
>
>


[v3 PATCH] nonesuch is insufficiently useless (lwg2996)

2019-05-14 Thread Nina Dinka Ranns
Tested on Linux x86_64
nonesuch is insufficiently useless (lwg2996)

2019-05-14  Nina Dinka Ranns  
nonesuch is insufficiently useless (lwg2996)
* include/std/type_traits
struct __nonesuch: added private base class to make __nonesuch
not an aggregate and removed deleted default constructor
* include/bits/stl_pair.h:
struct __nonesuch_no_braces: Removed
(operator=(const pair&)): Use __nonesuch instead of
__nonesuch_no_braces.
(operator=(pair&&)): Likewise
* include/std/tuple
(operator=(const tuple&)): Use __nonesuch instead of
__nonesuch_no_braces.
(operator=(tuple&&)): Likewise
* include/experimental/type_traits
 struct nonesuch: added private base class to make nonesuch
not an aggregate and removed deleted default constructor
* testsuite/20_util/nonesuch/nonesuch.cc: New
* testsuite/experimental/type_traits/nonesuch.cc: New
Index: libstdc++-v3/include/bits/stl_pair.h
===
--- libstdc++-v3/include/bits/stl_pair.h	(revision 270630)
+++ libstdc++-v3/include/bits/stl_pair.h	(working copy)
@@ -178,13 +178,6 @@
 	return false;
   }
   };
-
-  // PR libstdc++/79141, a utility type for preventing
-  // initialization of an argument of a disabled assignment
-  // operator from a pair of empty braces.
-  struct __nonesuch_no_braces : std::__nonesuch {
-explicit __nonesuch_no_braces(const __nonesuch&) = delete;
-  };
 #endif // C++11
 
   template class __pair_base
@@ -378,7 +371,7 @@
   operator=(typename conditional<
 		__and_,
 		   is_copy_assignable<_T2>>::value,
-		const pair&, const __nonesuch_no_braces&>::type __p)
+		const pair&, const __nonesuch&>::type __p)
   {
 	first = __p.first;
 	second = __p.second;
@@ -389,7 +382,7 @@
   operator=(typename conditional<
 		__and_,
 		   is_move_assignable<_T2>>::value,
-		pair&&, __nonesuch_no_braces&&>::type __p)
+		pair&&, __nonesuch&&>::type __p)
   noexcept(__and_,
 		  is_nothrow_move_assignable<_T2>>::value)
   {
Index: libstdc++-v3/include/experimental/type_traits
===
--- libstdc++-v3/include/experimental/type_traits	(revision 270630)
+++ libstdc++-v3/include/experimental/type_traits	(working copy)
@@ -226,9 +226,9 @@
 
 template using void_t = void;
 
-struct nonesuch
+struct __nonesuchbase{};
+struct nonesuch : private __nonesuchbase
 {
-  nonesuch() = delete;
   ~nonesuch() = delete;
   nonesuch(nonesuch const&) = delete;
   void operator=(nonesuch const&) = delete;
Index: libstdc++-v3/include/std/tuple
===
--- libstdc++-v3/include/std/tuple	(revision 270630)
+++ libstdc++-v3/include/std/tuple	(working copy)
@@ -816,7 +816,7 @@
   tuple&
   operator=(typename conditional<__assignable(),
  const tuple&,
- const __nonesuch_no_braces&>::type __in)
+ const __nonesuch&>::type __in)
   noexcept(__nothrow_assignable())
   {
 	this->_M_assign(__in);
@@ -826,7 +826,7 @@
   tuple&
   operator=(typename conditional<__assignable<_Elements...>(),
  tuple&&,
- __nonesuch_no_braces&&>::type __in)
+ __nonesuch&&>::type __in)
   noexcept(__nothrow_assignable<_Elements...>())
   {
 	this->_M_assign(std::move(__in));
@@ -1204,7 +1204,7 @@
   tuple&
   operator=(typename conditional<__assignable(),
  const tuple&,
- const __nonesuch_no_braces&>::type __in)
+ const __nonesuch&>::type __in)
   noexcept(__nothrow_assignable())
   {
 	this->_M_assign(__in);
@@ -1214,7 +1214,7 @@
   tuple&
   operator=(typename conditional<__assignable<_T1, _T2>(),
  tuple&&,
- __nonesuch_no_braces&&>::type __in)
+ __nonesuch&&>::type __in)
   noexcept(__nothrow_assignable<_T1, _T2>())
   {
 	this->_M_assign(std::move(__in));
Index: libstdc++-v3/include/std/type_traits
===
--- libstdc++-v3/include/std/type_traits	(revision 270630)
+++ libstdc++-v3/include/std/type_traits	(working copy)
@@ -2769,8 +2769,8 @@
  __call_is_nothrow_<_Fn, _Args...>>::type
 { };
 
-  struct __nonesuch {
-__nonesuch() = delete;
+  struct __nonesuchbase{};
+  struct __nonesuch : private __nonesuchbase{
 ~__nonesuch() = delete;
 __nonesuch(__nonesuch const&) = delete;
 void operator=(__nonesuch const&) = delete;
Index: libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc
=

[v3 PATCH] Inconsistency wrt Allocators in basic_string assignment vs. basic_string::assign (LWG2579)

2019-05-09 Thread Nina Dinka Ranns
Tested on Linux x86_64
Inconsistency wrt Allocators in basic_string assignment vs.
basic_string::assign (LWG2579)

2019-05-09  Nina Dinka Ranns  
Inconsistency wrt Allocators in basic_string assignment vs.
basic_string::assign (LWG2579)
* include/bits/basic_string.h:
 operator=(const basic_string& __str): moved allocator
decision from operator= to assign
 assign(const basic_string& __str): moved allocator decision
from operator= to assign
* testsuite/21_strings/basic_string/allocator/char/copy_assign.cc:
Adding tests
* testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc:
Adding tests
Index: libstdc++-v3/include/bits/basic_string.h
===
--- libstdc++-v3/include/bits/basic_string.h	(revision 270943)
+++ libstdc++-v3/include/bits/basic_string.h	(working copy)
@@ -664,35 +664,6 @@
   basic_string&
   operator=(const basic_string& __str)
   {
-#if __cplusplus >= 201103L
-	if (_Alloc_traits::_S_propagate_on_copy_assign())
-	  {
-	if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
-		&& _M_get_allocator() != __str._M_get_allocator())
-	  {
-		// Propagating allocator cannot free existing storage so must
-		// deallocate it before replacing current allocator.
-		if (__str.size() <= _S_local_capacity)
-		  {
-		_M_destroy(_M_allocated_capacity);
-		_M_data(_M_local_data());
-		_M_set_length(0);
-		  }
-		else
-		  {
-		const auto __len = __str.size();
-		auto __alloc = __str._M_get_allocator();
-		// If this allocation throws there are no effects:
-		auto __ptr = _Alloc_traits::allocate(__alloc, __len + 1);
-		_M_destroy(_M_allocated_capacity);
-		_M_data(__ptr);
-		_M_capacity(__len);
-		_M_set_length(__len);
-		  }
-	  }
-	std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator());
-	  }
-#endif
 	return this->assign(__str);
   }
 
@@ -1363,6 +1334,35 @@
   basic_string&
   assign(const basic_string& __str)
   {
+#if __cplusplus >= 201103L
+	if (_Alloc_traits::_S_propagate_on_copy_assign())
+	  {
+	if (!_Alloc_traits::_S_always_equal() && !_M_is_local()
+		&& _M_get_allocator() != __str._M_get_allocator())
+	  {
+		// Propagating allocator cannot free existing storage so must
+		// deallocate it before replacing current allocator.
+		if (__str.size() <= _S_local_capacity)
+		  {
+		_M_destroy(_M_allocated_capacity);
+		_M_data(_M_local_data());
+		_M_set_length(0);
+		  }
+		else
+		  {
+		const auto __len = __str.size();
+		auto __alloc = __str._M_get_allocator();
+		// If this allocation throws there are no effects:
+		auto __ptr = _Alloc_traits::allocate(__alloc, __len + 1);
+		_M_destroy(_M_allocated_capacity);
+		_M_data(__ptr);
+		_M_capacity(__len);
+		_M_set_length(__len);
+		  }
+	  }
+	std::__alloc_on_copy(_M_get_allocator(), __str._M_get_allocator());
+	  }
+#endif
 	this->_M_assign(__str);
 	return *this;
   }
Index: libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc
===
--- libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc	(revision 270943)
+++ libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/copy_assign.cc	(working copy)
@@ -133,10 +133,47 @@
   VERIFY( v1.get_allocator() == a2 );
 }
 
+void test04()
+{
+  // LWG2579
+  typedef propagating_allocator alloc_type;
+
+  typedef std::basic_string test_type;
+
+  test_type v1("tralalala",alloc_type(1));
+  test_type v2("content", alloc_type(2));
+  test_type v3("content2", alloc_type(3));
+
+  v1.assign(v2);
+  v3 = v2;
+  VERIFY(2 == v1.get_allocator().get_personality());
+  VERIFY(2 == v3.get_allocator().get_personality());
+
+}
+
+void test05()
+{
+  // LWG2579
+  typedef propagating_allocator alloc_type;
+
+  typedef std::basic_string test_type;
+
+  test_type v1("tralalala",alloc_type(1));
+  test_type v2("content", alloc_type(2));
+  test_type v3("content2", alloc_type(3));
+
+  v1.assign(v2);
+  v3 = v2;
+  VERIFY(1 == v1.get_allocator().get_personality());
+  VERIFY(3 == v3.get_allocator().get_personality());
+}
+
 int main()
 {
   test01();
   test02();
   test03();
+  test04();
+  test05();
   return 0;
 }
Index: libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc
===
--- libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc	(revision 270943)
+++ libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/copy_assign.cc	(working copy)
@@ -133,10 +133,46 @@
   VERIFY( v1.get_allocator() == a2 );
 }
 
+void test04()
+{
+  // LWG2579
+  typedef propagating_allocator alloc_t

Re: [v3 PATCH] Make stateful allocator propagation more consistent for operator+(basic_string) (P1165R1)

2019-05-07 Thread Nina Dinka Ranns
On Tue, 7 May 2019 at 12:22, Jonathan Wakely  wrote:
>
> I can remove that #if and test and commit the result for you though,
> no need for another revision of the patch.
Thanks ! :)
Best,
Nina


Re: [v3 PATCH] Make stateful allocator propagation more consistent for operator+(basic_string) (P1165R1)

2019-05-07 Thread Nina Dinka Ranns
Ack. I've put the use of _Alloc_traits::is_always_equal within #if
__cplusplus >= 201703L block since it is officially a C++17 feature.
Let me know if you think that's an overkill.
New changelog below. I didn't change the description of
operator+(basic_string&&,basic_string&&) as it's still technically
always resulting in an allocator from the first parameter.


2019-05-01  Nina Dinka Ranns  
Make stateful allocator propagation more consistent
foroperator+(basic_string) (P1165R1)
* include/bits/basic_string.h:
(operator+(basic_string&&,basic_string&&) : Changed resulting
allocator to always be the one from the first parameter
* include/bits/basic_string.tcc:
(operator+(const _CharT*, const basic_string&)) : Changed
resulting allocator to be SOCCC on the second parameter's allocator
(operator+(_CharT, const basic_string&)) : Likewise
* testsuite/21_strings/basic_string/allocator/char/operator_plus.cc: New
* testsuite/21_strings/basic_string/allocator/wchar_t/operator_plus.cc:
New
Index: libstdc++-v3/include/bits/basic_string.h
===
--- libstdc++-v3/include/bits/basic_string.h	(revision 270655)
+++ libstdc++-v3/include/bits/basic_string.h	(working copy)
@@ -6097,11 +6097,22 @@
 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
 	  basic_string<_CharT, _Traits, _Alloc>&& __rhs)
 {
-  const auto __size = __lhs.size() + __rhs.size();
-  const bool __cond = (__size > __lhs.capacity()
-			   && __size <= __rhs.capacity());
-  return __cond ? std::move(__rhs.insert(0, __lhs))
-	: std::move(__lhs.append(__rhs));
+	  using _Alloc_traits = allocator_traits<_Alloc>;
+	  bool __use_rhs = false;
+#if __cplusplus >= 201703L
+  if _GLIBCXX17_CONSTEXPR (typename _Alloc_traits::is_always_equal{})
+	__use_rhs = true;
+	  else
+#endif
+  if (__lhs.get_allocator() == __rhs.get_allocator())
+	__use_rhs = true;
+	  if (__use_rhs)
+	  {
+		const auto __size = __lhs.size() + __rhs.size();
+		if (__size > __lhs.capacity() && __size <= __rhs.capacity())
+		  return std::move(__rhs.insert(0, __lhs));
+	  }
+	  return std::move(__lhs.append(__rhs));
 }
 
   template
Index: libstdc++-v3/include/bits/basic_string.tcc
===
--- libstdc++-v3/include/bits/basic_string.tcc	(revision 270655)
+++ libstdc++-v3/include/bits/basic_string.tcc	(working copy)
@@ -1161,8 +1161,12 @@
   __glibcxx_requires_string(__lhs);
   typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
   typedef typename __string_type::size_type	  __size_type;
+  typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	rebind<_CharT>::other _Char_alloc_type;
+  typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
   const __size_type __len = _Traits::length(__lhs);
-  __string_type __str;
+  __string_type __str(_Alloc_traits::_S_select_on_copy(
+  __rhs.get_allocator()));
   __str.reserve(__len + __rhs.size());
   __str.append(__lhs, __len);
   __str.append(__rhs);
@@ -1175,7 +1179,11 @@
 {
   typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
   typedef typename __string_type::size_type	  __size_type;
-  __string_type __str;
+  typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	rebind<_CharT>::other _Char_alloc_type;
+  typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
+  __string_type __str(_Alloc_traits::_S_select_on_copy(
+  __rhs.get_allocator()));
   const __size_type __len = __rhs.size();
   __str.reserve(__len + 1);
   __str.append(__size_type(1), __lhs);
Index: libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/operator_plus.cc
===
--- libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/operator_plus.cc	(nonexistent)
+++ libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/operator_plus.cc	(working copy)
@@ -0,0 +1,151 @@
+// 2019-04-30  Nina Dinka Ranns  
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+ 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+ 
+// You should have received a copy of the GNU General Pub

[v3 PATCH] Make stateful allocator propagation more consistent for operator+(basic_string) (P1165R1)

2019-05-02 Thread Nina Dinka Ranns
Tested on Linux x86_64
Make stateful allocator propagation more consistent for
operator+(basic_string) (P1165R1)

2019-05-01  Nina Dinka Ranns  
Make stateful allocator propagation more consistent for
operator+(basic_string) (P1165R1)
* include/bits/basic_string.tcc:
 (operator+(const _CharT*, const basic_string&)) : Changed
resulting allocator to be SOCCC on the second parameter's allocator
 (operator+(_CharT, const basic_string&)) : Likewise
 (operator+(basic_string&&,basic_string&&) : Changed resulting
allocator to always be the one from the first parameter
* testsuite/21_strings/basic_string/allocator/char/operator_plus.cc: New
* testsuite/21_strings/basic_string/allocator/wchar_t/operator_plus.cc
: New
Index: libstdc++-v3/include/bits/basic_string.h
===
--- libstdc++-v3/include/bits/basic_string.h	(revision 270655)
+++ libstdc++-v3/include/bits/basic_string.h	(working copy)
@@ -6096,13 +6096,7 @@
 inline basic_string<_CharT, _Traits, _Alloc>
 operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
 	  basic_string<_CharT, _Traits, _Alloc>&& __rhs)
-{
-  const auto __size = __lhs.size() + __rhs.size();
-  const bool __cond = (__size > __lhs.capacity()
-			   && __size <= __rhs.capacity());
-  return __cond ? std::move(__rhs.insert(0, __lhs))
-	: std::move(__lhs.append(__rhs));
-}
+{ return std::move(__lhs.append(__rhs)); }
 
   template
 inline basic_string<_CharT, _Traits, _Alloc>
Index: libstdc++-v3/include/bits/basic_string.tcc
===
--- libstdc++-v3/include/bits/basic_string.tcc	(revision 270655)
+++ libstdc++-v3/include/bits/basic_string.tcc	(working copy)
@@ -1161,8 +1161,12 @@
   __glibcxx_requires_string(__lhs);
   typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
   typedef typename __string_type::size_type	  __size_type;
+  typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	rebind<_CharT>::other _Char_alloc_type;
+  typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
   const __size_type __len = _Traits::length(__lhs);
-  __string_type __str;
+  __string_type __str(_Alloc_traits::_S_select_on_copy(
+  __rhs.get_allocator()));
   __str.reserve(__len + __rhs.size());
   __str.append(__lhs, __len);
   __str.append(__rhs);
@@ -1175,7 +1179,11 @@
 {
   typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
   typedef typename __string_type::size_type	  __size_type;
-  __string_type __str;
+  typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
+	rebind<_CharT>::other _Char_alloc_type;
+  typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits;
+  __string_type __str(_Alloc_traits::_S_select_on_copy(
+  __rhs.get_allocator()));
   const __size_type __len = __rhs.size();
   __str.reserve(__len + 1);
   __str.append(__size_type(1), __lhs);
Index: libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/operator_plus.cc
===
--- libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/operator_plus.cc	(nonexistent)
+++ libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/operator_plus.cc	(working copy)
@@ -0,0 +1,151 @@
+// 2019-04-30  Nina Dinka Ranns  
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+ 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+ 
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+// COW strings don't support C++11 allocators:
+// { dg-require-effective-target cxx11-abi }
+
+#include 
+#include 
+#include 
+#include 
+ 
+using C = char;
+using traits = std::char_traits;
+
+using __gnu_test::propagating_allocator;
+
+void test01()
+{
+  typedef propagating_allocator alloc_type;
+  typedef std::basic_string test_type;
+
+  test_type v1("something",alloc_type(1));
+  test_type v2("something",alloc_type(2));
+  auto r1 = v1 + v2;
+  VERIFY(r1.get_allocator().get_personality() == 1);
+
+  auto r2 = v1 + std::

Re: Adding noexcept-specification on tuple constructors (LWG 2899)

2019-04-29 Thread Nina Dinka Ranns
noted, thanks :)
Best,
Nina

On Sun, 28 Apr 2019 at 22:46, Jonathan Wakely  wrote:
>
> On 28/04/19 22:44 +0100, Jonathan Wakely wrote:
> >On 29/04/19 00:18 +0300, Ville Voutilainen wrote:
> >>On Wed, 24 Apr 2019 at 14:53, Jonathan Wakely  wrote:
> >>>
> >>>On 24/04/19 11:21 +0100, Nina Dinka Ranns wrote:
> >>>>New diff attached.
> >>>
> >>>Thanks, this looks great. I think we can apply this as soon as stage 1
> >>>begins (which should be Real Soon Now).
> >>
> >>Tested on Linux-PPC64, committed to trunk. Congrats, Nina, first patch
> >>in, let there be many more. :)
> >
> >Thanks, Nina, and Ville for taking care of the commit.
> >
> >Apologies for not noticing it earlier, but the first line of the
> >ChangeLog entry was not formatted correctly. There should be two
> >spaces either side of the author's name:
> >
> >2019-04-28  John Doe  
> >
> >not:
> >
> >2019-04-28 John Doe 
> >
> >I've committed r270633 to fix it.
> >
> >Thanks again.
>
> Oh, and the files in the ChangeLog entry should use paths relative to
> the ChangeLog file, so no libstdc++-v3/ prefixes. I missed that in the
> review too.
>
>


Re: Adding noexcept-specification on tuple constructors (LWG 2899)

2019-04-24 Thread Nina Dinka Ranns
On Tue, 23 Apr 2019 at 21:28, Jonathan Wakely  wrote:
>
> On 23/04/19 18:43 +0100, Nina Dinka Ranns wrote:
> >On Thu, 18 Apr 2019 at 21:35, Jonathan Wakely  wrote:
> >>
> >> On 16/04/19 17:59 +0100, Nina Dinka Ranns wrote:
> >> >On Tue, 16 Apr 2019 at 15:18, Jonathan Wakely  wrote:
> >> >>
> >> >> On 16/04/19 14:08 +0100, Nina Dinka Ranns wrote:
> >> >> >Tested on Linux-PPC64
> >> >> >Adding noexcept-specification on tuple constructors (LWG 2899)
> >> >>
> >> >> Thanks, Nina!
> >> >>
> >> >> This looks great, although as I think Ville has explained we won't
> >> >> commit it until the next stage 1, after the GCC 9 release.
> >> >ack
> >> >
> >> >>
> >> >> The changes look good, I just have some mostly-stylistic comments,
> >> >> which are inline below ...
> >> >>
> >> >>
> >> >> >2019-04-13 Nina Dinka Ranns 
> >> >> >
> >> >> >Adding noexcept-specification on tuple constructors (LWG 2899)
> >> >> >* libstdc++-v3/include/std/tuple:
> >> >> >(tuple()): Add noexcept-specification.
> >> >> >(tuple(const _Elements&...)): Likewise
> >> >> >(tuple(_UElements&&...)): Likewise
> >> >> >(tuple(const tuple<_UElements...>&)): Likewise
> >> >> >(tuple(tuple<_UElements...>&&)): Likewise
> >> >> >(tuple(const _T1&, const _T2&)): Likewise
> >> >> >(tuple(_U1&&, _U2&&)): Likewise
> >> >> >(tuple(const tuple<_U1, _U2>&): Likewise
> >> >> >(tuple(tuple<_U1, _U2>&&): Likewise
> >> >> >(tuple(const pair<_U1, _U2>&): Likewise
> >> >> >(tuple(pair<_U1, _U2>&&): Likewise
> >> >> >
> >> >> >
> >> >>
> >> >> There should be no blank lines in the changelog entry here. A single
> >> >> change should be recorded as a single block in the changelog, with no
> >> >> blank lines within it.
> >> >ack. Do you need me to do anything about this or is it for future
> >> >reference only ?
> >>
> >> For future reference. Whoever commits the patch can correct the
> >> changelog.
> >>
> >> >>
> >> >> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc: 
> >> >> > New
> >> >> >* 
> >> >> > libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs2.cc: New
> >> >> >* 
> >> >> > libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs3.cc: New
> >> >> >* 
> >> >> > libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs4.cc: New
> >> >> >* 
> >> >> > libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs5.cc: New
> >> >> >* 
> >> >> > libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs6.cc: New
> >> >>
> >> >> This is a lot of new test files for a small-ish QoI feature. Could
> >> >> they be combined into one file?  Generally we do want one test file
> >> >> per feature, but I think all of these are arguably testing one feature
> >> >> (just on different constructors). The downside of lots of smaller
> >> >> files is that we have to compile+assemble+link+run each one, which
> >> >> adds several fork()s to launch a new process for each step. On some
> >> >> platforms that can be quite slow.
> >> >I can do that, but there may be an issue. See below.
> >> >
> >> >>
> >> >>
> >> >> >@@ -624,6 +634,7 @@
> >> >> >   && (sizeof...(_Elements) >= 1),
> >> >> > bool>::type=true>
> >> >> > constexpr tuple(_UElements&&... __elements)
> >> >> >+
> >> >> >noexcept(__and_...>::value)
> >> >>
> >> >> Can this be __nothrow_constructible<_UElements>() ?
> >> >It should have been that in the first place. Apologies. Fixed.
> >> >
> >> >
> >> >>

Re: Adding noexcept-specification on tuple constructors (LWG 2899)

2019-04-23 Thread Nina Dinka Ranns
On Thu, 18 Apr 2019 at 21:35, Jonathan Wakely  wrote:
>
> On 16/04/19 17:59 +0100, Nina Dinka Ranns wrote:
> >On Tue, 16 Apr 2019 at 15:18, Jonathan Wakely  wrote:
> >>
> >> On 16/04/19 14:08 +0100, Nina Dinka Ranns wrote:
> >> >Tested on Linux-PPC64
> >> >Adding noexcept-specification on tuple constructors (LWG 2899)
> >>
> >> Thanks, Nina!
> >>
> >> This looks great, although as I think Ville has explained we won't
> >> commit it until the next stage 1, after the GCC 9 release.
> >ack
> >
> >>
> >> The changes look good, I just have some mostly-stylistic comments,
> >> which are inline below ...
> >>
> >>
> >> >2019-04-13 Nina Dinka Ranns 
> >> >
> >> >Adding noexcept-specification on tuple constructors (LWG 2899)
> >> >* libstdc++-v3/include/std/tuple:
> >> >(tuple()): Add noexcept-specification.
> >> >(tuple(const _Elements&...)): Likewise
> >> >(tuple(_UElements&&...)): Likewise
> >> >(tuple(const tuple<_UElements...>&)): Likewise
> >> >(tuple(tuple<_UElements...>&&)): Likewise
> >> >(tuple(const _T1&, const _T2&)): Likewise
> >> >(tuple(_U1&&, _U2&&)): Likewise
> >> >(tuple(const tuple<_U1, _U2>&): Likewise
> >> >(tuple(tuple<_U1, _U2>&&): Likewise
> >> >(tuple(const pair<_U1, _U2>&): Likewise
> >> >(tuple(pair<_U1, _U2>&&): Likewise
> >> >
> >> >
> >>
> >> There should be no blank lines in the changelog entry here. A single
> >> change should be recorded as a single block in the changelog, with no
> >> blank lines within it.
> >ack. Do you need me to do anything about this or is it for future
> >reference only ?
>
> For future reference. Whoever commits the patch can correct the
> changelog.
>
> >>
> >> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc: New
> >> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs2.cc: 
> >> > New
> >> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs3.cc: 
> >> > New
> >> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs4.cc: 
> >> > New
> >> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs5.cc: 
> >> > New
> >> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs6.cc: 
> >> > New
> >>
> >> This is a lot of new test files for a small-ish QoI feature. Could
> >> they be combined into one file?  Generally we do want one test file
> >> per feature, but I think all of these are arguably testing one feature
> >> (just on different constructors). The downside of lots of smaller
> >> files is that we have to compile+assemble+link+run each one, which
> >> adds several fork()s to launch a new process for each step. On some
> >> platforms that can be quite slow.
> >I can do that, but there may be an issue. See below.
> >
> >>
> >>
> >> >@@ -624,6 +634,7 @@
> >> >   && (sizeof...(_Elements) >= 1),
> >> > bool>::type=true>
> >> > constexpr tuple(_UElements&&... __elements)
> >> >+
> >> >noexcept(__and_...>::value)
> >>
> >> Can this be __nothrow_constructible<_UElements>() ?
> >It should have been that in the first place. Apologies. Fixed.
> >
> >
> >>
> >> > : _Inherited(std::forward<_UElements>(__elements)...) { }
> >> >
> >> >   template >> >@@ -635,6 +646,7 @@
> >> >   && (sizeof...(_Elements) >= 1),
> >> > bool>::type=false>
> >> > explicit constexpr tuple(_UElements&&... __elements)
> >> >+noexcept(__nothrow_constructible<_UElements&&...>())
> >>
> >> The && here is redundant, though harmless.
> >>
> >> is_constructible is exactly equivalent to is_constructible
> >> because U means construction from an rvalue of type U and so does U&&.
> >>
> >> It's fine to leave the && there though.
> >I'm happy to go either way. The only reason I us

Re: Adding noexcept-specification on tuple constructors (LWG 2899)

2019-04-16 Thread Nina Dinka Ranns
On Tue, 16 Apr 2019 at 15:18, Jonathan Wakely  wrote:
>
> On 16/04/19 14:08 +0100, Nina Dinka Ranns wrote:
> >Tested on Linux-PPC64
> >Adding noexcept-specification on tuple constructors (LWG 2899)
>
> Thanks, Nina!
>
> This looks great, although as I think Ville has explained we won't
> commit it until the next stage 1, after the GCC 9 release.
ack

>
> The changes look good, I just have some mostly-stylistic comments,
> which are inline below ...
>
>
> >2019-04-13 Nina Dinka Ranns 
> >
> >Adding noexcept-specification on tuple constructors (LWG 2899)
> >* libstdc++-v3/include/std/tuple:
> >(tuple()): Add noexcept-specification.
> >(tuple(const _Elements&...)): Likewise
> >(tuple(_UElements&&...)): Likewise
> >(tuple(const tuple<_UElements...>&)): Likewise
> >(tuple(tuple<_UElements...>&&)): Likewise
> >(tuple(const _T1&, const _T2&)): Likewise
> >(tuple(_U1&&, _U2&&)): Likewise
> >(tuple(const tuple<_U1, _U2>&): Likewise
> >(tuple(tuple<_U1, _U2>&&): Likewise
> >(tuple(const pair<_U1, _U2>&): Likewise
> >(tuple(pair<_U1, _U2>&&): Likewise
> >
> >
>
> There should be no blank lines in the changelog entry here. A single
> change should be recorded as a single block in the changelog, with no
> blank lines within it.
ack. Do you need me to do anything about this or is it for future
reference only ?

>
> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc: New
> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs2.cc: New
> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs3.cc: New
> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs4.cc: New
> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs5.cc: New
> >* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs6.cc: New
>
> This is a lot of new test files for a small-ish QoI feature. Could
> they be combined into one file?  Generally we do want one test file
> per feature, but I think all of these are arguably testing one feature
> (just on different constructors). The downside of lots of smaller
> files is that we have to compile+assemble+link+run each one, which
> adds several fork()s to launch a new process for each step. On some
> platforms that can be quite slow.
I can do that, but there may be an issue. See below.

>
>
> >@@ -624,6 +634,7 @@
> >   && (sizeof...(_Elements) >= 1),
> > bool>::type=true>
> > constexpr tuple(_UElements&&... __elements)
> >+
> >noexcept(__and_...>::value)
>
> Can this be __nothrow_constructible<_UElements>() ?
It should have been that in the first place. Apologies. Fixed.


>
> > : _Inherited(std::forward<_UElements>(__elements)...) { }
> >
> >   template >@@ -635,6 +646,7 @@
> >   && (sizeof...(_Elements) >= 1),
> > bool>::type=false>
> > explicit constexpr tuple(_UElements&&... __elements)
> >+noexcept(__nothrow_constructible<_UElements&&...>())
>
> The && here is redundant, though harmless.
>
> is_constructible is exactly equivalent to is_constructible
> because U means construction from an rvalue of type U and so does U&&.
>
> It's fine to leave the && there though.
I'm happy to go either way. The only reason I used && form is because
it mimics the wording in the LWG resolution.

>
>
> >@@ -966,6 +995,7 @@
> > && !is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value,
> >   bool>::type = true>
> > constexpr tuple(_U1&& __a1, _U2&& __a2)
> >+noexcept(__nothrow_constructible<_U1&&,_U2&&>())
>
> There should be a space after the comma here, and all the later
> additions in the file.
ack. Fixed

>
>
> >Index: libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
> >===
> >--- libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
> >(nonexistent)
> >+++ libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc
> >(working copy)
> >@@ -0,0 +1,191 @@
> >+// { dg-options { -std=gnu++2a } }
> >+// { dg-do run { target c++2a } }
>
> This new file doesn't use std::is_nothrow_convertible so 

Adding noexcept-specification on tuple constructors (LWG 2899)

2019-04-16 Thread Nina Dinka Ranns
Tested on Linux-PPC64
Adding noexcept-specification on tuple constructors (LWG 2899)


2019-04-13 Nina Dinka Ranns 

Adding noexcept-specification on tuple constructors (LWG 2899)
* libstdc++-v3/include/std/tuple:
(tuple()): Add noexcept-specification.
(tuple(const _Elements&...)): Likewise
(tuple(_UElements&&...)): Likewise
(tuple(const tuple<_UElements...>&)): Likewise
(tuple(tuple<_UElements...>&&)): Likewise
(tuple(const _T1&, const _T2&)): Likewise
(tuple(_U1&&, _U2&&)): Likewise
(tuple(const tuple<_U1, _U2>&): Likewise
(tuple(tuple<_U1, _U2>&&): Likewise
(tuple(const pair<_U1, _U2>&): Likewise
(tuple(pair<_U1, _U2>&&): Likewise


* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs.cc: New
* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs2.cc: New
* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs3.cc: New
* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs4.cc: New
* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs5.cc: New
* libstdc++-v3/testsuite/20_util/tuple/cons/noexcept_specs6.cc: New


noexcept_tuple.diff
Description: Binary data


Re: [v3 PATCH] Implement C++17 GB50 resolution

2017-02-18 Thread Dinka Ranns
Comments addressed. Please find the new diff attached to this e-mail.

Changelog after review comments :

2017-02-18 Dinka Ranns <dinka.ra...@googlemail.com>

C++17 GB50 resolution
* include/std/chrono:
(duration::operator++()): Add _GLIBCXX17_CONSTEXPR.
(duration::operator++(int)): Likewise
(duration::operator--()): Likewise
(duration::operator--(int)): Likewise
(duration::operator+=(const duration&)): Likewise
(duration::operator-=(const duration&)): Likewise
(duration::operator*=(const rep&)): Likewise
(duration::operator/=(const rep&)): Likewise
(duration::operator%=(const rep&)): Likewise
(duration::operator%=(const duration&)): Likewise
(time_point::operator+=(const duration&)): Likewise
(time_point::operator-=(const duration&)): Likewise

* testsuite/20_util/duration/arithmetic/constexpr_c++17.cc: new tests
* testsuite/20_util/time_point/arithmetic/constexpr.cc: new tests




On 15 February 2017 at 09:35, Jonathan Wakely <jwak...@redhat.com> wrote:
> Hi, Dinka, thanks for the patch.
>
> On 14/02/17 21:22 +, Dinka Ranns wrote:
>>
>> diff --git a/libstdc++-v3/include/std/chrono
>> b/libstdc++-v3/include/std/chrono
>> index ceae7f8..6a6995c 100644
>> --- a/libstdc++-v3/include/std/chrono
>> +++ b/libstdc++-v3/include/std/chrono
>> @@ -349,50 +349,50 @@ _GLIBCXX_END_NAMESPACE_VERSION
>> operator-() const
>> { return duration(-__r); }
>>
>> -   duration&
>> +   constexpr duration&
>
>
> This needs to use _GLIBCXX17_CONSTEXPR instead of 'constexpr'
>
> These functions aren't constexpr in C++11 and C++14, and the standard
> (annoyingly) forbids us from adding constexpr anywhere it isn't
> present in the standard.
>
> The macro _GLIBCXX17_CONSTEXPR expands to 'constexpr' if __cplusplus >
> 201402L, and expands to nothing otherwise.
>
> Each new 'constexpr' you've added needs to use that macro.
>
>> diff --git
>> a/libstdc++-v3/testsuite/20_util/duration/arithmetic/constexpr.cc
>> b/libstdc++-v3/testsuite/20_util/duration/arithmetic/constexpr.cc
>> index 285f941..1128a52 100644
>> --- a/libstdc++-v3/testsuite/20_util/duration/arithmetic/constexpr.cc
>> +++ b/libstdc++-v3/testsuite/20_util/duration/arithmetic/constexpr.cc
>> @@ -19,11 +19,31 @@
>>
>> #include 
>> #include 
>
>
> There should be a blank line before and after this function, however
> ...
>
>> +constexpr auto test_operators()
>> +{
>> +  std::chrono::nanoseconds d1 { };
>> +  d1++;
>
>
> This new function uses C++14 return type deduction, so will fail if
> the test is run in C++11 mode (the default is C++14, but it can be
> overridden on the command-line).
>
>> +  ++d1;
>> +  d1--;
>> +  --d1;
>
>
> Also once you change the new 'constexpr' specifiers to use the
> _GLIBCXX17_CONSTEXPR macro this test will fail in C++14 mode. I think
> this new function needs to be moved to a new test file, such as
> testsuite/20_util/duration/arithmetic/constexpr_c++17.cc
>
> That should contain just your new test_operators() function, because
> the rest of the class will be tested by the existing constexpr.cc test
> file. So something like:
>
> // { dg-options "-std=gnu++17" }
> // { dg-do compile { target c++1z } }
>
> // Copyright etc. etc.
> // ...
>
> #include 
>
> constexpr auto test_operators()
> {
>  // ...
> }
>
> constexpr auto d4 = test_operators();
>
>
> Note that the "dg-do compile" line should use the c++1z target instead
> of c++11, and needs to override the default dialect with a dg-options
> line.
>
> This test doesn't need a "main" function because it's a "dg-do
> compile" test, so isn't linked. (The existing test that you modified
> didn't need one either, but it doesn't do any harm leaving it there).
>
>
>> diff --git
>> a/libstdc++-v3/testsuite/20_util/time_point/arithmetic/constexpr.cc
>> b/libstdc++-v3/testsuite/20_util/time_point/arithmetic/constexpr.cc
>> new file mode 100644
>> index 000..e87a226
>> --- /dev/null
>> +++ b/libstdc++-v3/testsuite/20_util/time_point/arithmetic/constexpr.cc
>> @@ -0,0 +1,39 @@
>> +// { dg-do compile { target c++11 } }
>
>
> Since the time_point member functions will only be constexpr in C++17
> this test also needs to use c++1z instead of c++11, and needs to
> override the default C++14 dialect, i.e.
>
> // { dg-options "-std=gnu++17" }
> // { dg-do compile { target c++1z } }
>
diff --git a/libstdc++-v3/

[v3 PATCH] Implement C++17 GB50 resolution

2017-02-14 Thread Dinka Ranns
Tested on Linux-x64

Implementation of resolution for C++17 GB50

2017-02-12 Dinka Ranns <dinka.ra...@googlemail.com>

C++17 GB50 resolution
* libstdc++-v3/include/std/chrono:
(duration::operator++()): Add constexpr.
(duration::operator++(int)): Likewise
(duration::operator--()): Likewise
(duration::operator--(int)): Likewise
(duration::operator+=(const duration&)): Likewise
(duration::operator-=(const duration&)): Likewise
(duration::operator*=(const rep&)): Likewise
(duration::operator/=(const rep&)): Likewise
(duration::operator%=(const rep&)): Likewise
(duration::operator%=(const duration&)): Likewise
(time_point::operator+=(const duration&)): Likewise
(time_point::operator-=(const duration&)): Likewise

* libstdc++-v3/testsuite/20_util/duration/arithmetic/constexpr.cc:
new tests
* libstdc++-v3/testsuite/20_util/time_point/arithmetic/constexpr.cc: new
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index ceae7f8..6a6995c 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -349,50 +349,50 @@ _GLIBCXX_END_NAMESPACE_VERSION
operator-() const
{ return duration(-__r); }
 
-   duration&
+   constexpr duration&
operator++()
{
  ++__r;
  return *this;
}
 
-   duration
+   constexpr duration
operator++(int)
{ return duration(__r++); }
 
-   duration&
+   constexpr duration&
operator--()
{
  --__r;
  return *this;
}
 
-   duration
+   constexpr duration
operator--(int)
{ return duration(__r--); }
 
-   duration&
+   constexpr duration&
operator+=(const duration& __d)
{
  __r += __d.count();
  return *this;
}
 
-   duration&
+   constexpr duration&
operator-=(const duration& __d)
{
  __r -= __d.count();
  return *this;
}
 
-   duration&
+   constexpr duration&
operator*=(const rep& __rhs)
{
  __r *= __rhs;
  return *this;
}
 
-   duration&
+   constexpr duration&
operator/=(const rep& __rhs)
{
  __r /= __rhs;
@@ -401,7 +401,7 @@ _GLIBCXX_END_NAMESPACE_VERSION
 
// DR 934.
template
- typename enable_if::value,
+ constexpr typename enable_if::value,
 duration&>::type
  operator%=(const rep& __rhs)
  {
@@ -410,7 +410,7 @@ _GLIBCXX_END_NAMESPACE_VERSION
  }
 
template
- typename enable_if::value,
+ constexpr typename enable_if::value,
 duration&>::type
  operator%=(const duration& __d)
  {
@@ -631,14 +631,14 @@ _GLIBCXX_END_NAMESPACE_VERSION
{ return __d; }
 
// arithmetic
-   time_point&
+   constexpr time_point&
operator+=(const duration& __dur)
{
  __d += __dur;
  return *this;
}
 
-   time_point&
+   constexpr time_point&
operator-=(const duration& __dur)
{
  __d -= __dur;
diff --git a/libstdc++-v3/testsuite/20_util/duration/arithmetic/constexpr.cc 
b/libstdc++-v3/testsuite/20_util/duration/arithmetic/constexpr.cc
index 285f941..1128a52 100644
--- a/libstdc++-v3/testsuite/20_util/duration/arithmetic/constexpr.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/arithmetic/constexpr.cc
@@ -19,11 +19,31 @@
 
 #include 
 #include 
+constexpr auto test_operators()
+{
+  std::chrono::nanoseconds d1 { };
+  d1++;
+  ++d1;
+  d1--;
+  --d1;
+
+  auto d2(d1);
+
+  d1+=d2;
+  d1-=d2;
 
+  d1*=1;
+  d1/=1;
+  d1%=1;
+  d1%=d2;
+
+  return d1;
+}
 int main()
 {
   constexpr std::chrono::nanoseconds d1 { };
   constexpr auto d2(+d1);
   constexpr auto d3(-d2);
+  constexpr auto d4 = test_operators();
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/20_util/time_point/arithmetic/constexpr.cc 
b/libstdc++-v3/testsuite/20_util/time_point/arithmetic/constexpr.cc
new file mode 100644
index 000..e87a226
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/time_point/arithmetic/constexpr.cc
@@ -0,0 +1,39 @@
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2011-2016 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