public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Ed Smith-Rowland <3dw4rd@verizon.net>
To: Jason Merrill <jason@redhat.com>,
	gcc-patches <gcc-patches@gcc.gnu.org>,
	Paolo Carlini <paolo.carlini@oracle.com>
Subject: Re: [C++17] Implement N3928 - Extending static_assert
Date: Wed, 24 Jun 2015 15:39:00 -0000	[thread overview]
Message-ID: <558ACD9D.2010507@verizon.net> (raw)
In-Reply-To: <5581C912.6050704@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 723 bytes --]

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


[-- Attachment #2: CL_static_assert_nomsg --]
[-- Type: text/plain, Size: 687 bytes --]

cp/

2015-06-24  Edward Smith-Rowland  <3dw4rd@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  <3dw4rd@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.


[-- Attachment #3: patch_static_assert_nomsg_3 --]
[-- Type: text/plain, Size: 8043 bytes --]

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: testsuite/g++.dg/cpp0x/static_assert12.C
===================================================================
--- testsuite/g++.dg/cpp0x/static_assert12.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/static_assert12.C	(working copy)
@@ -0,0 +1,30 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++11 -pedantic" }
+
+template<typename T>
+  struct is_float
+  {
+    static constexpr bool value = false;
+  };
+
+template<>
+  struct is_float<float>
+  {
+    static constexpr bool value = true;
+  };
+
+template<typename T>
+  T
+  float_thing(T __x)
+  {
+    static_assert(is_float<T>::value, ""); // { dg-error "static assertion failed" }
+    static_assert(is_float<T>::value); // { dg-error "static assertion failed" }
+  }
+
+int
+main()
+{
+  float_thing(1);
+}
+
+// { dg-warning "static_assert without a message only available with " "" { target *-*-* } 21 }
Index: testsuite/g++.dg/cpp0x/static_assert13.C
===================================================================
--- testsuite/g++.dg/cpp0x/static_assert13.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/static_assert13.C	(working copy)
@@ -0,0 +1,28 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++11" }
+
+template<typename T>
+  struct is_float
+  {
+    static constexpr bool value = false;
+  };
+
+template<>
+  struct is_float<float>
+  {
+    static constexpr bool value = true;
+  };
+
+template<typename T>
+  T
+  float_thing(T __x)
+  {
+    static_assert(is_float<T>::value, ""); // { dg-error "static assertion failed" }
+    static_assert(is_float<T>::value); // { dg-error "static assertion failed" }
+  }
+
+int
+main()
+{
+  float_thing(1);
+}
Index: testsuite/g++.dg/cpp0x/static_assert8.C
===================================================================
--- testsuite/g++.dg/cpp0x/static_assert8.C	(revision 224897)
+++ testsuite/g++.dg/cpp0x/static_assert8.C	(working copy)
@@ -1,7 +1,9 @@
 // { dg-do compile { target c++11 } }
 
-static_assert (1 == 0); // { dg-error "expected (string-literal|',') before" }
+static_assert (1 == 0); // { dg-error "static assertion failed" }
 
 static_assert (1 == 0,); // { dg-error "expected string-literal before '\\)'" }
 
 static_assert (1 == 0, "oops"); // { dg-error "static assertion failed" }
+
+// { dg-error "static_assert without a message only available with " "" { target *-*-* } 3 }
Index: testsuite/g++.dg/cpp1y/static_assert1.C
===================================================================
--- testsuite/g++.dg/cpp1y/static_assert1.C	(revision 0)
+++ testsuite/g++.dg/cpp1y/static_assert1.C	(working copy)
@@ -0,0 +1,30 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++14 -pedantic" }
+
+template<typename T>
+  struct is_float
+  {
+    static constexpr bool value = false;
+  };
+
+template<>
+  struct is_float<float>
+  {
+    static constexpr bool value = true;
+  };
+
+template<typename T>
+  T
+  float_thing(T __x)
+  {
+    static_assert(is_float<T>::value, ""); // { dg-error "static assertion failed" }
+    static_assert(is_float<T>::value); // { dg-error "static assertion failed" }
+  }
+
+int
+main()
+{
+  float_thing(1);
+}
+
+// { dg-warning "static_assert without a message only available with " "" { target *-*-* } 21 }
Index: testsuite/g++.dg/cpp1y/static_assert2.C
===================================================================
--- testsuite/g++.dg/cpp1y/static_assert2.C	(revision 0)
+++ testsuite/g++.dg/cpp1y/static_assert2.C	(working copy)
@@ -0,0 +1,28 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++14" }
+
+template<typename T>
+  struct is_float
+  {
+    static constexpr bool value = false;
+  };
+
+template<>
+  struct is_float<float>
+  {
+    static constexpr bool value = true;
+  };
+
+template<typename T>
+  T
+  float_thing(T __x)
+  {
+    static_assert(is_float<T>::value, ""); // { dg-error "static assertion failed" }
+    static_assert(is_float<T>::value); // { dg-error "static assertion failed" }
+  }
+
+int
+main()
+{
+  float_thing(1);
+}
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 } }
+
+template<typename T>
+  struct is_float
+  {
+    static constexpr bool value = false;
+  };
+
+template<>
+  struct is_float<float>
+  {
+    static constexpr bool value = true;
+  };
+
+template<typename T>
+  T
+  float_thing(T __x)
+  {
+    static_assert(is_float<T>::value, ""); // { dg-error "static assertion failed" }
+    static_assert(is_float<T>::value); // { dg-error "static assertion failed" }
+  }
+
+int
+main()
+{
+  float_thing(1);
+}

  reply	other threads:[~2015-06-24 15:33 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-02 20:16 Ed Smith-Rowland
2015-05-04 15:28 ` Marek Polacek
2015-05-20  1:56 ` [PING] " Ed Smith-Rowland
2015-05-20 15:29 ` Jason Merrill
2015-06-15 16:07   ` Jason Merrill
2015-06-16  0:37     ` Ed Smith-Rowland
2015-06-17 14:44       ` Jason Merrill
2015-06-17 18:17         ` Ed Smith-Rowland
2015-06-17 19:39           ` Jason Merrill
2015-06-24 15:39             ` Ed Smith-Rowland [this message]
2015-08-04 16:10               ` Paolo Carlini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=558ACD9D.2010507@verizon.net \
    --to=3dw4rd@verizon.net \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    --cc=paolo.carlini@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).