aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Smith-Rowland <3dw4rd@verizon.net>2015-06-24 15:27:04 +0000
committerEdward Smith-Rowland <emsr@gcc.gnu.org>2015-06-24 15:27:04 +0000
commite79fc3d4d72228eeec47b8a53721663371042b8e (patch)
tree58295d23ad987e9a1dc0d61178435cf66c08a320
parentaa97bb6f1229cf69aa17ad7660c3bc63c39ab22b (diff)
downloadgcc-e79fc3d4d72228eeec47b8a53721663371042b8e.zip
gcc-e79fc3d4d72228eeec47b8a53721663371042b8e.tar.gz
gcc-e79fc3d4d72228eeec47b8a53721663371042b8e.tar.bz2
Implement N3928 - Extending static_assert
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
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/parser.c40
-rw-r--r--gcc/cp/semantics.c13
-rw-r--r--gcc/testsuite/ChangeLog10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/static_assert12.C30
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/static_assert13.C28
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/static_assert8.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/static_assert1.C30
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/static_assert2.C28
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/static_assert-nomsg.C27
10 files changed, 203 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c9c3977..197bc77 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 5150abe..e0e484a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index aeb5f7b..c0abeab 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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");
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index af6d43a..26d39ce 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..ff6f40d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/static_assert12.C
@@ -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
index 0000000..86b0b03
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/static_assert13.C
@@ -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);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/static_assert8.C b/gcc/testsuite/g++.dg/cpp0x/static_assert8.C
index ea23afb..972f859 100644
--- a/gcc/testsuite/g++.dg/cpp0x/static_assert8.C
+++ b/gcc/testsuite/g++.dg/cpp0x/static_assert8.C
@@ -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
index 0000000..513e347
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/static_assert1.C
@@ -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
index 0000000..d862282
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/static_assert2.C
@@ -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
index 0000000..3d12e18
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/static_assert-nomsg.C
@@ -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);
+}