Re: [C++17] Implement N3928 - Extending static_assert

2015-08-04 Thread Paolo Carlini

Hi,

On 06/24/2015 05:32 PM, Ed Smith-Rowland wrote:

Index: testsuite/g++.dg/cpp1z/static_assert-nomsg.C
===
--- testsuite/g++.dg/cpp1z/static_assert-nomsg.C(revision 0)
+++ testsuite/g++.dg/cpp1z/static_assert-nomsg.C(working copy)
@@ -0,0 +1,27 @@
+// { dg-do compile { target c++1z } }
As far as I can see, we can't really use this syntax in the cpp1z 
directory: the testcase is effectively skipped. Indeed, we don't use it 
anywhere else. I'm going to replace it with the straightforward:


// { dg-options -std=c++1z }

Thanks,
Paolo.




Re: [C++17] Implement N3928 - Extending static_assert

2015-06-24 Thread Ed Smith-Rowland

On 06/17/2015 03:22 PM, Jason Merrill wrote:

On 06/17/2015 01:53 PM, Ed Smith-Rowland wrote:

I tried the obvious: an error message with %qE and got 'false'.
constexpr values are evaluated early on.

Is there a possibility that late folding could help or is that
completely different?


Late folding could help, but I think handling it in libcpp (by 
actually stringizing the argument) would work better.


Jason


OK, Doing the bit with libcpp and getting a better message is taking 
longer than I thought it would.

I'm going ahead with what I had back in May.
I'm still working on better - it'll just take a hot minute.

Meanwhile, this takes care of an annoyance for many.

Committed 224903.

Ed

cp/

2015-06-24  Edward Smith-Rowland  3dw...@verizon.net

Implement N3928 - Extending static_assert
* parser.c (cp_parser_static_assert): Support static_assert with
no message string.  Supply an empty string in this case.
* semantics.c (finish_static_assert): Don't try to print a message if
the message strnig is empty.


testsuite/

2015-06-24  Edward Smith-Rowland  3dw...@verizon.net

Implement N3928 - Extending static_assert
* g++.dg/cpp0x/static_assert8.C: Adjust.
* g++.dg/cpp0x/static_assert12.C: New.
* g++.dg/cpp0x/static_assert13.C: New.
* g++.dg/cpp1y/static_assert1.C: New.
* g++.dg/cpp1y/static_assert2.C: New.
* g++.dg/cpp1z/static_assert-nomsg.C: New.

Index: cp/parser.c
===
--- cp/parser.c (revision 224897)
+++ cp/parser.c (working copy)
@@ -12173,6 +12173,7 @@
 
static_assert-declaration:
  static_assert ( constant-expression , string-literal ) ; 
+ static_assert ( constant-expression ) ; (C++1Z)
 
If MEMBER_P, this static_assert is a class member.  */
 
@@ -12210,20 +12211,35 @@
/*allow_non_constant_p=*/true,
/*non_constant_p=*/dummy);
 
-  /* Parse the separating `,'.  */
-  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+  if (cp_lexer_peek_token (parser-lexer)-type == CPP_CLOSE_PAREN)
+{
+  if (cxx_dialect  cxx1z)
+   pedwarn (input_location, OPT_Wpedantic,
+static_assert without a message 
+only available with -std=c++1z or -std=gnu++1z);
+  /* Eat the ')'  */
+  cp_lexer_consume_token (parser-lexer);
+  message = build_string (1, );
+  TREE_TYPE (message) = char_array_type_node;
+  fix_string_type (message);
+}
+  else
+{
+  /* Parse the separating `,'.  */
+  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
 
-  /* Parse the string-literal message.  */
-  message = cp_parser_string_literal (parser, 
-  /*translate=*/false,
-  /*wide_ok=*/true);
+  /* Parse the string-literal message.  */
+  message = cp_parser_string_literal (parser, 
+ /*translate=*/false,
+ /*wide_ok=*/true);
 
-  /* A `)' completes the static assertion.  */
-  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
-cp_parser_skip_to_closing_parenthesis (parser, 
-   /*recovering=*/true, 
-   /*or_comma=*/false,
-  /*consume_paren=*/true);
+  /* A `)' completes the static assertion.  */
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+   cp_parser_skip_to_closing_parenthesis (parser, 
+   /*recovering=*/true, 
+   /*or_comma=*/false,
+  /*consume_paren=*/true);
+}
 
   /* A semicolon terminates the declaration.  */
   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
