From: emsr Date: Wed, 24 Jun 2015 15:27:04 +0000 (+0000) Subject: cp/ X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1f6b3916b7a2d5a5a1ef52f745815b3ffcf11baf;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@224903 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c9c3977a4ee5..197bc77736aa 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 PR c++/65750 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 5150abeec23d..e0e484a4c47c 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 aeb5f7ba2984..c0abeaba1c4c 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 af6d43aa445a..26d39ce9afd9 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 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 000000000000..ff6f40d918fc --- /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 + struct is_float + { + static constexpr bool value = false; + }; + +template<> + struct is_float + { + static constexpr bool value = true; + }; + +template + T + float_thing(T __x) + { + static_assert(is_float::value, ""); // { dg-error "static assertion failed" } + static_assert(is_float::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 000000000000..86b0b0360d94 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/static_assert13.C @@ -0,0 +1,28 @@ +// { dg-do compile } +// { dg-options "-std=gnu++11" } + +template + struct is_float + { + static constexpr bool value = false; + }; + +template<> + struct is_float + { + static constexpr bool value = true; + }; + +template + T + float_thing(T __x) + { + static_assert(is_float::value, ""); // { dg-error "static assertion failed" } + static_assert(is_float::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 ea23afb857df..972f859d6ef9 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 000000000000..513e347d7e59 --- /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 + struct is_float + { + static constexpr bool value = false; + }; + +template<> + struct is_float + { + static constexpr bool value = true; + }; + +template + T + float_thing(T __x) + { + static_assert(is_float::value, ""); // { dg-error "static assertion failed" } + static_assert(is_float::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 000000000000..d862282cda82 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/static_assert2.C @@ -0,0 +1,28 @@ +// { dg-do compile } +// { dg-options "-std=gnu++14" } + +template + struct is_float + { + static constexpr bool value = false; + }; + +template<> + struct is_float + { + static constexpr bool value = true; + }; + +template + T + float_thing(T __x) + { + static_assert(is_float::value, ""); // { dg-error "static assertion failed" } + static_assert(is_float::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 000000000000..3d12e1846759 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/static_assert-nomsg.C @@ -0,0 +1,27 @@ +// { dg-do compile { target c++1z } } + +template + struct is_float + { + static constexpr bool value = false; + }; + +template<> + struct is_float + { + static constexpr bool value = true; + }; + +template + T + float_thing(T __x) + { + static_assert(is_float::value, ""); // { dg-error "static assertion failed" } + static_assert(is_float::value); // { dg-error "static assertion failed" } + } + +int +main() +{ + float_thing(1); +}