Implement N3928 - Extending static_assert
authorEdward Smith-Rowland <3dw4rd@verizon.net>
Wed, 24 Jun 2015 15:27:04 +0000 (15:27 +0000)
committerEdward Smith-Rowland <emsr@gcc.gnu.org>
Wed, 24 Jun 2015 15:27:04 +0000 (15:27 +0000)
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.

From-SVN: r224903

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/static_assert12.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/static_assert13.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/static_assert8.C
gcc/testsuite/g++.dg/cpp1y/static_assert1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/static_assert2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/static_assert-nomsg.C [new file with mode: 0644]

index c9c3977a4ee52092b41d196673b106996a7569f7..197bc77736aad439abf1e2b40774739498fdbd99 100644 (file)
@@ -1,3 +1,11 @@
+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.
+
 2015-06-24  Adam Butcher  <adam@jessamine.co.uk>
 
        PR c++/65750
index 5150abeec23db494c177c45488bc0612e82dfd90..e0e484a4c47ca530f199f7c4c69b3d2dde091a28 100644 (file)
@@ -12173,6 +12173,7 @@ cp_parser_linkage_specification (cp_parser* parser)
 
    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 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
                                    /*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 aeb5f7ba29848db5c039a0db46027ffe0c0c2d38..c0abeaba1c4c0bff8b056b4dcd20191ecf07fdd9 100644 (file)
@@ -7174,8 +7174,17 @@ finish_static_assert (tree condition, tree message, location_t location,
       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 af6d43aa445aede142254c909ce34d6102215758..26d39ce9afd93be53776a8977b673b6432fd9ffd 100644 (file)
@@ -1,3 +1,13 @@
+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.
+
 2015-06-24  Adam Butcher  <adam@jessamine.co.uk>
 
        PR c++/65750
diff --git a/gcc/testsuite/g++.dg/cpp0x/static_assert12.C b/gcc/testsuite/g++.dg/cpp0x/static_assert12.C
new file mode 100644 (file)
index 0000000..ff6f40d
--- /dev/null
@@ -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 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/static_assert13.C b/gcc/testsuite/g++.dg/cpp0x/static_assert13.C
new file mode 100644 (file)
index 0000000..86b0b03
--- /dev/null
@@ -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 ea23afb857df250de410486e4627a3e551fc11c6..972f859d6ef9165ad1b8dec4df4864533857dd17 100644 (file)
@@ -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 }
diff --git a/gcc/testsuite/g++.dg/cpp1y/static_assert1.C b/gcc/testsuite/g++.dg/cpp1y/static_assert1.C
new file mode 100644 (file)
index 0000000..513e347
--- /dev/null
@@ -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 }
diff --git a/gcc/testsuite/g++.dg/cpp1y/static_assert2.C b/gcc/testsuite/g++.dg/cpp1y/static_assert2.C
new file mode 100644 (file)
index 0000000..d862282
--- /dev/null
@@ -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);
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/static_assert-nomsg.C b/gcc/testsuite/g++.dg/cpp1z/static_assert-nomsg.C
new file mode 100644 (file)
index 0000000..3d12e18
--- /dev/null
@@ -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);
+}