Index: cp/semantics.c
===
--- cp/semantics.c  (revision 224897)
+++ cp/semantics.c  (working copy)
@@ -7174,8 +7174,17 @@
   input_location = location;
   if (TREE_CODE (condition) == INTEGER_CST 
integer_zerop (condition))
-/* Report the error. */
-error (static assertion failed: %s, TREE_STRING_POINTER (message));
+   {
+ int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
+(TREE_TYPE (TREE_TYPE (message;
+ int len = TREE_STRING_LENGTH (message) / sz - 1;
+  /* Report the error. */
+ if (len == 0)
+error (static assertion failed);
+ else
+error (static assertion failed: %s,
+  TREE_STRING_POINTER (message));
+   }
   else if (condition  condition != error_mark_node)
{
  error (non-constant condition for static assertion);
Index: 

Re: [C++17] Implement N3928 - Extending static_assert

2015-06-17 Thread Jason Merrill

On 06/17/2015 01:53 PM, Ed Smith-Rowland wrote:

I tried the obvious: an error message with %qE and got 'false'.
constexpr values are evaluated early on.

Is there a possibility that late folding could help or is that
completely different?


Late folding could help, but I think handling it in libcpp (by actually 
stringizing the argument) would work better.


Jason



Re: [C++17] Implement N3928 - Extending static_assert

2015-06-17 Thread Ed Smith-Rowland

On 06/17/2015 10:23 AM, Jason Merrill wrote:

On 06/15/2015 07:14 PM, Ed Smith-Rowland wrote:

I wanted to fix it up as per your suggestion.  If someone wants it now I
can retest and commit.  Otherwise give me a bit more time.


Someone in LWG was asking about it, and I figured it wouldn't hurt to 
have this version in now.  Glad to hear you're working on the 
improvement as well, thanks!


Jason


I tried the obvious: an error message with %qE and got 'false'. 
constexpr values are evaluated early on.


Is there a possibility that late folding could help or is that 
completely different?


Ed



Re: [C++17] Implement N3928 - Extending static_assert

2015-06-17 Thread Jason Merrill

On 06/15/2015 07:14 PM, Ed Smith-Rowland wrote:

I wanted to fix it up as per your suggestion.  If someone wants it now I
can retest and commit.  Otherwise give me a bit more time.


Someone in LWG was asking about it, and I figured it wouldn't hurt to 
have this version in now.  Glad to hear you're working on the 
improvement as well, thanks!


Jason



Re: [C++17] Implement N3928 - Extending static_assert

2015-06-15 Thread Jason Merrill

On 05/20/2015 11:28 AM, Jason Merrill wrote:

On 05/02/2015 04:16 PM, Ed Smith-Rowland wrote:

This extends' static assert to not require a message string.
I elected to make this work also for C++11 and C++14 and warn only with
-pedantic.
I think many people just write
   static_assert(thing, );
.

I took the path of building an empty string in the parser in this case.
I wasn't sure if setting message to NULL_TREE would cause sadness later
on or not.


Hmm.  Yes, this technically implements the feature, but my impression of
the (non-normative) intent was that they wanted leaving out the string
to print the argument expression, in about the same way as

#define BOOST_STATIC_ASSERT( B ) static_assert(B, #B)

So the patch is OK as is, but you might also look into some libcpp magic
to insert a second argument that stringizes the first.


Are you planning to check this in?

Jason




Re: [C++17] Implement N3928 - Extending static_assert

2015-06-15 Thread Ed Smith-Rowland

On 06/15/2015 12:05 PM, Jason Merrill wrote:

On 05/20/2015 11:28 AM, Jason Merrill wrote:

On 05/02/2015 04:16 PM, Ed Smith-Rowland wrote:

This extends' static assert to not require a message string.
I elected to make this work also for C++11 and C++14 and warn only with
-pedantic.
I think many people just write
   static_assert(thing, );
.

I took the path of building an empty string in the parser in this case.
I wasn't sure if setting message to NULL_TREE would cause sadness later
on or not.


Hmm.  Yes, this technically implements the feature, but my impression of
the (non-normative) intent was that they wanted leaving out the string
to print the argument expression, in about the same way as

#define BOOST_STATIC_ASSERT( B ) static_assert(B, #B)

So the patch is OK as is, but you might also look into some libcpp magic
to insert a second argument that stringizes the first.


Are you planning to check this in?

Jason





Jason,

I wanted to fix it up as per your suggestion.  If someone wants it now I 
can retest and commit.  Otherwise give me a bit more time.


Also, if you or someone else really has the whole enchilada then by all 
means just commit that.


Ed



Re: [C++17] Implement N3928 - Extending static_assert

2015-05-20 Thread Jason Merrill

On 05/02/2015 04:16 PM, Ed Smith-Rowland wrote:

This extends' static assert to not require a message string.
I elected to make this work also for C++11 and C++14 and warn only with
-pedantic.
I think many people just write
   static_assert(thing, );
.

I took the path of building an empty string in the parser in this case.
I wasn't sure if setting message to NULL_TREE would cause sadness later
on or not.


Hmm.  Yes, this technically implements the feature, but my impression of 
the (non-normative) intent was that they wanted leaving out the string 
to print the argument expression, in about the same way as


#define BOOST_STATIC_ASSERT( B ) static_assert(B, #B)

So the patch is OK as is, but you might also look into some libcpp magic 
to insert a second argument that stringizes the first.


Jason



[PING] [C++17] Implement N3928 - Extending static_assert

2015-05-19 Thread Ed Smith-Rowland

On 05/02/2015 04:16 PM, Ed Smith-Rowland wrote:

This extends' static assert to not require a message string.
I elected to make this work also for C++11 and C++14 and warn only 
with -pedantic.

I think many people just write
  static_assert(thing, );
.

I took the path of building an empty string in the parser in this case.
I wasn't sure if setting message to NULL_TREE would cause sadness 
later on or not.


I also, perhaps in a fit of overzealousness made finish_static_assert 
not print the extra :  and an empty message in this case.


I didn't modify _Static_assert for C.

Built and tested on x86_64-linux.

OK



Ping? Comments?




Re: [C++17] Implement N3928 - Extending static_assert

2015-05-04 Thread Marek Polacek
On Sat, May 02, 2015 at 04:16:18PM -0400, Ed Smith-Rowland wrote:
 This extends' static assert to not require a message string.
 I elected to make this work also for C++11 and C++14 and warn only with
 -pedantic.
 I think many people just write
   static_assert(thing, );
 .
 
 I took the path of building an empty string in the parser in this case.
 I wasn't sure if setting message to NULL_TREE would cause sadness later on
 or not.
 
 I also, perhaps in a fit of overzealousness made finish_static_assert not
 print the extra :  and an empty message in this case.
 
 I didn't modify _Static_assert for C.

I'm not aware of any C DR that is asking for _Static_assert (cst-expr), so
I suppose there's no need to change C at this point.

Marek


[C++17] Implement N3928 - Extending static_assert

2015-05-02 Thread Ed Smith-Rowland

This extends' static assert to not require a message string.
I elected to make this work also for C++11 and C++14 and warn only with 
-pedantic.

I think many people just write
  static_assert(thing, );
.

I took the path of building an empty string in the parser in this case.
I wasn't sure if setting message to NULL_TREE would cause sadness later 
on or not.


I also, perhaps in a fit of overzealousness made finish_static_assert 
not print the extra :  and an empty message in this case.


I didn't modify _Static_assert for C.

Built and tested on x86_64-linux.

OK

cp/

2015-05-02  Edward Smith-Rowland  3dw...@verizon.net

Implement N3928 - Extending static_assert
* parser.c (cp_parser_static_assert): Support static_assert with
no message string.  Supply an empty string in this case.
* semantics.c (finish_static_assert): Don't try to print a message if
the message strnig is empty.


testsuite/

2015-05-02  Edward Smith-Rowland  3dw...@verizon.net

Implement N3928 - Extending static_assert
* g++.dg/cpp0x/static_assert8.C: Adjust.
* g++.dg/cpp0x/static_assert12.C: New.
* g++.dg/cpp0x/static_assert13.C: New.
* g++.dg/cpp1y/static_assert1.C: New.
* g++.dg/cpp1y/static_assert2.C: New.
* g++.dg/cpp1z/static_assert-nomsg.C: New.
Index: cp/parser.c
===
--- cp/parser.c (revision 222723)
+++ cp/parser.c (working copy)
@@ -12153,6 +12153,7 @@
 
static_assert-declaration:
  static_assert ( constant-expression , string-literal ) ; 
+ static_assert ( constant-expression ) ; (C++1Z)
 
If MEMBER_P, this static_assert is a class member.  */
 
@@ -12190,20 +12191,35 @@
/*allow_non_constant_p=*/true,
/*non_constant_p=*/dummy);
 
-  /* Parse the separating `,'.  */
-  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+  if (cp_lexer_peek_token (parser-lexer)-type == CPP_CLOSE_PAREN)
+{
+  if (cxx_dialect  cxx1z)
+   pedwarn (input_location, OPT_Wpedantic,
+static_assert without a message 
+only available with -std=c++1z or -std=gnu++1z);
+  /* Eat the ')'  */
+  cp_lexer_consume_token (parser-lexer);
+  message = build_string (1, );
+  TREE_TYPE (message) = char_array_type_node;
+  fix_string_type (message);
+}
+  else
+{
+  /* Parse the separating `,'.  */
+  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
 
-  /* Parse the string-literal message.  */
-  message = cp_parser_string_literal (parser, 
-  /*translate=*/false,
-  /*wide_ok=*/true);
+  /* Parse the string-literal message.  */
+  message = cp_parser_string_literal (parser, 
+ /*translate=*/false,
+ /*wide_ok=*/true);
 
-  /* A `)' completes the static assertion.  */
-  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
-cp_parser_skip_to_closing_parenthesis (parser, 
-   /*recovering=*/true, 
-   /*or_comma=*/false,
-  /*consume_paren=*/true);
+  /* A `)' completes the static assertion.  */
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+   cp_parser_skip_to_closing_parenthesis (parser, 
+   /*recovering=*/true, 
+   /*or_comma=*/false,
+  /*consume_paren=*/true);
+}
 
   /* A semicolon terminates the declaration.  */
   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
Index: cp/semantics.c
===
--- cp/semantics.c  (revision 222723)
+++ cp/semantics.c  (working copy)
@@ -7184,8 +7184,17 @@
   input_location = location;
   if (TREE_CODE (condition) == INTEGER_CST 
integer_zerop (condition))
-/* Report the error. */
-error (static assertion failed: %s, TREE_STRING_POINTER (message));
+   {
+ int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
+(TREE_TYPE (TREE_TYPE (message;
+ int len = TREE_STRING_LENGTH (message) / sz - 1;
+  /* Report the error. */
+ if (len == 0)
+error (static assertion failed);
+ else
+error (static assertion failed: %s,
+  TREE_STRING_POINTER (message));
+   }
   else if (condition  condition != error_mark_node)
{
  error (non-constant condition for static assertion);
Index: testsuite/g++.dg/cpp0x/static_assert12.C
===
---