[PATCH][libsanitizer] Cherry-pick r211008 [Was: Re: libsanitizer merge from upstream r208536]
Hi, On 06/16/2014 10:42 AM, Konstantin Serebryany wrote: On Wed, Jun 11, 2014 at 2:28 PM, Paolo Carlini paolo.carl...@oracle.com wrote: Hi, On 05/22/2014 09:02 PM, Jakub Jelinek wrote: In file included from ../../../../trunk/libsanitizer/asan/asan_interceptors.cc:147:0: ../../../../trunk/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc: In function ‘int __interceptor_accept4(int, void*, unsigned int*, int)’: ../../../../trunk/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1821:12: warning: ‘addrlen0’ may be used uninitialized in this function [-Wmaybe-uninitialized] unsigned addrlen0; ^ ../../../../trunk/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc: In function ‘int __interceptor_accept(int, void*, unsigned int*)’: ../../../../trunk/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1799:12: warning: ‘addrlen0’ may be used uninitialized in this function [-Wmaybe-uninitialized] unsigned addrlen0; ^ That sounds like a false positive warning: unsigned addrlen0; if (addrlen) { COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); addrlen0 = *addrlen; } int fd2 = REAL(accept4)(fd, addr, addrlen, f); if (fd2 = 0) { if (fd = 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); if (addr addrlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); } (unless the COMMON_INTERCEPTOR* macros do too weird stuff), wonder why the predicate aware uninit doesn't handle this. By the way, I'm still seeing the above. Maybe a maintainer can have a look, double check it's just a false positive a shut it up somehow? I've fixed this in upstream trunk: http://llvm.org/viewvc/llvm-project?view=revisionrevision=211008 This will get into GCC with the next merge; or feel free to cherry pick. Thus, can I apply the below? Thanks! Paolo. / 2014-06-23 Paolo Carlini paolo.carl...@oracle.com * sanitizer_common/sanitizer_common_interceptors.inc: Cherry pick upstream r211008. Index: sanitizer_common/sanitizer_common_interceptors.inc === --- sanitizer_common/sanitizer_common_interceptors.inc (revision 211905) +++ sanitizer_common/sanitizer_common_interceptors.inc (working copy) @@ -1796,7 +1796,7 @@ INTERCEPTOR(int, getsockopt, int sockfd, int level INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); - unsigned addrlen0; + unsigned addrlen0 = 0; if (addrlen) { COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); addrlen0 = *addrlen; @@ -1818,7 +1818,7 @@ INTERCEPTOR(int, accept, int fd, void *addr, unsig INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); - unsigned addrlen0; + unsigned addrlen0 = 0; if (addrlen) { COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); addrlen0 = *addrlen;
[C++ Patch] PR 33972
Hi, in this old rejects-valid we reject: struct s { typedef void f(void); f operator(); }; at the beginning of grokdeclarator: if (((dname IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG) innermost_code != cdk_function ! (ctype !declspecs-any_specifiers_p)) { It seems to me that we can simply remove the check, because a bit later we have: /* Only functions may be declared using an operator-function-id. */ if (unqualified_id IDENTIFIER_OPNAME_P (unqualified_id) TREE_CODE (type) != FUNCTION_TYPE TREE_CODE (type) != METHOD_TYPE) { which uses type and is more precise. Tested x86_64-linux. Thanks! Paolo. /// /cp 2014-06-24 Paolo Carlini paolo.carl...@oracle.com PR c++/33972 * decl.c (grokdeclarator): Do not early check for operator-function-id as non-function. /testsuite 2014-06-24 Paolo Carlini paolo.carl...@oracle.com PR c++/33972 * g++.dg/other/operator3.C: New. * g++.dg/template/operator8.C: Adjust. * g++.dg/template/operator9.C: Likewise. Index: cp/decl.c === --- cp/decl.c (revision 211931) +++ cp/decl.c (working copy) @@ -9007,7 +9007,7 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } - if (((dname IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG) + if (flags == TYPENAME_FLAG innermost_code != cdk_function ! (ctype !declspecs-any_specifiers_p)) { Index: testsuite/g++.dg/other/operator3.C === --- testsuite/g++.dg/other/operator3.C (revision 0) +++ testsuite/g++.dg/other/operator3.C (working copy) @@ -0,0 +1,7 @@ +// PR c++/33972 + +struct s +{ + typedef void f(void); + f operator(); +}; Index: testsuite/g++.dg/template/operator8.C === --- testsuite/g++.dg/template/operator8.C (revision 211931) +++ testsuite/g++.dg/template/operator8.C (working copy) @@ -2,5 +2,5 @@ struct A { -templateoperator+ void foo() {} // { dg-error identifier|non-function|template arguments } +templateoperator+ void foo() {} // { dg-error identifier|parameter|template arguments } }; Index: testsuite/g++.dg/template/operator9.C === --- testsuite/g++.dg/template/operator9.C (revision 211931) +++ testsuite/g++.dg/template/operator9.C (working copy) @@ -1,6 +1,6 @@ //PR c++/27670 -templateoperator+ void foo(); // { dg-error before|non-function|template } +templateoperator+ void foo(); // { dg-error before|parameter|template } void bar() {
[C++ Patch/RFC] PR 49132
Hi, this remained unresolved for a long time, but, if I understand correctly Jason' Comment 1, should be rather easy, just do not complain for uninitialized const members in aggregates, recursively too (per struct B in the testcases). Does the below makes sense, then?!? It passes testing, anyway. I'm also taking the occasion to guard the warnings with complain tf_warning. Thanks, Paolo. / Index: cp/typeck2.c === --- cp/typeck2.c(revision 211955) +++ cp/typeck2.c(working copy) @@ -1342,28 +1342,15 @@ process_init_constructor_record (tree type, tree i next = massage_init_elt (TREE_TYPE (field), next, complain); /* Warn when some struct elements are implicitly initialized. */ - warning (OPT_Wmissing_field_initializers, - missing initializer for member %qD, field); + if (complain tf_warning) + warning (OPT_Wmissing_field_initializers, +missing initializer for member %qD, field); } else { - if (TREE_READONLY (field)) + if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) { if (complain tf_error) - error (uninitialized const member %qD, field); - else - return PICFLAG_ERRONEOUS; - } - else if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field))) - { - if (complain tf_error) - error (member %qD with uninitialized const fields, field); - else - return PICFLAG_ERRONEOUS; - } - else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) - { - if (complain tf_error) error (member %qD is uninitialized reference, field); else return PICFLAG_ERRONEOUS; @@ -1371,8 +1358,9 @@ process_init_constructor_record (tree type, tree i /* Warn when some struct elements are implicitly initialized to zero. */ - warning (OPT_Wmissing_field_initializers, - missing initializer for member %qD, field); + if (complain tf_warning) + warning (OPT_Wmissing_field_initializers, +missing initializer for member %qD, field); if (!zero_init_p (TREE_TYPE (field))) next = build_zero_init (TREE_TYPE (field), /*nelts=*/NULL_TREE, Index: testsuite/g++.dg/cpp0x/aggr1.C === --- testsuite/g++.dg/cpp0x/aggr1.C (revision 0) +++ testsuite/g++.dg/cpp0x/aggr1.C (working copy) @@ -0,0 +1,16 @@ +// PR c++/49132 +// { dg-do compile { target c++11 } } + +struct A { + const int m; +}; + +A a1 = {}; +A a2{}; + +struct B { + A a; +}; + +B b1 = {}; +B b2{}; Index: testsuite/g++.dg/init/aggr11.C === --- testsuite/g++.dg/init/aggr11.C (revision 0) +++ testsuite/g++.dg/init/aggr11.C (working copy) @@ -0,0 +1,13 @@ +// PR c++/49132 + +struct A { + const int m; +}; + +A a1 = {}; + +struct B { + A a; +}; + +B b1 = {};
Re: [C++ Patch/RFC] PR 49132
... in order to handle correctly in C++98 mode (*) the case of references in a member, I think we have to add an explicit check of CLASSTYPE_REF_FIELDS_NEED_INIT, per the below. Thanks, Paolo. (*) For C++11 my previous patch is fine, the TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE check catches also references in members. Index: cp/typeck2.c === --- cp/typeck2.c(revision 211955) +++ cp/typeck2.c(working copy) @@ -1342,37 +1342,32 @@ process_init_constructor_record (tree type, tree i next = massage_init_elt (TREE_TYPE (field), next, complain); /* Warn when some struct elements are implicitly initialized. */ - warning (OPT_Wmissing_field_initializers, - missing initializer for member %qD, field); + if (complain tf_warning) + warning (OPT_Wmissing_field_initializers, +missing initializer for member %qD, field); } else { - if (TREE_READONLY (field)) + if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) { if (complain tf_error) - error (uninitialized const member %qD, field); + error (member %qD is uninitialized reference, field); else return PICFLAG_ERRONEOUS; } - else if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field))) + else if (CLASSTYPE_REF_FIELDS_NEED_INIT (TREE_TYPE (field))) { if (complain tf_error) - error (member %qD with uninitialized const fields, field); + error (member %qD with uninitialized reference fields, field); else return PICFLAG_ERRONEOUS; } - else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) - { - if (complain tf_error) - error (member %qD is uninitialized reference, field); - else - return PICFLAG_ERRONEOUS; - } /* Warn when some struct elements are implicitly initialized to zero. */ - warning (OPT_Wmissing_field_initializers, - missing initializer for member %qD, field); + if (complain tf_warning) + warning (OPT_Wmissing_field_initializers, +missing initializer for member %qD, field); if (!zero_init_p (TREE_TYPE (field))) next = build_zero_init (TREE_TYPE (field), /*nelts=*/NULL_TREE, Index: testsuite/g++.dg/cpp0x/aggr1.C === --- testsuite/g++.dg/cpp0x/aggr1.C (revision 0) +++ testsuite/g++.dg/cpp0x/aggr1.C (working copy) @@ -0,0 +1,16 @@ +// PR c++/49132 +// { dg-do compile { target c++11 } } + +struct A { + const int m; +}; + +A a1 = {}; +A a2{}; + +struct B { + A a; +}; + +B b1 = {}; +B b2{}; Index: testsuite/g++.dg/cpp0x/aggr2.C === --- testsuite/g++.dg/cpp0x/aggr2.C (revision 0) +++ testsuite/g++.dg/cpp0x/aggr2.C (working copy) @@ -0,0 +1,16 @@ +// PR c++/49132 +// { dg-do compile { target c++11 } } + +struct A { + int m; +}; + +A a1 = {}; // { dg-error uninitialized reference } +A a2{}; // { dg-error uninitialized reference } + +struct B { + A a; +}; + +B b1 = {}; // { dg-error uninitialized reference } +B b2{}; // { dg-error uninitialized reference } Index: testsuite/g++.dg/init/aggr11.C === --- testsuite/g++.dg/init/aggr11.C (revision 0) +++ testsuite/g++.dg/init/aggr11.C (working copy) @@ -0,0 +1,13 @@ +// PR c++/49132 + +struct A { + const int m; +}; + +A a1 = {}; + +struct B { + A a; +}; + +B b1 = {}; Index: testsuite/g++.dg/init/aggr12.C === --- testsuite/g++.dg/init/aggr12.C (revision 0) +++ testsuite/g++.dg/init/aggr12.C (working copy) @@ -0,0 +1,13 @@ +// PR c++/49132 + +struct A { + int m; +}; + +A a1 = {}; // { dg-error uninitialized reference } + +struct B { + A a; +}; + +B b1 = {}; // { dg-error uninitialized reference }
Re: [PATCH] Fix PR c++/61537
Hi, On 06/24/2014 01:40 AM, Adam Butcher wrote: +++ b/gcc/testsuite/g++.dg/cpp1y/pr61537.C @@ -0,0 +1,24 @@ +// PR c++/61537 +// { dg-do compile { target c++1y } } I don't think this is a C++1y specific issue... +// { dg-options } Also, likely minor detail, could you please explain why you need this? Thanks for working on the bug! Paolo.
[C++ Patch] Small compound-literal parsing clean up
Hi, should we do something like this? Tested x86_64-linux. Thanks, Paolo. 2014-06-26 Paolo Carlini paolo.carl...@oracle.com * parser.c (cp_parser_compound_literal_p): New. (cp_parser_postfix_expression, cp_parser_sizeof_operand): Use it. Index: parser.c === --- parser.c(revision 212052) +++ parser.c(working copy) @@ -5609,6 +5609,30 @@ cp_parser_qualifying_entity (cp_parser *parser, return scope; } +/* Return true if we are looking at a compound-literal, false otherwise. */ + +static bool +cp_parser_compound_literal_p (cp_parser *parser) +{ + /* Consume the `('. */ + cp_lexer_consume_token (parser-lexer); + + cp_lexer_save_tokens (parser-lexer); + + /* Skip tokens until the next token is a closing parenthesis. + If we find the closing `)', and the next token is a `{', then + we are looking at a compound-literal. */ + bool compound_literal_p += (cp_parser_skip_to_closing_parenthesis (parser, false, false, + /*consume_paren=*/true) +cp_lexer_next_token_is (parser-lexer, CPP_OPEN_BRACE)); + + /* Roll back the tokens we skipped. */ + cp_lexer_rollback_tokens (parser-lexer); + + return compound_literal_p; +} + /* Parse a postfix-expression. postfix-expression: @@ -5917,25 +5941,12 @@ cp_parser_postfix_expression (cp_parser *parser, b cp_lexer_next_token_is (parser-lexer, CPP_OPEN_PAREN)) { tree initializer = NULL_TREE; - bool compound_literal_p; cp_parser_parse_tentatively (parser); - /* Consume the `('. */ - cp_lexer_consume_token (parser-lexer); /* Avoid calling cp_parser_type_id pointlessly, see comment in cp_parser_cast_expression about c++/29234. */ - cp_lexer_save_tokens (parser-lexer); - - compound_literal_p - = (cp_parser_skip_to_closing_parenthesis (parser, false, false, - /*consume_paren=*/true) - cp_lexer_next_token_is (parser-lexer, CPP_OPEN_BRACE)); - - /* Roll back the tokens we skipped. */ - cp_lexer_rollback_tokens (parser-lexer); - - if (!compound_literal_p) + if (!cp_parser_compound_literal_p (parser)) cp_parser_simulate_error (parser); else { @@ -23966,31 +23977,15 @@ cp_parser_sizeof_operand (cp_parser* parser, enum if (cp_lexer_next_token_is (parser-lexer, CPP_OPEN_PAREN)) { tree type = NULL_TREE; - bool compound_literal_p; /* We can't be sure yet whether we're looking at a type-id or an expression. */ cp_parser_parse_tentatively (parser); - /* Consume the `('. */ - cp_lexer_consume_token (parser-lexer); /* Note: as a GNU Extension, compound literals are considered postfix-expressions as they are in C99, so they are valid arguments to sizeof. See comment in cp_parser_cast_expression for details. */ - cp_lexer_save_tokens (parser-lexer); - /* Skip tokens until the next token is a closing parenthesis. -If we find the closing `)', and the next token is a `{', then -we are looking at a compound-literal. */ - compound_literal_p - = (cp_parser_skip_to_closing_parenthesis (parser, false, false, - /*consume_paren=*/true) - cp_lexer_next_token_is (parser-lexer, CPP_OPEN_BRACE)); - /* Roll back the tokens we skipped. */ - cp_lexer_rollback_tokens (parser-lexer); - /* If we were looking at a compound-literal, simulate an error -so that the call to cp_parser_parse_definitely below will -fail. */ - if (compound_literal_p) + if (cp_parser_compound_literal_p (parser)) cp_parser_simulate_error (parser); else {
Re: testsuite allocators patch
Hi, I'm afraid something went badly wrong with this commit, I'm seeing tens of fails. See eg: https://gcc.gnu.org/ml/gcc-testresults/2014-06/msg02439.html Paolo.
Re: testsuite allocators patch
Hi, On 06/27/2014 12:38 AM, Jonathan Wakely wrote: On 26/06/14 23:21 +0200, Paolo Carlini wrote: Hi, I'm afraid something went badly wrong with this commit, I'm seeing tens of fails. See eg: https://gcc.gnu.org/ml/gcc-testresults/2014-06/msg02439.html It seems that uneq_allocator is no longer copy constructible. Can you spot a quick fix, like a thinko, or do you think Francois has to look into it? I'm inclined to revert it for now, the noise is quite annoying... Thanks, Paolo.
Re: [Patch, PR 61061] Add state limit for regex NFA
Hi, On 06/27/2014 05:56 AM, Tim Shen wrote: The limit can be customized by defining a macro _GLIBCXX_REGEX_STATE_LIMIT. The default value is 10. The testcase can be handled if we optimize consecutive quantifiers (collapse them to one). But cases like (a{100}b){100} can't be handled still. We implement range quantifier (foo){n} by copying state sequence (foo) n-1 times. That consumes more space. We may reimplement it (by adding a new _S_op*) someday. Bootstrapped and tested. The actual patch is missing.. ;) Paolo. PS: sorry for being distracted by other issues: what happened to the other regex issue? I think we are simply going to apply, when ready, your more complete fix, right?
Re: [c++-concepts] Change constraint equivalence
Hi, On 06/27/2014 09:41 AM, Braden Obrzut wrote: Are you sure about this? Andrew has been putting everything in ChangeLog.concepts in the root. In terms of general GCC rules, Marek is certainly right. Whether Andrew has (very) special reasons for doing that I don't know, meant to ask for some time, actually. Paolo.
[C++ Patch] PR 61614
Hi, r204228 represented just a small cleanup (https://gcc.gnu.org/ml/gcc-patches/2013-10/msg02597.html) but apparently is causing this small regression present on the release branch too. Shall we simply revert it for now? At least on the branch? Tested x86_64-linux. Thanks, Paolo. / /cp 2014-06-27 Paolo Carlini paolo.carl...@oracle.com PR c++/61614 * semantics.c (finish_compound_literal): Revert r204228. /testsuite 2014-06-27 Paolo Carlini paolo.carl...@oracle.com PR c++/61614 * g++.dg/ext/complit14.C: New. Index: cp/semantics.c === --- cp/semantics.c (revision 212064) +++ cp/semantics.c (working copy) @@ -2607,7 +2607,6 @@ finish_compound_literal (tree type, tree compound_ if ((!at_function_scope_p () || CP_TYPE_CONST_P (type)) TREE_CODE (type) == ARRAY_TYPE !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) - !cp_unevaluated_operand initializer_constant_valid_p (compound_literal, type)) { tree decl = create_temporary_var (type); Index: testsuite/g++.dg/ext/complit14.C === --- testsuite/g++.dg/ext/complit14.C(revision 0) +++ testsuite/g++.dg/ext/complit14.C(working copy) @@ -0,0 +1,11 @@ +// PR c++/61614 +// { dg-options } + +int Fn (...); + +void +Test () +{ + int j = Fn ((const int[]) { 0 });// OK + unsigned long sz = sizeof Fn ((const int[]) { 0 }); // Error +}
Re: [Patch, PR 61061] Add state limit for regex NFA
Hi, On 06/27/2014 06:53 PM, Tim Shen wrote: PS: sorry for being distracted by other issues: what happened to the other regex issue? I think we are simply going to apply, when ready, your more complete fix, right? The problem given in the other PR (PR 61582) is also solved by this patch (but I forgot to mention that); They are all examples like nested range quantifiers. Good, thanks. I'll let Jon properly reviewing the patch, he followed your recent work more closely than me. PR 61424's patch is ready; I was waiting for some Ok go ahead, but now I realize that I need to send the complete patch first :) I'll send it later. Yes, I meant that one, was too lazy to look it up ;) Thanks in advance, anyway! Paolo.
Re: testsuite allocators patch
Hi, On 06/27/2014 07:33 PM, Jonathan Wakely wrote: I didn't see an obvious fix (I'm not sure if the templated constructor can deduce its argument since the change) but have been out all day and not had a chance to look into it. Ok, thanks. I'm reverting the last two libstdc++-v3 commits. Paolo.
Re: [v3] Tighten some config/abi/pre/gnu.ver patterns
Hi, On 06/08/2014 06:02 PM, Paolo Carlini wrote: Hi, as discussed, tested x86_64-linux multilib, committed. for now I reverted this. Things get too complicated when we have to conditionally export some symbols depending on the target (see libstdc++/61536). Thanks, Paolo.
[C++ Patch] PR 51400
Hi, this issue manifests itself as an ICE on the gcc_assert toward the end of start_decl: if (VAR_P (decl) DECL_NAMESPACE_SCOPE_P (decl) !TREE_PUBLIC (decl) !was_public !DECL_THIS_STATIC (decl) !DECL_ARTIFICIAL (decl)) { /* This is a const variable with implicit 'static'. Set DECL_THIS_STATIC so we can tell it from variables that are !TREE_PUBLIC because of the anonymous namespace. */ gcc_assert (CP_TYPE_CONST_P (TREE_TYPE (decl)) || errorcount); DECL_THIS_STATIC (decl) = 1; } and the reason seems clear to me: both handle_noreturn_attribute and handle_const_attribute call build_pointer_type and discard the TYPE_QUALS on the original POINTER_TYPE. That seems obviously incorrect. The below fixes the ICE and passes testing. Thanks! Paolo. / /c-family 2014-06-28 Paolo Carlini paolo.carl...@oracle.com PR c++/51400 * c-common.c (handle_noreturn_attribute, handle_const_attribute): Do not discard TYPE_QUALS of type. /testsuite 2014-06-28 Paolo Carlini paolo.carl...@oracle.com PR c++/51400 * g++.dg/cpp0x/constexpr-attribute3.C: New. Index: c-family/c-common.c === --- c-family/c-common.c (revision 212104) +++ c-family/c-common.c (working copy) @@ -6575,9 +6575,11 @@ handle_noreturn_attribute (tree *node, tree name, else if (TREE_CODE (type) == POINTER_TYPE TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) TREE_TYPE (*node) - = build_pointer_type - (build_type_variant (TREE_TYPE (type), -TYPE_READONLY (TREE_TYPE (type)), 1)); + = (build_qualified_type +(build_pointer_type + (build_type_variant (TREE_TYPE (type), + TYPE_READONLY (TREE_TYPE (type)), 1)), + TYPE_QUALS (type))); else { warning (OPT_Wattributes, %qE attribute ignored, name); @@ -6988,9 +6990,11 @@ handle_const_attribute (tree *node, tree name, tre else if (TREE_CODE (type) == POINTER_TYPE TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) TREE_TYPE (*node) - = build_pointer_type - (build_type_variant (TREE_TYPE (type), 1, -TREE_THIS_VOLATILE (TREE_TYPE (type; + = (build_qualified_type +(build_pointer_type + (build_type_variant (TREE_TYPE (type), 1, + TREE_THIS_VOLATILE (TREE_TYPE (type, + TYPE_QUALS (type))); else { warning (OPT_Wattributes, %qE attribute ignored, name); Index: testsuite/g++.dg/cpp0x/constexpr-attribute3.C === --- testsuite/g++.dg/cpp0x/constexpr-attribute3.C (revision 0) +++ testsuite/g++.dg/cpp0x/constexpr-attribute3.C (working copy) @@ -0,0 +1,5 @@ +// PR c++/51400 +// { dg-do compile { target c++11 } } + +constexpr int (*f)() __attribute__((noreturn)) = 0; +constexpr int (*g)() __attribute__((const)) = 0;
[C++ Patch] PR 54891
Hi, I think it's fair to say that this issue is rather tricky, considering that among the compilers I have at hand none gets it right without regressing on parse/pr26997.C. The basic issue is simple: in C++11 (void)[]{}; is well formed, thus cp_parser_tokens_start_cast_expression should be changed to return non-zero when a '[' follows the parenthesized type-id. Then, however, if we do nothing else we regress on the line: (C ())[2]; of the above testcase, because in that case we have a '[' but in fact we don't have a cast-expression - ie, we don't have a lambda-expression - and we want to parse the whole expression as unary-expression. Thus I figured out that in such ambiguous cases we can avoid committing (we used to call cp_parser_parse_definitely which becomes a conditional cp_parser_commit_to_topmost_tentative_parse) and instead first try cp_parser_cast_expression and then fall back to cp_parser_unary_expression (if cp_parser_parse_definitely returns false after the former). Tested x86_64-linux. Thanks, Paolo. /cp 2014-06-30 Paolo Carlini paolo.carl...@oracle.com PR c++/54891 * parser.c (cp_parser_tokens_start_cast_expression): In C++11 a '[' can also start a primary-expression. (cp_parser_cast_expression): Parse a cast-expression only tentatively when cp_parser_tokens_start_cast_expression returns -1. /testsuite 2014-06-30 Paolo Carlini paolo.carl...@oracle.com PR c++/54891 * g++.dg/cpp0x/lambda/lambda-cast1.C: New. Index: cp/parser.c === --- cp/parser.c (revision 212119) +++ cp/parser.c (working copy) @@ -4109,6 +4109,7 @@ complain_flags (bool decltype_p) this ( expression ) id-expression + lambda-expression (C++11) GNU Extensions: @@ -7621,10 +7622,10 @@ cp_parser_delete_expression (cp_parser* parser) tf_warning_or_error); } -/* Returns true if TOKEN may start a cast-expression and false - otherwise. */ +/* Returns 1 if TOKEN may start a cast-expression and, in C++11, + isn't '[', -1 if the TOKEN is '[' in C++11, 0 otherwise. */ -static bool +static int cp_parser_tokens_start_cast_expression (cp_parser *parser) { cp_token *token = cp_lexer_peek_token (parser-lexer); @@ -7667,7 +7668,7 @@ cp_parser_tokens_start_cast_expression (cp_parser case CPP_OR: case CPP_OR_OR: case CPP_EOF: - return false; + return 0; case CPP_OPEN_PAREN: /* In ((type ()) () the last () isn't a valid cast-expression, @@ -7675,12 +7676,15 @@ cp_parser_tokens_start_cast_expression (cp_parser return cp_lexer_peek_nth_token (parser-lexer, 2)-type != CPP_CLOSE_PAREN; - /* '[' may start a primary-expression in obj-c++. */ + /* '[' may start a primary-expression in obj-c++ and in C++11, +as a lambda expression, eg, '(void)[]{}'. */ case CPP_OPEN_SQUARE: + if (cxx_dialect = cxx11) + return -1; return c_dialect_objc (); default: - return true; + return 1; } } @@ -7705,7 +7709,7 @@ cp_parser_cast_expression (cp_parser *parser, bool { tree type = NULL_TREE; tree expr = NULL_TREE; - bool cast_expression_p; + int cast_expression = 0; const char *saved_message; /* There's no way to know yet whether or not this is a cast. @@ -7728,6 +7732,7 @@ cp_parser_cast_expression (cp_parser *parser, bool will commit to the parse at that point, because we cannot undo the action that is done when creating a new class. So, then we cannot back up and do a postfix-expression. + Another tricky case is the following (c++/29234): struct S { void operator () (); }; @@ -7746,20 +7751,30 @@ cp_parser_cast_expression (cp_parser *parser, bool we are dealing with an unary-expression, a postfix-expression or something else. +Yet another tricky case, in C++11, is the following (c++/54891): + +(void)[]{}; + + The issue is that usually, besides the case of lambda-expressions, +the parenthesized type-id cannot be followed by '[', and, eg, we +want to parse '(C ())[2];' in parse/pr26997.C as unary-expression. +Thus, if cp_parser_tokens_start_cast_expression returns -1, below +we don't commit, we try a cast-expression, then an unary-expression. + Save tokens so that we can put them back. */ cp_lexer_save_tokens (parser-lexer); /* We may be looking at a cast-expression. */ - cast_expression_p - = (cp_parser_skip_to_closing_parenthesis (parser, false, false, - /*consume_paren=*/true) - cp_parser_tokens_start_cast_expression (parser)); + if (cp_parser_skip_to_closing_parenthesis (parser, false, false
Re: [PATCH PR C++/58781, 59867, 60249 ] Various user-defined string literal issues involving character encodings, dropped bytes, semi-infinite loops
... I'm going to commit as obvious the below, to avoid the spurious fail that we are all seeing. Thanks, Paolo. 2014-07-01 Paolo Carlini paolo.carl...@oracle.com * g++.dg/cpp1y/pr59867.C: Fix target selector. Index: g++.dg/cpp1y/pr59867.C === --- g++.dg/cpp1y/pr59867.C (revision 212191) +++ g++.dg/cpp1y/pr59867.C (working copy) @@ -1,7 +1,6 @@ // PR c++/59867 -// { dg-do compile { target c++14 } } +// { dg-do compile { target c++1y } } -#include iostream using namespace std; // constant
[C++ Patch] Replace error + error with error + inform
Hi, noticed these error messages. Tested x86_64-linux. Thanks, Paolo. /// /cp 2014-07-01 Paolo Carlini paolo.carl...@oracle.com * pt.c (convert_template_argument): Use inform instead of error in three places. /testsuite 2014-07-01 Paolo Carlini paolo.carl...@oracle.com * g++.dg/cpp0x/variadic-ex10.C: Adjust for inform instead of error. * g++.dg/cpp0x/variadic-ex14.C: Likewise. * g++.dg/parse/error11.C: Likewise. * g++.old-deja/g++.brendan/template17.C: Likewise. Index: cp/pt.c === --- cp/pt.c (revision 212194) +++ cp/pt.c (working copy) @@ -6468,13 +6468,16 @@ convert_template_argument (tree parm, parameter list for %qD, i + 1, in_decl); if (is_type) - error ( expected a constant of type %qT, got %qT, - TREE_TYPE (parm), - (DECL_P (arg) ? DECL_NAME (arg) : orig_arg)); + inform (input_location, + expected a constant of type %qT, got %qT, + TREE_TYPE (parm), + (DECL_P (arg) ? DECL_NAME (arg) : orig_arg)); else if (requires_tmpl_type) - error ( expected a class template, got %qE, orig_arg); + inform (input_location, + expected a class template, got %qE, orig_arg); else - error ( expected a type, got %qE, orig_arg); + inform (input_location, + expected a type, got %qE, orig_arg); } } return error_mark_node; @@ -6487,9 +6490,11 @@ convert_template_argument (tree parm, parameter list for %qD, i + 1, in_decl); if (is_tmpl_type) - error ( expected a type, got %qT, DECL_NAME (arg)); + inform (input_location, + expected a type, got %qT, DECL_NAME (arg)); else - error ( expected a class template, got %qT, orig_arg); + inform (input_location, + expected a class template, got %qT, orig_arg); } return error_mark_node; } @@ -6537,8 +6542,9 @@ convert_template_argument (tree parm, error (type/value mismatch at argument %d in template parameter list for %qD, i + 1, in_decl); - error ( expected a template of type %qD, got %qT, -parm, orig_arg); + inform (input_location, + expected a template of type %qD, got %qT, + parm, orig_arg); } val = error_mark_node; Index: testsuite/g++.dg/cpp0x/variadic-ex10.C === --- testsuite/g++.dg/cpp0x/variadic-ex10.C (revision 212194) +++ testsuite/g++.dg/cpp0x/variadic-ex10.C (working copy) @@ -5,5 +5,5 @@ Tuple t0; // Types contains no arguments Tupleint t1; // Types contains one argument: int Tupleint, float t2; // Types contains two arguments: int and float Tuple0 error; // { dg-error mismatch mismatch } -// { dg-error expected a type expected a type { target *-*-* } 7 } +// { dg-message expected a type expected a type { target *-*-* } 7 } // { dg-error in declaration in declaration { target *-*-* } 7 } Index: testsuite/g++.dg/cpp0x/variadic-ex14.C === --- testsuite/g++.dg/cpp0x/variadic-ex14.C (revision 212194) +++ testsuite/g++.dg/cpp0x/variadic-ex14.C (working copy) @@ -9,10 +9,10 @@ templatetemplateclass... class Q class Y { /* XA xA; // okay XB xB; // { dg-error mismatch mismatch } -// { dg-error expected a template expected { target *-*-* } 11 } +// { dg-message expected a template expected { target *-*-* } 11 } // { dg-error invalid type invalid { target *-*-* } 11 } XC xC; // { dg-error mismatch mismatch } -// { dg-error expected a template expected { target *-*-* } 14 } +// { dg-message expected a template expected { target *-*-* } 14 } // { dg-error invalid type invalid { target *-*-* } 14 } YA yA; YB yB; Index: testsuite/g++.dg/parse/error11.C === --- testsuite/g++.dg/parse/error11.C(revision 212194) +++ testsuite/g++.dg/parse/error11.C(working copy) @@ -33,7 +33,7 @@ template int N struct Foo2 {}; template struct Foo2::B; // { dg-error 21:'::' cannot begin begin { target { ! c++11 } } } // { dg-message 21:':' is an alternate alt { target { ! c++11 } } 33 } // { dg-message 25:type/value mismatch mismatch { target *-*-* } 33 } -// { dg-error 25:expected a constant const { target *-*-* } 33 } +// { dg-message 25:expected a constant const { target *-*-* } 33
Re: Ok to backport r210653 (fix for PR58930) to gcc-4_9-branch?
Hi, On 07/01/2014 08:49 PM, Paul Pluzhnikov wrote: Index: gcc/testsuite/g++.dg/cpp0x/nsdmi-template11.C === --- gcc/testsuite/g++.dg/cpp0x/nsdmi-template11.C (revision 0) +++ gcc/testsuite/g++.dg/cpp0x/nsdmi-template11.C (revision 212207) @@ -0,0 +1,30 @@ +// PR c++/58930 +// { dg-do compile { target c++11 } } + +struct SampleModule +{ + explicit SampleModule (int); +}; + +template typename +struct BaseHandler +{ + SampleModule module_ { 0 }; +}; + +BaseHandlerint a; +// PR c++/58930 +// { dg-do compile { target c++11 } } + +struct SampleModule +{ + explicit SampleModule (int); +}; + +template typename +struct BaseHandler +{ + SampleModule module_ { 0 }; +}; + +BaseHandlerint a; If this is what you actually committed, something went wrong with the testcases... Paolo.
[C++ Patch] PR 51448, 53618, 58059
Hi, some time ago I started analyzing the bugs in Bugzilla involving crashes for too deep recursive template instantiation and figured out that this subset is probably the simplest to tackle (https://gcc.gnu.org/ml/gcc-patches/2013-08/msg01348.html). All these crashes involve instantiate_class_template_1 *before* the existing push_tinst_level check, via most_specialized_class, and I think it makes sense to protect it in a way very similar to that used in maybe_instantiate_noexcept. Lately I also tried simply moving the existing check before most_specialized_class and it mostly worked for C++, but regressions showed up in the libstdc++-v3 testsuite (mostly in 20_util). As regards the testcases, template/recurse.C is tweaked because the diagnostic about template instantiation depth exceed is exactly the same but isn't duplicated anymore. Anyway, tested x86_64-linux. Thanks, Paolo. / /cp 2014-07-01 Paolo Carlini paolo.carl...@oracle.com PR c++/51488 PR c++/53618 PR c++/58059 * pt.c (instantiate_class_template_1): Call push_tinst_level / pop_tinst_level around most_specialized_class. /testsuite 2014-07-01 Paolo Carlini paolo.carl...@oracle.com PR c++/51488 PR c++/53618 PR c++/58059 * g++.dg/cpp0x/template-recurse1.C: New. * g++.dg/template/recurse4.C: Likewise. * g++.dg/template/recurse.C: Adjust. Index: cp/pt.c === --- cp/pt.c (revision 212204) +++ cp/pt.c (working copy) @@ -8905,8 +8911,15 @@ instantiate_class_template_1 (tree type) gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL); /* Determine what specialization of the original template to - instantiate. */ - t = most_specialized_class (type, tf_warning_or_error); + instantiate. Note: protect vs too deep instantiation. */ + if (push_tinst_level (type)) +{ + t = most_specialized_class (type, tf_warning_or_error); + pop_tinst_level (); +} + else +t = error_mark_node; + if (t == error_mark_node) { TYPE_BEING_DEFINED (type) = 1; Index: testsuite/g++.dg/cpp0x/template-recurse1.C === --- testsuite/g++.dg/cpp0x/template-recurse1.C (revision 0) +++ testsuite/g++.dg/cpp0x/template-recurse1.C (working copy) @@ -0,0 +1,25 @@ +// PR c++/58059 +// { dg-do compile { target c++11 } } + +templatebool, typename T = void struct enable_if { typedef T type; }; +templatetypename T struct enable_iffalse, T { }; + +// This code is nonsense; it was produced by minimizing the problem repeatedly. +constexpr bool test_func(int value) { + return true; +} +template int TParm, class Enable=void +struct test_class { + static constexpr int value = 0; +}; +template int TParm +struct test_class +TParm, +// This line ultimately causes the crash. +typename enable_iftest_func(test_classTParm-1::value)::type // { dg-error depth exceeds } + { + static constexpr int value = 1; +}; + +// This instantiation is required in order to crash. +template class test_class2,void; Index: testsuite/g++.dg/template/recurse.C === --- testsuite/g++.dg/template/recurse.C (revision 212204) +++ testsuite/g++.dg/template/recurse.C (working copy) @@ -5,9 +5,7 @@ template int I struct F { int operator()() { - FI+1 f;// { dg-error incomplete type incomplete } - // { dg-bogus exceeds maximum.*exceeds maximum exceeds { xfail *-*-* } 8 } -// { dg-error exceeds maximum exceeds { xfail *-*-* } 8 } + FI+1 f;// { dg-error depth exceeds|incomplete } return f()*I; // { dg-message recursively recurse } } }; Index: testsuite/g++.dg/template/recurse4.C === --- testsuite/g++.dg/template/recurse4.C(revision 0) +++ testsuite/g++.dg/template/recurse4.C(working copy) @@ -0,0 +1,5 @@ +// PR c++/51488 + +templateclass T,class U=void struct s; +templateclass T struct sT,typename sT::a {}; +sint ca; // { dg-error depth exceeds|incomplete }
Re: [C++ Patch] PR 51448, 53618, 58059
.. consider this patch withdrawn. I believe that something is going wrong indeed as part of most_specialized_instantiation but the details need to be figured out. I'm now focusing on fn_type_unification via get_bindings. Paolo.
Re: [C++ Patch] PR 51448, 53618, 58059
Hi again, On 07/02/2014 05:06 PM, Paolo Carlini wrote: .. consider this patch withdrawn. I believe that something is going wrong indeed as part of most_specialized_instantiation but the details need to be figured out. I'm now focusing on fn_type_unification via get_bindings. In fact my typo above most_specialized_instantiation vs most_specialized class reveals something: we don't seem to have an analogous for *classes* of the mechanism implemented in fn_type_unification for functions, and all the testcases I'm handling involve *classes*. Paolo.
[C++ Patch] PR 51448, 53618, 58059 (Take 2)
Hi again, this is IMHO more spot-on, because I figured out where exactly things go wrong as part of the most_specialized_class call. In complete analogy with the get_bindings case for functions, the problem happens in get_class_bindings, thus I added a simple push_tinst_level check around the tsubst there, which works fine for the testcases we have in this area. Tested x86_64-linux. Thanks, Paolo. / /cp 2014-07-03 Paolo Carlini paolo.carl...@oracle.com PR c++/51488 PR c++/53618 PR c++/58059 * pt.c (get_class_bindings): Call push_tinst_level/pop_tinst_level around tsubst. /testsuite 2014-07-03 Paolo Carlini paolo.carl...@oracle.com PR c++/51488 PR c++/53618 PR c++/58059 * g++.dg/cpp0x/template-recurse1.C: New. * g++.dg/template/recurse4.C: Likewise. * g++.dg/template/recurse.C: Adjust. Index: cp/pt.c === --- cp/pt.c (revision 212223) +++ cp/pt.c (working copy) @@ -18826,6 +18826,13 @@ get_class_bindings (tree tmpl, tree tparms, tree s if (! TREE_VEC_ELT (innermost_deduced_args, i)) return NULL_TREE; + tree tinst = build_tree_list (tmpl, args); + if (! push_tinst_level (tinst)) +{ + ggc_free (tinst); + return NULL_TREE; +} + /* Verify that nondeduced template arguments agree with the type obtained from argument deduction. @@ -18839,6 +18846,9 @@ get_class_bindings (tree tmpl, tree tparms, tree s `T' is `A' but unify () does not check whether `typename T::X' is `int'. */ spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE); + + pop_tinst_level (); + spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), spec_args, tmpl, tf_none, false, false); Index: testsuite/g++.dg/cpp0x/template-recurse1.C === --- testsuite/g++.dg/cpp0x/template-recurse1.C (revision 0) +++ testsuite/g++.dg/cpp0x/template-recurse1.C (working copy) @@ -0,0 +1,25 @@ +// PR c++/58059 +// { dg-do compile { target c++11 } } + +templatebool, typename T = void struct enable_if { typedef T type; }; +templatetypename T struct enable_iffalse, T { }; + +// This code is nonsense; it was produced by minimizing the problem repeatedly. +constexpr bool test_func(int value) { + return true; +} +template int TParm, class Enable=void +struct test_class { + static constexpr int value = 0; +}; +template int TParm +struct test_class +TParm, +// This line ultimately causes the crash. +typename enable_iftest_func(test_classTParm-1::value)::type // { dg-error depth exceeds } + { + static constexpr int value = 1; +}; + +// This instantiation is required in order to crash. +template class test_class2,void; Index: testsuite/g++.dg/template/recurse.C === --- testsuite/g++.dg/template/recurse.C (revision 21) +++ testsuite/g++.dg/template/recurse.C (working copy) @@ -5,9 +5,7 @@ template int I struct F { int operator()() { - FI+1 f;// { dg-error incomplete type incomplete } - // { dg-bogus exceeds maximum.*exceeds maximum exceeds { xfail *-*-* } 8 } -// { dg-error exceeds maximum exceeds { xfail *-*-* } 8 } + FI+1 f;// { dg-error depth exceeds|incomplete } return f()*I; // { dg-message recursively recurse } } }; Index: testsuite/g++.dg/template/recurse4.C === --- testsuite/g++.dg/template/recurse4.C(revision 0) +++ testsuite/g++.dg/template/recurse4.C(working copy) @@ -0,0 +1,5 @@ +// PR c++/51488 + +templateclass T,class U=void struct s; +templateclass T struct sT,typename sT::a {}; +sint ca; // { dg-error depth exceeds|incomplete }
Re: [Patch, PR 61720] Clear regex BFS match queue after every iteration
Hi, On 07/06/2014 10:56 AM, Tim Shen wrote: This bug shouldn't be introduced, if I wrote clearer code last summer. Sorry :(. The _Executor is a little bit messy. The _M_match_queue is not cleared because it's treated `globally` between iterations (in _M_main_dispatch(..., __bfs)). Add a new file general_testcases.cc; we can gradually move test cases to this single file to reduce duplicated compilation in testing? Patch itself looks obvious to me, but I don't understand the general_testcases.cc idea, do we have something similar elsewhere in library or compiler?!? I would say, let's just add a normal testcase and close the bug (mainline and branch I suppose) Thanks, Paolo.
Re: [Patch, PR 61720] Clear regex BFS match queue after every iteration
Hi, On 07/06/2014 08:20 PM, Tim Shen wrote: I'd like to merge testcases to several huge files (char, wchar_t, dg-do compile, locales, etc.) to (greatly) reduce duplicated regex compilation. We do not really care the fine-grained test report, do we? We hope them all PASS. Yes. As long as it's possible to tell which part of test fails when something doesn't pass, that's fine. Bah... too bad we have to resort to this. Then please summarize the discussion at the beginning of the file: what the file is *exactly* for (an accidental contributor should be able to understand if and what should go in it) and why it does exist in the first place. Also, please remember the test variables. Paolo.
[C++ Patch] PR 59361
Hi, in April Andrew figured out that: The problem occurs in cp_parser_cast_expression. A term of having the form (T())... cannot be parsed as a cast expression since the the expansion is only applied to a part of the cast expression. If ... follows the closing paren, the expression must be parsed as unary expression. Today I simplified a bit his patch, moving the CPP_ELLIPSIS handling inside cp_parser_tokens_start_cast_expression. Tested x86_64-linux. Thanks, Paolo. // /cp 2014-07-07 Andrew Sutton andrew.n.sut...@gmail.com Paolo Carlini paolo.carl...@oracle.com PR c++/59361 * parser.c (cp_parser_tokens_start_cast_expression): Return 0 for CPP_ELLIPSIS too. /testsuite 2014-07-07 Andrew Sutton andrew.n.sut...@gmail.com Paolo Carlini paolo.carl...@oracle.com PR c++/59361 * g++.dg/cpp0x/vt-59361.C: New. Index: cp/parser.c === --- cp/parser.c (revision 212324) +++ cp/parser.c (working copy) @@ -7666,6 +7666,7 @@ cp_parser_tokens_start_cast_expression (cp_parser case CPP_OR: case CPP_OR_OR: case CPP_EOF: +case CPP_ELLIPSIS: return 0; case CPP_OPEN_PAREN: Index: testsuite/g++.dg/cpp0x/vt-59361.C === --- testsuite/g++.dg/cpp0x/vt-59361.C (revision 0) +++ testsuite/g++.dg/cpp0x/vt-59361.C (working copy) @@ -0,0 +1,20 @@ +// PR c++/59361 +// { dg-do compile { target c++11 } } + +templatebool ...Bs +struct and_ +{ + constexpr static bool value{true}; +}; + +templatetypename T +struct true_ +{ + constexpr operator bool() const { return true; } +}; + +templatetypename ...Ts +constexpr bool foo(Ts...) +{ + return and_(true_Ts())...::value; +}
[C++ Patch, obvious] Use %final% and %override% in error messages
Hi, tested x86_64-linux, committed as obvious. Thanks, Paolo. /cp 2014-07-07 Paolo Carlini paolo.carl...@oracle.com * class.c (check_for_override): Wrap the 'final' and 'override' keywords in % and %. /testsuite 2014-07-07 Paolo Carlini paolo.carl...@oracle.com * g++.dg/cpp0x/override1.C: Tweak expected error messages. Index: cp/class.c === --- cp/class.c (revision 212330) +++ cp/class.c (working copy) @@ -2771,9 +2771,9 @@ check_for_override (tree decl, tree ctype) TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true; } else if (DECL_FINAL_P (decl)) -error (%q+#D marked final, but is not virtual, decl); +error (%q+#D marked %final%, but is not virtual, decl); if (DECL_OVERRIDE_P (decl) !overrides_found) -error (%q+#D marked override, but does not override, decl); +error (%q+#D marked %override%, but does not override, decl); } /* Warn about hidden virtual functions that are not overridden in t. Index: testsuite/g++.dg/cpp0x/override1.C === --- testsuite/g++.dg/cpp0x/override1.C (revision 212330) +++ testsuite/g++.dg/cpp0x/override1.C (working copy) @@ -18,7 +18,7 @@ struct D : B template class T struct D2 : T { - void h() override {} // { dg-error marked override, but does not override } + void h() override {} // { dg-error marked 'override', but does not override } }; template class T struct D3 : T @@ -38,14 +38,14 @@ struct B3 struct B4 { - void f() final {} // { dg-error marked final, but is not virtual } + void f() final {} // { dg-error marked 'final', but is not virtual } }; struct D5 : B { - void ff() override {} // { dg-error marked override, but does not override } - virtual void fff() override {} // { dg-error marked override, but does not override } - virtual void x() override {} // { dg-error marked override, but does not override } + void ff() override {} // { dg-error marked 'override', but does not override } + virtual void fff() override {} // { dg-error marked 'override', but does not override } + virtual void x() override {} // { dg-error marked 'override', but does not override } void g() override; };
[C++ Patch] PR 60686
Hi, in this bug submitter noticed that talking only about explicit constructors without mentioning conversion operators is misleading in C++11. Thus Jon suggested simply not mentioning the constructors in the error message, which I find reasonable because after all it's about the fact that the user has 'explicit' on the definition, not about 'explicit' being used on the wrong type of declaration. Certainly anyway, another option would be extending the current error message and mention conversion operators too or even providing different error messages for C++98 and C++11 (maybe overkill considering that we do *accept* explicit operators in C++98 mode, we only emit a pedwarn). Tested x86_64-linux. Thanks, Paolo. /// /cp 2014-07-07 Jonathan Wakely jwak...@redhat.com Paolo Carlini paolo.carl...@oracle.com PR c++/60686 * decl.c (grokdeclarator): Adjust error message about 'explicit' outside class definition for C++11. /testsuite 2014-07-07 Jonathan Wakely jwak...@redhat.com Paolo Carlini paolo.carl...@oracle.com PR c++/60686 * g++.dg/cpp0x/explicit8.C: New. Index: cp/decl.c === --- cp/decl.c (revision 212332) +++ cp/decl.c (working copy) @@ -10117,9 +10117,10 @@ grokdeclarator (const cp_declarator *declarator, if (explicitp == 1 || (explicitp friendp)) { - /* [dcl.fct.spec] The explicit specifier shall only be used in -declarations of constructors within a class definition. */ - error (only declarations of constructors can be %explicit%); + /* [dcl.fct.spec] (C++11) The explicit specifier shall be used only +in the declaration of a constructor or conversion function within +a class definition. */ + error (only declarations can be marked %explicit%); explicitp = 0; } Index: testsuite/g++.dg/cpp0x/explicit8.C === --- testsuite/g++.dg/cpp0x/explicit8.C (revision 0) +++ testsuite/g++.dg/cpp0x/explicit8.C (working copy) @@ -0,0 +1,8 @@ +// PR c++/60686 +// { dg-do compile { target c++11 } } + +struct A { + explicit operator int() const; +}; + +explicit inline A::operator int() const { return 1; } // { dg-error only declarations can be marked 'explicit' }
[C++ Patch] PR 57466 (DR 1584)
Hi, the defect (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584) is Ready and both clang and SolarisStudio already implement it. The below very simple tweak seems enough, testing is fine on x86_64-linux. Thanks! Paolo. / /cp 2014-07-08 Paolo Carlini paolo.carl...@oracle.com DR 1584 PR c++/57466 * pt.c (unify): Implement resolution, disregard cv-qualifiers of function types. /testsuite 2014-07-08 Paolo Carlini paolo.carl...@oracle.com DR 1584 PR c++/57466 * g++.dg/template/pr57466.C: New. * g++.dg/cpp0x/pr57466.C: Likewise. * g++.dg/template/unify6.C: Update. Index: cp/pt.c === --- cp/pt.c (revision 212347) +++ cp/pt.c (working copy) @@ -17831,8 +17831,13 @@ unify (tree tparms, tree targs, tree parm, tree ar a match unless we are allowing additional qualification. If ARG is `const int' and PARM is just `T' that's OK; that binds `const int' to `T'. */ - if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL, -arg, parm)) + + /* DR 1584: cv-qualification of a deduced function type is +ignored; see 8.3.5 [dcl.fct]. */ + if (TREE_CODE (arg) != FUNCTION_TYPE + !check_cv_quals_for_unify (strict_in + | UNIFY_ALLOW_LESS_CV_QUAL, + arg, parm)) return unify_cv_qual_mismatch (explain_p, parm, arg); /* Consider the case where ARG is `const volatile int' and Index: testsuite/g++.dg/cpp0x/pr57466.C === --- testsuite/g++.dg/cpp0x/pr57466.C(revision 0) +++ testsuite/g++.dg/cpp0x/pr57466.C(working copy) @@ -0,0 +1,18 @@ +// PR c++/57466 +// { dg-do compile { target c++11 } } + +templatetypename T + constexpr bool + is_pointer(const T*) + { return true; } + +templatetypename T + constexpr bool + is_pointer(const T) + { return false; } + +using F = void(); + +constexpr F* f = nullptr; + +static_assert( is_pointer(f), function pointer is a pointer ); Index: testsuite/g++.dg/template/pr57466.C === --- testsuite/g++.dg/template/pr57466.C (revision 0) +++ testsuite/g++.dg/template/pr57466.C (working copy) @@ -0,0 +1,8 @@ +// DR 1584, PR c++/57466 + +templateclass T void f2(const T*); +void g2(); + +void m() { + f2(g2);// OK: cv-qualification of deduced function type ignored +} Index: testsuite/g++.dg/template/unify6.C === --- testsuite/g++.dg/template/unify6.C (revision 212347) +++ testsuite/g++.dg/template/unify6.C (working copy) @@ -3,21 +3,20 @@ void Baz (); -template typename T void Foo1 (T *); // #1 -template typename T void Foo1 (T const *a) {a (1);} // #2 +template typename T void Foo1 (T *); +template typename T void Foo1 (T const *a) {a (1);} // { dg-error too many arguments } template typename T T const *Foo2 (T *); -template typename T void Foo3 (T *, T const * = 0); // { dg-message note } +template typename T void Foo3 (T *, T const * = 0); void Bar () { - Foo1 (Baz); // #1 + Foo1 (Baz); // { dg-message required from here } Foo2 (Baz); Foo3 (Baz); - Foo3 (Baz, Baz); // { dg-error no matching function } - // { dg-message (candidate|incompatible cv-qualifiers) candidate note { target *-*-* } 21 } + Foo3 (Baz, Baz); }
Re: [Patch, PR 61720] Clear regex BFS match queue after every iteration
Hi, On 07/09/2014 03:53 AM, Tim Shen wrote: +// This file is for general testcases in regex. +// We use a single file for multiple testcases because it takes too long to +// compile regex for each testcase in a single file. +// Normal testcases in other files should be moved into this file in the future. Thus the plan would be *all* the regex testcases in a single file!?! If I understand correctly, that certainly doesn't make sense. In any case, I don't want this detail to slow down fixing the bug, thus please commit fix + normal testcase mainline and branch and then we'll take our time discussing the testing issue (I'm also meeting Jon face to face in a few days...) By the way, are we sure that the various regex testcases are enabled to run in parallel in the testsuite? Thanks, Paolo.
Re: [Patch, PR 61720] Clear regex BFS match queue after every iteration
Hi, On 07/09/2014 10:08 AM, Jonathan Wakely wrote: All the 28_regex tests run as part of the same target: normal7) \ dirs=`cd $$srcdir; echo 26_*/* 28_*/[c-z]*`;; \ I've tried moving the 26_numeric tests to a different target but it doesn't make much difference, the regex tests still take longer than any other target. We could try splitting up the 28_regex tests across two targets, but the fact is that it takes 2-5 seconds to compile any test using std::regex, so the more tests we add the slower the testsuite gets. I'm not an expert in this area, but my guess is indeed that it would be beneficial to split up 28_regex across multiple targets, why not more than 2, I would try 4 for example. In general, I agree it would certainly make sense grouping the tests, but not all in a single file! Anyway, let's fix this bug first. Paolo.
Re: [C++ Patch] PR 57466 (DR 1584)
Hi, On 07/09/2014 12:26 AM, Jason Merrill wrote: I'd rather handle this in check_cv_quals_for_unify. Yes, the below passes testing. Thanks, Paolo. / /cp 2014-07-09 Paolo Carlini paolo.carl...@oracle.com DR 1584 PR c++/57466 * pt.c (check_cv_quals_for_unify): Implement resolution, disregard cv-qualifiers of function types. /testsuite 2014-07-09 Paolo Carlini paolo.carl...@oracle.com DR 1584 PR c++/57466 * g++.dg/template/pr57466.C: New. * g++.dg/cpp0x/pr57466.C: Likewise. * g++.dg/template/unify6.C: Update. Index: cp/pt.c === --- cp/pt.c (revision 212385) +++ cp/pt.c (working copy) @@ -17189,6 +17189,11 @@ check_cv_quals_for_unify (int strict, tree arg, tr int arg_quals = cp_type_quals (arg); int parm_quals = cp_type_quals (parm); + /* DR 1584: cv-qualification of a deduced function type is + ignored; see 8.3.5 [dcl.fct]. */ + if (TREE_CODE (arg) == FUNCTION_TYPE) +return 1; + if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM !(strict UNIFY_ALLOW_OUTER_MORE_CV_QUAL)) { Index: testsuite/g++.dg/cpp0x/pr57466.C === --- testsuite/g++.dg/cpp0x/pr57466.C(revision 0) +++ testsuite/g++.dg/cpp0x/pr57466.C(working copy) @@ -0,0 +1,18 @@ +// PR c++/57466 +// { dg-do compile { target c++11 } } + +templatetypename T + constexpr bool + is_pointer(const T*) + { return true; } + +templatetypename T + constexpr bool + is_pointer(const T) + { return false; } + +using F = void(); + +constexpr F* f = nullptr; + +static_assert( is_pointer(f), function pointer is a pointer ); Index: testsuite/g++.dg/template/pr57466.C === --- testsuite/g++.dg/template/pr57466.C (revision 0) +++ testsuite/g++.dg/template/pr57466.C (working copy) @@ -0,0 +1,8 @@ +// DR 1584, PR c++/57466 + +templateclass T void f2(const T*); +void g2(); + +void m() { + f2(g2);// OK: cv-qualification of deduced function type ignored +} Index: testsuite/g++.dg/template/unify6.C === --- testsuite/g++.dg/template/unify6.C (revision 212385) +++ testsuite/g++.dg/template/unify6.C (working copy) @@ -3,21 +3,20 @@ void Baz (); -template typename T void Foo1 (T *); // #1 -template typename T void Foo1 (T const *a) {a (1);} // #2 +template typename T void Foo1 (T *); +template typename T void Foo1 (T const *a) {a (1);} // { dg-error too many arguments } template typename T T const *Foo2 (T *); -template typename T void Foo3 (T *, T const * = 0); // { dg-message note } +template typename T void Foo3 (T *, T const * = 0); void Bar () { - Foo1 (Baz); // #1 + Foo1 (Baz); // { dg-message required from here } Foo2 (Baz); Foo3 (Baz); - Foo3 (Baz, Baz); // { dg-error no matching function } - // { dg-message (candidate|incompatible cv-qualifiers) candidate note { target *-*-* } 21 } + Foo3 (Baz, Baz); }
Re: [C++ Patch] PR 60686
Hi, On 07/09/2014 12:39 AM, Jason Merrill wrote: On 07/07/2014 11:15 AM, Paolo Carlini wrote: + error (only declarations can be marked %explicit%); That's pretty unclear, since a definition is a declaration. Let's split this into three error messages: If the problem is that we're outside the class, we should say that. If the problem is that it's not a constructor or conversion function, we should say that. If the problem is that it's not a member of the current class, we should say that. Ok. In terms of wording, for the first case we can consistently follow the example of 'virtual'. For the second case, we can simply extend the existing wording. The third case, I don't think it can really happen, because there are earlier checks which simply return error_mark_node if a declaration is within the wrong class... I tested the below. Thanks, Paolo. /// /cp 2014-07-09 Paolo Carlini paolo.carl...@oracle.com PR c++/60686 * decl.c (grokdeclarator): Adjust error message about 'explicit' outside class declaration for C++11. /testsuite 2014-07-09 Paolo Carlini paolo.carl...@oracle.com PR c++/60686 * g++.dg/cpp0x/explicit8.C: New. Index: cp/decl.c === --- cp/decl.c (revision 212385) +++ cp/decl.c (working copy) @@ -10117,9 +10117,14 @@ grokdeclarator (const cp_declarator *declarator, if (explicitp == 1 || (explicitp friendp)) { - /* [dcl.fct.spec] The explicit specifier shall only be used in -declarations of constructors within a class definition. */ - error (only declarations of constructors can be %explicit%); + /* [dcl.fct.spec] (C++11) The explicit specifier shall be used only +in the declaration of a constructor or conversion function within +a class definition. */ + if (!current_class_type) + error (%explicit% outside class declaration); + else + error (only declarations of constructors and conversion operators + can be %explicit%); explicitp = 0; } Index: testsuite/g++.dg/cpp0x/explicit8.C === --- testsuite/g++.dg/cpp0x/explicit8.C (revision 0) +++ testsuite/g++.dg/cpp0x/explicit8.C (working copy) @@ -0,0 +1,14 @@ +// PR c++/60686 +// { dg-do compile { target c++11 } } + +struct A { + explicit operator int() const; +}; + +explicit inline A::operator int() const { return 1; } // { dg-error 'explicit' outside class declaration } + +struct B { + explicit void f(); // { dg-error only declarations of constructors and conversion operators can be 'explicit' } +}; + +explicit void B::f() { } // { dg-error 'explicit' outside class declaration }
Re: [C++ Patch] PR 60686
Hi, On 07/09/2014 10:34 PM, Jason Merrill wrote: On 07/09/2014 06:07 AM, Paolo Carlini wrote: The third case, I don't think it can really happen, because there are earlier checks which simply return error_mark_node if a declaration is within the wrong class... Not if it's a friend declaration: struct A { explicit A(int); }; struct B { explicit friend A::A(int); }; Oops, sorry, we even test for friends... Then I'm finishing testing the below. Thanks, Paolo. // Index: cp/decl.c === --- cp/decl.c (revision 212385) +++ cp/decl.c (working copy) @@ -10117,9 +10117,16 @@ grokdeclarator (const cp_declarator *declarator, if (explicitp == 1 || (explicitp friendp)) { - /* [dcl.fct.spec] The explicit specifier shall only be used in -declarations of constructors within a class definition. */ - error (only declarations of constructors can be %explicit%); + /* [dcl.fct.spec] (C++11) The explicit specifier shall be used only +in the declaration of a constructor or conversion function within +a class definition. */ + if (!current_class_type) + error (%explicit% outside class declaration); + else if (friendp) + error (%explicit% in friend declaration); + else + error (only declarations of constructors and conversion operators + can be %explicit%); explicitp = 0; } Index: testsuite/g++.dg/cpp0x/explicit8.C === --- testsuite/g++.dg/cpp0x/explicit8.C (revision 0) +++ testsuite/g++.dg/cpp0x/explicit8.C (working copy) @@ -0,0 +1,22 @@ +// PR c++/60686 +// { dg-do compile { target c++11 } } + +struct A { + explicit operator int() const; +}; + +explicit inline A::operator int() const { return 1; } // { dg-error 'explicit' outside class declaration } + +struct B { + explicit void f(); // { dg-error only declarations of constructors and conversion operators can be 'explicit' } +}; + +explicit void B::f() { } // { dg-error 'explicit' outside class declaration } + +struct C { + explicit C(int); +}; + +struct D { + explicit friend C::C(int); // { dg-error 'explicit' in friend declaration } +};
Re: [Patch, PR 61720] Clear regex BFS match queue after every iteration
On 07/10/2014 06:30 AM, Tim Shen wrote: Here's the sane patch :) Ok, thanks! Paolo.
Re: [PATCH, libstdc++] Add the logistic distribution as an extension
Hi, On 07/10/2014 10:07 AM, Ed Smith-Rowland wrote: The title says it all. I've been bootstrapping and testing with this on x86_64-linux for a month. OK? Look OK to me too, but I would move both operator() out of line, and definitely operator()(_UniformRandomNumberGenerator, const param_type) of von_mises_distribution. Thanks! Paolo.
Re: [PATCH, libstdc++] Add the logistic distribution as an extension
.. I have another comment: are we sure the usual strategy: templatetypename _UniformRandomNumberGenerator result_type operator()(_UniformRandomNumberGenerator __urng) { return this-operator()(__urng, this-_M_param); } doesn't make sense here too? Paolo.
[C++ Patch/RFC] Back to PR 53159
Hi, after more than 2 years, I'm finally back to this issue: https://gcc.gnu.org/ml/gcc-patches/2012-05/msg01442.html https://gcc.gnu.org/ml/gcc-patches/2012-05/msg01502.html and the below draft, which passes testing, tries to implement as closely as possible what Jason suggested in the thread above. How does it look? Thanks! Paolo. /// Index: cp/call.c === --- cp/call.c (revision 212431) +++ cp/call.c (working copy) @@ -3773,9 +3773,13 @@ build_user_type_conversion_1 (tree totype, tree ex if (flags LOOKUP_NO_NARROWING) conv-check_narrowing = true; - /* Combine it with the second conversion sequence. */ - cand-second_conv = merge_conversion_sequences (conv, - cand-second_conv); + if (!(flags LOOKUP_FOR_CHECK_NARROWING)) +/* Combine it with the second conversion sequence. */ +cand-second_conv = merge_conversion_sequences (conv, + cand-second_conv); + else +/* For convert_for_check_narrowing drop the second conversion. */ +cand-second_conv = conv; return cand; } @@ -3809,6 +3813,37 @@ build_user_type_conversion (tree totype, tree expr return ret; } +/* Used by check_narrowing. */ + +tree +convert_for_check_narrowing (tree totype, tree expr) +{ + struct z_candidate *cand; + tree ret; + + bool subtime = timevar_cond_start (TV_OVERLOAD); + cand = build_user_type_conversion_1 (totype, expr, + LOOKUP_NORMAL + | LOOKUP_FOR_CHECK_NARROWING, + tf_none); + + if (cand) +{ + if (cand-second_conv-kind == ck_ambig) + ret = error_mark_node; + else + ret = convert_like (cand-second_conv, expr, tf_none); +} + else +ret = NULL_TREE; + + if (!ret || ret == error_mark_node) +ret = expr; + + timevar_cond_stop (TV_OVERLOAD, subtime); + return ret; +} + /* Subroutine of convert_nontype_argument. EXPR is an argument for a template non-type parameter of integral or Index: cp/cp-tree.h === --- cp/cp-tree.h(revision 212431) +++ cp/cp-tree.h(working copy) @@ -4573,6 +4573,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, T #define LOOKUP_NO_NON_INTEGRAL (LOOKUP_NO_RVAL_BIND 1) /* Used for delegating constructors in order to diagnose self-delegation. */ #define LOOKUP_DELEGATING_CONS (LOOKUP_NO_NON_INTEGRAL 1) +/* Used by convert_for_check_narrowing. */ +#define LOOKUP_FOR_CHECK_NARROWING (LOOKUP_DELEGATING_CONS 1) #define LOOKUP_NAMESPACES_ONLY(F) \ (((F) LOOKUP_PREFER_NAMESPACES) !((F) LOOKUP_PREFER_TYPES)) @@ -5050,6 +5052,8 @@ extern bool sufficient_parms_p (const_tree); extern tree type_decays_to (tree); extern tree build_user_type_conversion (tree, tree, int, tsubst_flags_t); +extern tree convert_for_check_narrowing (tree, tree); + extern tree build_new_function_call(tree, vectree, va_gc **, bool, tsubst_flags_t); extern tree build_operator_new_call(tree, vectree, va_gc **, tree *, Index: cp/typeck2.c === --- cp/typeck2.c(revision 212431) +++ cp/typeck2.c(working copy) @@ -854,6 +854,13 @@ check_narrowing (tree type, tree init) if (!warn_narrowing || !ARITHMETIC_TYPE_P (type)) return; + if (CLASS_TYPE_P (ftype)) +{ + /* Look through, eg, conversion operators (c++/53159). */ + init = convert_for_check_narrowing (type, init); + ftype = unlowered_expr_type (init); +} + if (BRACE_ENCLOSED_INITIALIZER_P (init) TREE_CODE (type) == COMPLEX_TYPE) { Index: testsuite/g++.dg/cpp0x/Wnarrowing1.C === --- testsuite/g++.dg/cpp0x/Wnarrowing1.C(revision 0) +++ testsuite/g++.dg/cpp0x/Wnarrowing1.C(working copy) @@ -0,0 +1,14 @@ +// PR c++/53159 +// { dg-do compile { target c++11 } } +// { dg-options -Wnarrowing -Wno-overflow } + +struct X +{ + constexpr operator int() { return __INT_MAX__; } +}; + +int f() { return __INT_MAX__; } + +signed char a { __INT_MAX__ }; // { dg-warning narrowing conversion } +signed char b { f() }; // { dg-warning narrowing conversion } +signed char c { X{} }; // { dg-warning narrowing conversion }
Re: [C++ Patch/RFC] Back to PR 53159
Hi, On 07/10/2014 10:55 PM, Jason Merrill wrote: Hmm, why aren't we already getting the error from if (convs-check_narrowing) check_narrowing (totype, expr); in convert_like_real? Is it that we need to copy LOOKUP_NO_NARROWING into convflags in build_user_type_conversion_1? Ah, ah, thanks. Frankly I noticed that flag but somehow decided to not focus on it :( Anyway, certainly build_user_type_conversion_1 can be tweaked as you are suggesting, the only missing bit is that it doesn't get LOOKUP_NO_NARROWING in the flags, and cannot figure it out from expr because it's a TARGET_EXPR at that point. Thus it seems to me we have to pass it down from, say, check_initializer when init is still a CONSTRUCTOR and its BRACE_ENCLOSED_INITIALIZER_P (init) is set? I'm going to test the below... makes sense? Paolo. // Index: call.c === --- call.c (revision 212431) +++ call.c (working copy) @@ -3586,7 +3586,8 @@ build_user_type_conversion_1 (tree totype, tree ex /* It's OK to bind a temporary for converting constructor arguments, but not in converting the return value of a conversion operator. */ - convflags = ((flags LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION); + convflags = ((flags LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION + | (flags LOOKUP_NO_NARROWING)); flags = ~LOOKUP_NO_TEMP_BIND; if (ctors) Index: decl.c === --- decl.c (revision 212431) +++ decl.c (working copy) @@ -5707,6 +5707,7 @@ check_initializer (tree decl, tree init, int flags return NULL_TREE; } } + flags |= LOOKUP_NO_NARROWING; } if (TREE_CODE (decl) == CONST_DECL)
Re: [C++ Patch/RFC] Back to PR 53159
... the below is another, very safe, option for setting LOOKUP_NO_NARROWING in flags. Paolo. Index: call.c === --- call.c (revision 212431) +++ call.c (working copy) @@ -3586,7 +3586,8 @@ build_user_type_conversion_1 (tree totype, tree ex /* It's OK to bind a temporary for converting constructor arguments, but not in converting the return value of a conversion operator. */ - convflags = ((flags LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION); + convflags = ((flags LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION + | (flags LOOKUP_NO_NARROWING)); flags = ~LOOKUP_NO_TEMP_BIND; if (ctors) Index: decl.c === --- decl.c (revision 212431) +++ decl.c (working copy) @@ -5755,6 +5755,7 @@ check_initializer (tree decl, tree init, int flags } else { + flags |= LOOKUP_NO_NARROWING; init = reshape_init (type, init, tf_warning_or_error); if (SCALAR_TYPE_P (type)) check_narrowing (type, init);
Re: [C++ Patch/RFC] Back to PR 53159
... and of course the problem with all such ideas is that we easily end up warning twice in all the simple cases which check_narrowing can already handle. Something like the attached has more chances of passing the testsuite while not regressing in terms of duplicate warnings (which are hard to notice) Paolo. Index: call.c === --- call.c (revision 212431) +++ call.c (working copy) @@ -3586,7 +3586,8 @@ build_user_type_conversion_1 (tree totype, tree ex /* It's OK to bind a temporary for converting constructor arguments, but not in converting the return value of a conversion operator. */ - convflags = ((flags LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION); + convflags = ((flags LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION + | (flags LOOKUP_NO_NARROWING)); flags = ~LOOKUP_NO_TEMP_BIND; if (ctors) Index: decl.c === --- decl.c (revision 212431) +++ decl.c (working copy) @@ -5757,7 +5757,12 @@ check_initializer (tree decl, tree init, int flags { init = reshape_init (type, init, tf_warning_or_error); if (SCALAR_TYPE_P (type)) - check_narrowing (type, init); + { + if (!CLASS_TYPE_P (TREE_TYPE (init))) + check_narrowing (type, init); + else + flags |= LOOKUP_NO_NARROWING; + } } } else if (TREE_CODE (init) == TREE_LIST
[C++ Patch] PR 53159 (Take 2)
Hi, only today it occurred to me that we can as well delay all the diagnostic at issue to the check_narrowing at the end of convert_like_real and avoid at once possible issues with duplicate warnings. Tested x86_64-linux. Thanks, Paolo. // /cp 2014-07-11 Paolo Carlini paolo.carl...@oracle.com PR c++/53159 * call.c (build_user_type_conversion_1): Copy LOOKUP_NO_NARROWING into convflags. * decl.c (check_initializer): Dont' call check_narrowing here, set LOOKUP_NO_NARROWING. * typeck2.c (digest_init_r): Likewise. /testsuite 2014-07-11 Paolo Carlini paolo.carl...@oracle.com PR c++/53159 * g++.dg/cpp0x/Wnarrowing1.C: New. Index: cp/call.c === --- cp/call.c (revision 212449) +++ cp/call.c (working copy) @@ -3586,7 +3586,8 @@ build_user_type_conversion_1 (tree totype, tree ex /* It's OK to bind a temporary for converting constructor arguments, but not in converting the return value of a conversion operator. */ - convflags = ((flags LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION); + convflags = ((flags LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION + | (flags LOOKUP_NO_NARROWING)); flags = ~LOOKUP_NO_TEMP_BIND; if (ctors) Index: cp/decl.c === --- cp/decl.c (revision 212449) +++ cp/decl.c (working copy) @@ -5757,7 +5757,7 @@ check_initializer (tree decl, tree init, int flags { init = reshape_init (type, init, tf_warning_or_error); if (SCALAR_TYPE_P (type)) - check_narrowing (type, init); + flags |= LOOKUP_NO_NARROWING; } } else if (TREE_CODE (init) == TREE_LIST Index: cp/typeck2.c === --- cp/typeck2.c(revision 212449) +++ cp/typeck2.c(working copy) @@ -1027,7 +1027,7 @@ digest_init_r (tree type, tree init, bool nested, tree *exp; if (nested) - check_narrowing (type, init); + flags |= LOOKUP_NO_NARROWING; init = convert_for_initialization (0, type, init, flags, ICR_INIT, NULL_TREE, 0, complain); Index: testsuite/g++.dg/cpp0x/Wnarrowing1.C === --- testsuite/g++.dg/cpp0x/Wnarrowing1.C(revision 0) +++ testsuite/g++.dg/cpp0x/Wnarrowing1.C(working copy) @@ -0,0 +1,18 @@ +// PR c++/53159 +// { dg-do compile { target c++11 } } +// { dg-options -Wnarrowing -Wno-overflow } + +struct X +{ + constexpr operator int() { return __INT_MAX__; } +}; + +int f() { return __INT_MAX__; } + +signed char a { __INT_MAX__ }; // { dg-warning narrowing conversion } +signed char b { f() }; // { dg-warning narrowing conversion } +signed char c { X{} }; // { dg-warning narrowing conversion } + +signed char ar[] { __INT_MAX__ }; // { dg-warning narrowing conversion } +signed char br[] { f() }; // { dg-warning narrowing conversion } +signed char cr[] { X{} }; // { dg-warning narrowing conversion }
Re: [PATCH, libstdc++] Add the logistic distribution as an extension
Hi, On 07/11/2014 05:38 PM, Ed Smith-Rowland wrote: OK? Ok, thanks, but please adjust the dates you have on the testcases to the date of the actual commit (I suppose today or tomorrow) Thanks again! Paolo.
Re: [C++ Patch] PR 53159 (Take 2)
Hi, On 07/11/2014 07:58 PM, Jason Merrill wrote: Oops, this patch didn't thread with the earlier one... Yeah, sorry, I considered my drafts of yesterday evening a distraction and wanted to start a fresh thread with a complete (more meaningful) new proposal. Probably not a good idea, after all, confusing... On 07/11/2014 06:15 AM, Paolo Carlini wrote: if (SCALAR_TYPE_P (type)) Is the condition still necessary? I'm removing it and retesting. In any case (the eventual) check_narrowing will return immediately if !ARITHMETIC_TYPE_P (type) is true... Would the amended patch be Ok? Thanks! Paolo.
Re: [PATCH] libstdc++: add uniform on sphere distribution
Hi, On 07/13/2014 04:00 AM, Ulrich Drepper wrote: + templatestd::size_t _Dimen, typename _RealType, typename _CharT, + typename _Traits +std::basic_ostream_CharT, _Traits +operator(std::basic_ostream_CharT, _Traits __os, + const __gnu_cxx::uniform_on_sphere_distribution_Dimen, + _RealType __x) +{ + return __os; +} + + templatestd::size_t _Dimen, typename _RealType, typename _CharT, + typename _Traits +std::basic_istream_CharT, _Traits +operator(std::basic_istream_CharT, _Traits __is, + __gnu_cxx::uniform_on_sphere_distribution_Dimen, +_RealType __x) +{ + return __is; +} are these dummy implementations intended? Thanks, Paolo.
Re: [PATCH] libstdc++: add uniform on sphere distribution
Hi, On 07/13/2014 12:04 PM, Ulrich Drepper wrote: On Sun, Jul 13, 2014 at 5:24 AM, Paolo Carlini paolo.carl...@oracle.com wrote: are these dummy implementations intended? Yes. There is no state. The only parameter is the dimensionality which is a template parameter. Ah, interesting, didn't look close enough, sorry. Maybe add a one line comment in the bodies? Patch is Ok. Thanks! Paolo.
Re: [PATCH] libstdc++: add uniform on sphere distribution
Hi, On 07/13/2014 04:11 PM, Ulrich Drepper wrote: On Sun, Jul 13, 2014 at 9:55 AM, Ed Smith-Rowland 3dw...@verizon.net wrote: So I would just serialize _M_n here. It has fixed parameters. This would mean unnecessary work. When you try to use the parameter of the sphere distribution the normal distribution will be reset. So there really is no need here. At the cost of appearing a little dumb (and admittedly lately I'm not spending much time on random, anyway), I'd like to make sure I *really* understand your reasoning... Thus I read this (26.5.1.6/6): If a textual representation is written using os x and that representation is restored into the same or a different object y of the same type using is y, repeated invocations of y(g) shall produce the same sequence of numbers as would repeated invocations of x(g). and I think: the normal distributions in x and y do have a non-trivial state (_M_saved, _M_saved_available) which, at any given moment, is different in x and y. Then the trivial inserter of x is called and the trivial extractor of y is called, nothing changes in y. I don't see how the following invocations of y(g) can produce the same sequence of numbers that would be produced by invocations of x(g). Paolo.
Re: [PATCH] libstdc++: add uniform on sphere distribution
Hi, On 07/13/2014 06:03 PM, Ulrich Drepper wrote: On Sun, Jul 13, 2014 at 11:43 AM, Paolo Carlini paolo.carl...@oracle.com wrote: and I think: the normal distributions in x and y do have a non-trivial state (_M_saved, _M_saved_available) which, at any given moment, is different in x and y. Then the trivial inserter of x is called and the trivial extractor of y is called, nothing changes in y. I don't see how the following invocations of y(g) can produce the same sequence of numbers that would be produced by invocations of x(g). Remember: we are talking about distributions, not RNGs. The distribution has no parameters so given the same input (i.e., random byte sequences) it will create the same output all the time. Sorry, I still don't get it. When operator() of x and y, two uniform_on_sphere_distribution, call _M_n(__urng) and those _M_n have a different state, the numbers produced are in general different. For example, suppose _M_saved_available is true in both _M_n, everything is already decided, no RNGs are involved. Paolo.
Re: [PATCH] libstdc++: add uniform on sphere distribution
Hi, On 07/13/2014 06:18 PM, Ulrich Drepper wrote: On Sun, Jul 13, 2014 at 12:07 PM, Paolo Carlini paolo.carl...@oracle.com wrote: Sorry, I still don't get it. When operator() of x and y, two uniform_on_sphere_distribution, call _M_n(__urng) and those _M_n have a different state, the numbers produced are in general different. Correct. But in the case of this distribution once you have the random numbers the remainder of the work is done by a fixed formula: v = (N(0,1), ..., N(0,1)) result = v / ||v||_2 That's it, nothing else to be done. If you have two calls of operator() of two different uniform_on_sphere objects and you pass to each an RNG object in exactly the same state you will get the same result. I don't think so. It depends on the past of the two different uniform_on_sphere: each time each uniform_on_sphere calls _M_n(__urng) the state of *its own* _M_n changes, evolves from the initial state. For instance, you call it 4 times on one and 7 times on another. The states of the two _M_n are different, and from that point the next numbers will be different. This is exactly what happens when you call os x and is y, no object is destroyed, no object is constructed, and x has called _M_n(__urng) 4 times, and y has called it 7 times. Your inserters and extractors are trivial. The next numbers will be different. Note that, if I understand the standard correctly, we are comparing the numbers *from that point on*, not the whole story, whatever that may mean. In other terms, I'm saying the sequence of numbers produced after the 4th number isn't in general the same sequence of numbers produced after the 7th number. Paolo.
Re: [PATCH] libstdc++: add uniform on sphere distribution
Hi, On 07/13/2014 06:44 PM, Ulrich Drepper wrote: But your 4th and 7th call example by itself is not a reason. Again, the input exclusively determined by the random numbers. Here, of course, the 4th and 7th use will produce different results. But this is not what the state of the distribution is supposed to capture. For that you'll have to save the state of the RNG as well. Yes, you are right. Saving the full state of the distribution solves only half of my hypothetical problem, but certainly you have to save it if you want to, say, reset the RNGs to a common state and get the same sequences of numbers after the os x and is y pair. Paolo.
Re: [PATCH] libstdc++: add uniform on sphere distribution
Hi, On 07/14/2014 09:58 AM, Andreas Schwab wrote: FAIL: ext/random/arcsine_distribution/cons/default.cc (test for excess errors) Excess errors: /daten/aranym/gcc/gcc-20140714/libstdc++-v3/include/ext/random.tcc:1587:22: error: '_M_n' was not declared in this scope /daten/aranym/gcc/gcc-20140714/libstdc++-v3/include/ext/random.tcc:1598:22: error: '_M_n' was not declared in this scope Ulrich please fix those _M_n to __x._M_n and remove the obsolete comments. We could also add the usual minimal set of tests exercising serialization. Thanks. Paolo.
[C++ Patch/RFC] PR 60608
Hi, I have been looking a bit into this bug, using a reduced testcase which simplifies the debugging quite a bit for me (a non-variadic variant is ok). I cannot say to already understand all the details of the issue, but something which strikes me as interesting, is that the DEDUCE_CALL passed down by add_candidate gets lost and we end up calling type_unification_real from unify with DEDUCE_EXACT. If I change it to an unconditional DEDUCE_CALL, the testcase is accepted and the testsuite passes with no regressions. Is that all there is to the issue?!? Thanks! Paolo. Index: cp/pt.c === --- cp/pt.c (revision 212510) +++ cp/pt.c (working copy) @@ -18198,7 +18198,7 @@ unify (tree tparms, tree targs, tree parm, tree ar nargs = i; return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm), - args, nargs, 1, DEDUCE_EXACT, + args, nargs, 1, DEDUCE_CALL, LOOKUP_NORMAL, NULL, explain_p); } Index: testsuite/g++.dg/cpp0x/variadic161.C === --- testsuite/g++.dg/cpp0x/variadic161.C(revision 0) +++ testsuite/g++.dg/cpp0x/variadic161.C(working copy) @@ -0,0 +1,14 @@ +// PR c++/60608 +// { dg-do compile { target c++11 } } + +templatetypename... Args +void +wrapper(void (*)(Args...)); + +void myfun(int); + +void +test() +{ + wrapperconst int(myfun); +}
Re: [C++ Patch/RFC] PR 60608
Hi, On 07/14/2014 09:47 PM, Jason Merrill wrote: On 07/14/2014 12:20 PM, Paolo Carlini wrote: I have been looking a bit into this bug, using a reduced testcase which simplifies the debugging quite a bit for me (a non-variadic variant is ok). I cannot say to already understand all the details of the issue, but something which strikes me as interesting, is that the DEDUCE_CALL passed down by add_candidate gets lost and we end up calling type_unification_real from unify with DEDUCE_EXACT. If I change it to an unconditional DEDUCE_CALL, the testcase is accepted and the testsuite passes with no regressions. Is that all there is to the issue?!? Unfortunately, that goes too far. I think we want a new DEDUCE_PARMS that is like DEDUCE_EXACT but does the same transformations as tsubst_arg_types in this part of unify_pack_expansion: Thanks. This helps me a lot. In particular I see now, in tsubst_arg_types: /* Do array-to-pointer, function-to-pointer conversion, and ignore top-level qualifiers as required. */ type = cv_unqualified (type_decays_to (type)); which is exactly the ingredient we are missing. A rough draft already appears to work on the testcase, now I have only to figure out what happens of the various switches over unification_kind_t and adjust the other details (also, comments). Thanks again, Paolo.
[C++ Patch, committed] Small diagnostic fix
Hi, while looking into an old issue I noticed that in one place we don't check the return value of permerror. I'm going to commit the below as obvious. Thanks, Paolo. // 2014-07-15 Paolo Carlini paolo.carl...@oracle.com * call.c (convert_like_real): Call print_z_candidate and inform only if permerror returns true. Index: call.c === --- call.c (revision 212545) +++ call.c (working copy) @@ -6076,9 +6076,11 @@ convert_like_real (conversion *convs, tree expr, t { if (t-kind == ck_user t-cand-reason) { - permerror (loc, invalid user-defined conversion -from %qT to %qT, TREE_TYPE (expr), totype); - print_z_candidate (loc, candidate is:, t-cand); + complained = permerror (loc, invalid user-defined conversion + from %qT to %qT, TREE_TYPE (expr), + totype); + if (complained) + print_z_candidate (loc, candidate is:, t-cand); expr = convert_like_real (t, expr, fn, argnum, 1, /*issue_conversion_warnings=*/false, /*c_cast_p=*/false, @@ -6089,7 +6091,7 @@ convert_like_real (conversion *convs, tree expr, t complain); else expr = cp_convert (totype, expr, complain); - if (fn) + if (complained fn) inform (DECL_SOURCE_LOCATION (fn), initializing argument %P of %qD, argnum, fn); return expr;
Re: [C++ Patch/RFC] PR 50961
Hi, On 07/15/2014 11:46 PM, Jason Merrill wrote: You need to call resolve_nondeduced_context at some point. This doesn't seem to be the right place, since you also want to handle code like if (foovoid). Maybe in resolve_address_of_overloaded_function just before the error? Thanks, that helps (certainly resolve_nondeduced_context handles well the TEMPLATE_ID_EXPRs with which we are concerned, and, well, it's reassuring that decay_conversion calls it first). In practice, both for the original testcase and for a conditional (and in more cases, eg conditional expressions), what happens is that perform_implicit_conversion_flags is called, which, when implicit_conversion fails, calls instantiate_type (and then resolve_address_of_overloaded_function) only to get a good error message. Thus, would it make sense to use resolve_nondeduced_context in perform_implicit_conversion_flags itself?!? Conservatively, only when the target type is a boolean_type_node, maybe? I tested the below. Thanks again, Paolo. Index: cp/call.c === --- cp/call.c (revision 212576) +++ cp/call.c (working copy) @@ -9241,6 +9241,8 @@ perform_implicit_conversion_flags (tree type, tree if (error_operand_p (expr)) return error_mark_node; + expr = resolve_nondeduced_context (expr); + /* Get the high-water mark for the CONVERSION_OBSTACK. */ p = conversion_obstack_alloc (0); Index: testsuite/g++.dg/template/operator13.C === --- testsuite/g++.dg/template/operator13.C (revision 0) +++ testsuite/g++.dg/template/operator13.C (working copy) @@ -0,0 +1,12 @@ +// PR c++/50961 + +template class T void foo (); + +bool b1 = !foovoid; +bool b2 = foovoid ? true : false; + +void bar() +{ + if (foovoid) +; +}
Re: [PATCH] libstdc++: add uniform on sphere distribution
Hi, On 07/16/2014 01:05 PM, Ed Smith-Rowland wrote: One thing we all forgot: the operator== is also non-trivial because it needs to compare _M_n. Right. And reset too. I'm going to test and apply the below. Thanks, Paolo. /// 2014-07-16 Paolo Carlini paolo.carl...@oracle.com * include/ext/random: Minor formatting and cosmetic tweaks. (uniform_on_sphere_distribution::operator== (const uniform_on_sphere_distribution, const uniform_on_sphere_distribution)): Compare the _M_nds. (uniform_on_sphere_distribution::reset): Reset _M_nd. (operator!=(const uniform_on_sphere_distribution, const uniform_on_sphere_distribution)): Adjust. * include/ext/random.tcc: Minor cosmetc tweaks. Index: include/ext/random === --- include/ext/random (revision 212581) +++ include/ext/random (working copy) @@ -598,7 +598,7 @@ inline bool operator!=(const __gnu_cxx::beta_distribution_RealType __d1, const __gnu_cxx::beta_distribution_RealType __d2) - { return !(__d1 == __d2); } +{ return !(__d1 == __d2); } /** @@ -2575,7 +2575,7 @@ inline bool operator!=(const __gnu_cxx::triangular_distribution_RealType __d1, const __gnu_cxx::triangular_distribution_RealType __d2) - { return !(__d1 == __d2); } +{ return !(__d1 == __d2); } /** @@ -2810,7 +2810,7 @@ inline bool operator!=(const __gnu_cxx::von_mises_distribution_RealType __d1, const __gnu_cxx::von_mises_distribution_RealType __d2) - { return !(__d1 == __d2); } +{ return !(__d1 == __d2); } /** @@ -3328,12 +3328,12 @@ */ explicit uniform_on_sphere_distribution() - : _M_param(), _M_n(_RealType(0), _RealType(1)) + : _M_param(), _M_nd() { } explicit uniform_on_sphere_distribution(const param_type __p) - : _M_param(__p), _M_n(_RealType(0), _RealType(1)) + : _M_param(__p), _M_nd() { } /** @@ -3341,7 +3341,7 @@ */ void reset() - { } + { _M_nd.reset(); } /** * @brief Returns the parameter set of the distribution. @@ -3425,14 +3425,15 @@ friend bool operator==(const uniform_on_sphere_distribution __d1, const uniform_on_sphere_distribution __d2) - { return true; } + { return __d1._M_nd == __d2._M_nd; } /** - * @brief Inserts a %uniform_on_sphere_distribution random number distribution - * @p __x into the output stream @p __os. + * @brief Inserts a %uniform_on_sphere_distribution random number + *distribution @p __x into the output stream @p __os. * * @param __os An output stream. - * @param __x A %uniform_on_sphere_distribution random number distribution. + * @param __x A %uniform_on_sphere_distribution random number + * distribution. * * @returns The output stream with the state of @p __x inserted or in * an error state. @@ -3446,11 +3447,13 @@ __x); /** - * @brief Extracts a %uniform_on_sphere_distribution random number distribution + * @brief Extracts a %uniform_on_sphere_distribution random number + *distribution * @p __x from the input stream @p __is. * * @param __is An input stream. - * @param __x A %uniform_on_sphere_distribution random number generator engine. + * @param __x A %uniform_on_sphere_distribution random number + * generator engine. * * @returns The input stream with @p __x extracted or in an error state. */ @@ -3470,7 +3473,7 @@ const param_type __p); param_type _M_param; - std::normal_distribution_RealType _M_n; + std::normal_distribution_RealType _M_nd; }; /** @@ -3482,7 +3485,7 @@ _RealType __d1, const __gnu_cxx::uniform_on_sphere_distribution_Dimen, _RealType __d2) - { return false; } +{ return !(__d1 == __d2); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace __gnu_cxx Index: include/ext/random.tcc === --- include/ext/random.tcc (revision 212581) +++ include/ext/random.tcc (working copy) @@ -1551,7 +1551,7 @@ _RealType __sum = _RealType(0); std::generate(__ret.begin(), __ret.end(), - [__urng, __sum, this](){ _RealType __t = _M_n(__urng); + [__urng, __sum, this](){ _RealType __t = _M_nd(__urng); __sum += __t * __t; return __t; }); auto __norm = std::sqrt(__sum); @@ -1583,8 +1583,7 @@ const __gnu_cxx::uniform_on_sphere_distribution_Dimen
[C++ Patch] PR 61804
Hi, Richard Smith noticed another case, like '[' in C++11, where we want to keep the parsing uncommitted after the parenthesized type-id. Tested x86_64-linux. Thanks, Paolo. / /cp 2014-07-16 Paolo Carlini paolo.carl...@oracle.com PR c++/61804 * parser.c (cp_parser_tokens_start_cast_expression): Return -1 for '++' and '--'. /testsuite 2014-07-16 Paolo Carlini paolo.carl...@oracle.com PR c++/61804 * g++.dg/parse/pr61804.C: New. Index: cp/parser.c === --- cp/parser.c (revision 212581) +++ cp/parser.c (working copy) @@ -7700,8 +7700,8 @@ cp_parser_delete_expression (cp_parser* parser) tf_warning_or_error); } -/* Returns 1 if TOKEN may start a cast-expression and, in C++11, - isn't '[', -1 if TOKEN is '[' in C++11, 0 otherwise. */ +/* Returns 1 if TOKEN may start a cast-expression and, in C++11, isn't '['; + -1 if TOKEN is '++', '--', or '[' in C++11; 0 otherwise. */ static int cp_parser_tokens_start_cast_expression (cp_parser *parser) @@ -7755,13 +7755,26 @@ cp_parser_tokens_start_cast_expression (cp_parser return cp_lexer_peek_nth_token (parser-lexer, 2)-type != CPP_CLOSE_PAREN; +case CPP_OPEN_SQUARE: /* '[' may start a primary-expression in obj-c++ and in C++11, as a lambda-expression, eg, '(void)[]{}'. */ -case CPP_OPEN_SQUARE: if (cxx_dialect = cxx11) return -1; return c_dialect_objc (); +case CPP_PLUS_PLUS: +case CPP_MINUS_MINUS: + /* '++' and '--' may or may not start a cast-expression: + +struct T { void operator++(int); }; +void f() { (T())++; } + +vs + +int a; +(int)++a; */ + return -1; + default: return 1; } @@ -7874,8 +7887,8 @@ cp_parser_cast_expression (cp_parser *parser, bool function returning T. */ if (!cp_parser_error_occurred (parser)) { - /* Only commit if the cast-expression doesn't start with '[' in -C++11, which may or may not start a lambda-expression. */ + /* Only commit if the cast-expression doesn't start with +'++', '--', or '[' in C++11. */ if (cast_expression 0) cp_parser_commit_to_topmost_tentative_parse (parser); Index: testsuite/g++.dg/parse/pr61804.C === --- testsuite/g++.dg/parse/pr61804.C(revision 0) +++ testsuite/g++.dg/parse/pr61804.C(working copy) @@ -0,0 +1,9 @@ +// PR c++/61804 + +struct T { void operator++(int); }; +void f() { (T())++; } + +struct U { void operator--(int); }; +void g() { (U())--; } + +void h() { int a; (int)++a; (int)--a; }
Re: [C++ Patch/RFC] PR 50961
Hi, On 07/17/2014 02:40 AM, Jason Merrill wrote: On 07/16/2014 12:39 AM, Paolo Carlini wrote: In practice, both for the original testcase and for a conditional (and in more cases, eg conditional expressions), what happens is that perform_implicit_conversion_flags is called, which, when implicit_conversion fails, calls instantiate_type (and then resolve_address_of_overloaded_function) only to get a good error message. Thus, would it make sense to use resolve_nondeduced_context in perform_implicit_conversion_flags itself?!? Conservatively, only when the target type is a boolean_type_node, maybe? How about in standard_conversion in the type_unknown_p case after we've checked for pointer-to(-member)-function? Ah, I noticed that place a few days ago, when I didn't know about resolve_nondeduced_context, then I completely forgot about it... The below passes testing. Thanks! Paolo. Index: cp/call.c === --- cp/call.c (revision 212742) +++ cp/call.c (working copy) @@ -1107,14 +1107,22 @@ standard_conversion (tree to, tree from, tree expr to = strip_top_quals (to); from = strip_top_quals (from); - if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to)) - expr type_unknown_p (expr)) + if (expr type_unknown_p (expr)) { - tsubst_flags_t tflags = tf_conv; - expr = instantiate_type (to, expr, tflags); - if (expr == error_mark_node) - return NULL; - from = TREE_TYPE (expr); + if (TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to)) + { + tsubst_flags_t tflags = tf_conv; + expr = instantiate_type (to, expr, tflags); + if (expr == error_mark_node) + return NULL; + from = TREE_TYPE (expr); + } + else if (TREE_CODE (to) == BOOLEAN_TYPE) + { + /* Necessary for eg, TEMPLATE_ID_EXPRs (c++/50961). */ + expr = resolve_nondeduced_context (expr); + from = TREE_TYPE (expr); + } } fcode = TREE_CODE (from); Index: testsuite/g++.dg/template/operator13.C === --- testsuite/g++.dg/template/operator13.C (revision 0) +++ testsuite/g++.dg/template/operator13.C (working copy) @@ -0,0 +1,12 @@ +// PR c++/50961 + +template class void foo (); + +bool b1 = !foovoid; +bool b2 = foovoid ? true : false; + +void bar() +{ + if (foovoid) +; +}
Re: [patch] Add libstdc++ pretty printers for Library Fundamentals TS types
Hi, On 07/23/2014 12:45 PM, Jonathan Wakely wrote: On 15/07/14 13:03 +0100, Jonathan Wakely wrote: On 14/07/14 20:31 +0100, Jonathan Wakely wrote: This adds printers for the types in the std::experimental namespace. This should fix the test failures that Paolo and HJ are seeing, older versions of GDB didn't have the gdb.Type.name attribute. Confirmed fixed, by the way. Thanks! Paolo.
[C++ Patch] PR 57397
Hi, in this diagnostic issue Jon noticed that for testcases like: templateclass T1, class... Tn void foo(T1, Tn...); int main() { foo(); } we provide diagnostic saying candidate expects 2 arguments, 0 provided, whereas of course we want to say something like candidate expects at least 1 argument, 0 provided. The below simply tries to refine the existing logic in type_unification_real. Note that while handling this bug, I noticed that we don't appear to be up to date wrt cases like: templateclass T1, class... Tn, class... Un void bar(T1, Tn..., Un...); int main() { bar(1); } which we do reject and very recently clang started accepting. On the other hand we accept: int main() { bar(1, 2); } which clang rejects. My patch doesn't even try to cope with that (do be honest, I didn't lookup the relevant DRs and resolutions), that seems to me an unrelated issue, definitely not just a diagnostic one. Thanks, Paolo. /// /cp 2014-07-29 Paolo Carlini paolo.carl...@oracle.com PR c++/57397 * pt.c (unify_arity): Add boolean parameter. (unify_too_few_arguments): Likewise. (type_unification_real): Diagnose correctly insufficient arguments in the presence of trailing variadic parameters. /testsuite 2014-07-29 Paolo Carlini paolo.carl...@oracle.com PR c++/57397 * g++.dg/cpp0x/vt-57397.C: New. Index: cp/pt.c === --- cp/pt.c (revision 213123) +++ cp/pt.c (working copy) @@ -5517,13 +5517,21 @@ unify_method_type_error (bool explain_p, tree arg) } static int -unify_arity (bool explain_p, int have, int wanted) +unify_arity (bool explain_p, int have, int wanted, bool lb_p = false) { if (explain_p) -inform_n (input_location, wanted, - candidate expects %d argument, %d provided, - candidate expects %d arguments, %d provided, - wanted, have); +{ + if (lb_p) + inform_n (input_location, wanted, + candidate expects at least %d argument, %d provided, + candidate expects at least %d arguments, %d provided, + wanted, have); + else + inform_n (input_location, wanted, + candidate expects %d argument, %d provided, + candidate expects %d arguments, %d provided, + wanted, have); +} return 1; } @@ -5534,9 +5542,10 @@ unify_too_many_arguments (bool explain_p, int have } static int -unify_too_few_arguments (bool explain_p, int have, int wanted) +unify_too_few_arguments (bool explain_p, int have, int wanted, +bool lb_p = false) { - return unify_arity (explain_p, have, wanted); + return unify_arity (explain_p, have, wanted, lb_p); } static int @@ -16546,6 +16555,7 @@ type_unification_real (tree tparms, const tree *args; unsigned int nargs; unsigned int ia; + bool remaining_pack_p = false; gcc_assert (TREE_CODE (tparms) == TREE_VEC); gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST); @@ -16598,6 +16608,8 @@ type_unification_real (tree tparms, tree argvec; tree parmvec = make_tree_vec (1); + remaining_pack_p = true; + /* Allocate a TREE_VEC and copy in all of the arguments */ argvec = make_tree_vec (nargs - ia); for (i = 0; ia nargs; ++ia, ++i) @@ -16622,13 +16634,20 @@ type_unification_real (tree tparms, TREE_PURPOSE (parms) == NULL_TREE) { unsigned int count = nargs; + unsigned int excess_packs_count = 0; tree p = parms; while (p p != void_list_node) { count++; + excess_packs_count + += TREE_CODE (TREE_VALUE (p)) == TYPE_PACK_EXPANSION; p = TREE_CHAIN (p); } - return unify_too_few_arguments (explain_p, ia, count); + + if (excess_packs_count) + count -= excess_packs_count - remaining_pack_p; + return unify_too_few_arguments (explain_p, ia, count, + excess_packs_count); } if (!subr) Index: testsuite/g++.dg/cpp0x/vt-57397.C === --- testsuite/g++.dg/cpp0x/vt-57397.C (revision 0) +++ testsuite/g++.dg/cpp0x/vt-57397.C (working copy) @@ -0,0 +1,16 @@ +// PR c++/57397 +// { dg-do compile { target c++11 } } + +templateclass T1, class... Tn +void foo(T1, Tn...); + +templateclass T1, class T2, class... Tn +void bar(T1, T2, Tn...); + +int main() +{ + foo(); // { dg-error no matching } + // { dg-message candidate expects at least 1 argument, 0 provided { target *-*-* } 12 } + bar(1); // { dg-error no matching } + // { dg-message candidate expects at least 2 arguments, 1 provided { target *-*-* } 14 } +}
Re: [C++ Patch] PR 57397
Hi, On 07/29/2014 06:01 PM, Jason Merrill wrote: On 07/29/2014 10:28 AM, Paolo Carlini wrote: +unify_arity (bool explain_p, int have, int wanted, bool lb_p = false) I don't understand lb_p. lower_bound ;) The first name which came to my mind... @@ -16598,6 +16608,8 @@ type_unification_real (tree tparms, tree argvec; tree parmvec = make_tree_vec (1); + remaining_pack_p = true; + /* Allocate a TREE_VEC and copy in all of the arguments */ argvec = make_tree_vec (nargs - ia); for (i = 0; ia nargs; ++ia, ++i) Why would we get here in the too few args case? Won't we only hit this code if we had enough args for the non-pack parms? Yeah, that is exactly for the cases I was mentioning at the end of the my first message, eg: templateclass T1, class... T2, class... T3 void boo(T1, T2..., T3...) { } int main() { boo(1); } the patch as-is leads to a diagnostic similar to the current one, thus saying: candidate expects at least 2 arguments, 1 provided whereas the current one says: candidate expects 2 arguments, 1 provided. That seems fine, given the current status, because indeed, passing: int main() { boo(1, 2); } or, for that matter: int main() { boo(1, 2, 3); } are both accepted. Paolo.
Re: [C++ Patch] PR 57397
Hi, On 07/29/2014 06:56 PM, Jason Merrill wrote: On 07/29/2014 12:23 PM, Paolo Carlini wrote: On 07/29/2014 06:01 PM, Jason Merrill wrote: Why would we get here in the too few args case? Won't we only hit this code if we had enough args for the non-pack parms? Yeah, that is exactly for the cases I was mentioning at the end of the my first message, eg: templateclass T1, class... T2, class... T3 void boo(T1, T2..., T3...) { } int main() { boo(1); } Ah, right. And as you mention, we ought to accept that; it seems a bit odd to change the code to give a different wrong error instead of the current wrong error. :) Yeah, it is, but then we aren't really handling c++/57397, IMHO. I bet there is even a different bug report or a defect report for this second issue. I'll see what I can do, but I have no idea how difficult it will turn out to be... Paolo.
Re: [C++ Patch] PR 63265
Hi, On 11/10/2014 06:16 PM, Jason Merrill wrote: I don't think we want to suppress this warning in general. The problem in this PR is that the warning code is failing to recognize that the first operand is constant false. Thanks. Then, shall we do something like the below? Passes testing. Thanks, Paolo. // /cp 2014-11-11 Paolo Carlini paolo.carl...@oracle.com PR c++/63265 * pt.c (tsubst_copy_and_build, case COND_EXPR): Maybe fold to const the condition. /testsuite 2014-11-11 Paolo Carlini paolo.carl...@oracle.com PR c++/63265 * g++.dg/cpp0x/constexpr-63265.C: New. Index: cp/pt.c === --- cp/pt.c (revision 217342) +++ cp/pt.c (working copy) @@ -15137,7 +15137,9 @@ tsubst_copy_and_build (tree t, case COND_EXPR: { - tree cond = RECUR (TREE_OPERAND (t, 0)); + tree cond + = maybe_constant_value (fold_non_dependent_expr_sfinae + (RECUR (TREE_OPERAND (t, 0)), tf_none)); tree exp1, exp2; if (TREE_CODE (cond) == INTEGER_CST) Index: testsuite/g++.dg/cpp0x/constexpr-63265.C === --- testsuite/g++.dg/cpp0x/constexpr-63265.C(revision 0) +++ testsuite/g++.dg/cpp0x/constexpr-63265.C(working copy) @@ -0,0 +1,19 @@ +// PR c++/63265 +// { dg-do compile { target c++11 } } + +#define LSHIFT (sizeof(unsigned int) * __CHAR_BIT__) + +template int lshift +struct SpuriouslyWarns1 { +static constexpr unsigned int v = lshift LSHIFT ? 1U lshift : 0; +}; + +static_assert(SpuriouslyWarns1LSHIFT::v == 0, Impossible occurred); + +template int lshift +struct SpuriouslyWarns2 { +static constexpr bool okay = lshift LSHIFT; +static constexpr unsigned int v = okay ? 1U lshift : 0; +}; + +static_assert(SpuriouslyWarns2LSHIFT::v == 0, Impossible occurred);
Re: [C++ Patch] PR 63265
Hi, On 11/11/2014 02:19 PM, Jason Merrill wrote: On 11/11/2014 08:04 AM, Paolo Carlini wrote: -tree cond = RECUR (TREE_OPERAND (t, 0)); +tree cond + = maybe_constant_value (fold_non_dependent_expr_sfinae + (RECUR (TREE_OPERAND (t, 0)), tf_none)); I like this approach, but if the result of maybe_constant_value doesn't turn out to be an INTEGER_CST, we want to end up with the result of RECUR rather than the result of fold_non_dependent_expr, as the latter might not be suitable for subsequent tsubsting. I see. Something like the below, then? Thanks, Paolo. / Index: cp/pt.c === --- cp/pt.c (revision 217342) +++ cp/pt.c (working copy) @@ -15138,11 +15138,13 @@ tsubst_copy_and_build (tree t, case COND_EXPR: { tree cond = RECUR (TREE_OPERAND (t, 0)); + tree folded_cond = (maybe_constant_value + (fold_non_dependent_expr_sfinae (cond, tf_none))); tree exp1, exp2; - if (TREE_CODE (cond) == INTEGER_CST) + if (TREE_CODE (folded_cond) == INTEGER_CST) { - if (integer_zerop (cond)) + if (integer_zerop (folded_cond)) { ++c_inhibit_evaluation_warnings; exp1 = RECUR (TREE_OPERAND (t, 1)); @@ -15156,6 +15158,7 @@ tsubst_copy_and_build (tree t, exp2 = RECUR (TREE_OPERAND (t, 2)); --c_inhibit_evaluation_warnings; } + cond = folded_cond; } else { Index: testsuite/g++.dg/cpp0x/constexpr-63265.C === --- testsuite/g++.dg/cpp0x/constexpr-63265.C(revision 0) +++ testsuite/g++.dg/cpp0x/constexpr-63265.C(working copy) @@ -0,0 +1,19 @@ +// PR c++/63265 +// { dg-do compile { target c++11 } } + +#define LSHIFT (sizeof(unsigned int) * __CHAR_BIT__) + +template int lshift +struct SpuriouslyWarns1 { +static constexpr unsigned int v = lshift LSHIFT ? 1U lshift : 0; +}; + +static_assert(SpuriouslyWarns1LSHIFT::v == 0, Impossible occurred); + +template int lshift +struct SpuriouslyWarns2 { +static constexpr bool okay = lshift LSHIFT; +static constexpr unsigned int v = okay ? 1U lshift : 0; +}; + +static_assert(SpuriouslyWarns2LSHIFT::v == 0, Impossible occurred);
Re: [C++ Patch] PR 63265
Hi, On 11/11/2014 04:03 PM, Jason Merrill wrote: OK. Committed. What about 4.9? Technically the issue is a regression, but in my opinion the fix isn't completely trivial for a release branch.. Paolo.
[C++ Patch/RFC] PR 60420 aka DR 1510
Hi, if I understand correctly the existing uses of tf_ignore_bad_quals, in order to correctly implement the resolution of CWG 1510, thus accept the testcases, we have to handle decltypes like references and template type arguments, thus make sure cp_build_qualified_type_real is called with | tf_ignore_bad_quals. The template case seems easy and I figured out a simple one-liner, in tsubst; the non-template case seems more tricky, because grokdeclarator sees just a reference, doesn't have the information that the type is coming from a decltype fully handled the first and only time through finish_decltype_type: in the tentative patch I resorted to an additional flag in cp_decl_specifier_seq... Patch passes testing, anyway. Thanks, Paolo. Index: cp/cp-tree.h === --- cp/cp-tree.h(revision 217407) +++ cp/cp-tree.h(working copy) @@ -4933,6 +4933,8 @@ typedef struct cp_decl_specifier_seq { BOOL_BITFIELD explicit_char_p : 1; /* True iff ds_thread is set for __thread, not thread_local. */ BOOL_BITFIELD gnu_thread_keyword_p : 1; + /* True iff the type is a decltype. */ + BOOL_BITFIELD decltype_p : 1; } cp_decl_specifier_seq; /* The various kinds of declarators. */ Index: cp/decl.c === --- cp/decl.c (revision 217407) +++ cp/decl.c (working copy) @@ -9421,7 +9421,8 @@ grokdeclarator (const cp_declarator *declarator, type_quals |= cp_type_quals (type); type = cp_build_qualified_type_real -(type, type_quals, ((typedef_decl !DECL_ARTIFICIAL (typedef_decl) +(type, type_quals, typedef_decl !DECL_ARTIFICIAL (typedef_decl)) + || declspecs-decltype_p) ? tf_ignore_bad_quals : 0) | tf_warning_or_error)); /* We might have ignored or rejected some of the qualifiers. */ type_quals = cp_type_quals (type); Index: cp/parser.c === --- cp/parser.c (revision 217407) +++ cp/parser.c (working copy) @@ -14903,9 +14903,15 @@ cp_parser_simple_type_specifier (cp_parser* parser { type = token-u.value; if (decl_specs) - cp_parser_set_decl_spec_type (decl_specs, type, - token, - /*type_definition_p=*/false); + { + cp_parser_set_decl_spec_type (decl_specs, type, + token, + /*type_definition_p=*/false); + /* Remember that we are handling a decltype in order to +correctly implement the resolution of CWG 1510 when +its argument isn't instantiation dependent. */ + decl_specs-decltype_p = true; + } cp_lexer_consume_token (parser-lexer); return type; } Index: cp/pt.c === --- cp/pt.c (revision 217407) +++ cp/pt.c (working copy) @@ -12462,7 +12462,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain return cp_build_qualified_type_real (type, cp_type_quals (t) | cp_type_quals (type), -complain); +complain | tf_ignore_bad_quals); } case UNDERLYING_TYPE: Index: testsuite/g++.dg/cpp0x/decltype61.C === --- testsuite/g++.dg/cpp0x/decltype61.C (revision 0) +++ testsuite/g++.dg/cpp0x/decltype61.C (working copy) @@ -0,0 +1,20 @@ +// DR 1510, PR c++/60420 +// { dg-do compile { target c++11 } } + +struct MyIter +{ + int operator*(); +}; + +void foo(MyIter begin) +{ + auto x = [](const decltype(*begin)) { }; +} + +templatetypename Iterator +void bar(Iterator begin) +{ + auto x = [](const decltype(*begin)) { }; +} + +template void barMyIter(MyIter);
[C++ Patch] Add maybe_constant_folded_value
Hi, shall we do something like the below? Safety checked x86_64-linux. Thanks, Paolo. /// 2014-11-13 Paolo Carlini paolo.carl...@oracle.com * constexpr.c (maybe_constant_folded_value): Add. * cp-tree.h (maybe_constant_folded_value): Declare it. * call.c (null_ptr_cst_p): Use it. * pt.c (tsubst_copy_and_build, build_non_dependent_expr): Likewise. * semantics.c (begin_maybe_infinite_loop): Likewise. * typeck.c (cp_build_binary_op): Likewise. * typeck2.c (check_narrowing): Likewise. Index: call.c === --- call.c (revision 217468) +++ call.c (working copy) @@ -572,7 +572,7 @@ null_ptr_cst_p (tree t) { /* Core issue 903 says only literal 0 is a null pointer constant. */ if (cxx_dialect cxx11) - t = maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none)); + t = maybe_constant_folded_value (t); STRIP_NOPS (t); if (integer_zerop (t) !TREE_OVERFLOW (t)) return true; Index: constexpr.c === --- constexpr.c (revision 217468) +++ constexpr.c (working copy) @@ -2914,6 +2914,14 @@ maybe_constant_value (tree t, tree decl) return r; } +/* Like maybe_constant_value but first fold the argument. */ + +tree +maybe_constant_folded_value (tree t) +{ + return maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none)); +} + /* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather than wrapped in a TARGET_EXPR. */ Index: cp-tree.h === --- cp-tree.h (revision 217468) +++ cp-tree.h (working copy) @@ -6334,6 +6334,7 @@ extern bool require_potential_rvalue_constant_expr extern tree cxx_constant_value (tree, tree = NULL_TREE); extern tree maybe_constant_value (tree, tree = NULL_TREE); extern tree maybe_constant_init(tree, tree = NULL_TREE); +extern tree maybe_constant_folded_value(tree); extern bool is_sub_constant_expr(tree); extern bool reduced_constant_expression_p (tree); extern bool is_instantiation_of_constexpr (tree); Index: pt.c === --- pt.c(revision 217468) +++ pt.c(working copy) @@ -15138,8 +15138,7 @@ tsubst_copy_and_build (tree t, case COND_EXPR: { tree cond = RECUR (TREE_OPERAND (t, 0)); - tree folded_cond = (maybe_constant_value - (fold_non_dependent_expr_sfinae (cond, tf_none))); + tree folded_cond = maybe_constant_folded_value (cond); tree exp1, exp2; if (TREE_CODE (folded_cond) == INTEGER_CST) @@ -21864,7 +21863,7 @@ build_non_dependent_expr (tree expr) /* Try to get a constant value for all non-dependent expressions in order to expose bugs in *_dependent_expression_p and constexpr. */ if (cxx_dialect = cxx11) -maybe_constant_value (fold_non_dependent_expr_sfinae (expr, tf_none)); +maybe_constant_folded_value (expr); #endif /* Preserve OVERLOADs; the functions must be available to resolve Index: semantics.c === --- semantics.c (revision 217468) +++ semantics.c (working copy) @@ -511,8 +511,7 @@ begin_maybe_infinite_loop (tree cond) bool maybe_infinite = true; if (cond) { - cond = fold_non_dependent_expr_sfinae (cond, tf_none); - cond = maybe_constant_value (cond); + cond = maybe_constant_folded_value (cond); maybe_infinite = integer_nonzerop (cond); } vec_safe_push (cp_function_chain-infinite_loops, Index: typeck.c === --- typeck.c(revision 217468) +++ typeck.c(working copy) @@ -4133,8 +4133,7 @@ cp_build_binary_op (location_t location, || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)) { enum tree_code tcode0 = code0, tcode1 = code1; - tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none); - cop1 = maybe_constant_value (cop1); + tree cop1 = maybe_constant_folded_value (op1); doing_div_or_mod = true; warn_for_div_by_zero (location, cop1); @@ -4173,8 +4172,7 @@ cp_build_binary_op (location_t location, case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: { - tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none); - cop1 = maybe_constant_value (cop1); + tree cop1 = maybe_constant_folded_value (op1); doing_div_or_mod = true; warn_for_div_by_zero (location, cop1); } @@ -4268,8 +4266,7 @@ cp_build_binary_op (location_t location, } else if (code0 == INTEGER_TYPE code1 == INTEGER_TYPE) { - tree const_op1
Re: [C++ Patch] Add maybe_constant_folded_value
Hi, On 11/13/2014 05:42 PM, Jason Merrill wrote: On 11/13/2014 11:10 AM, Jason Merrill wrote: On 11/13/2014 05:47 AM, Paolo Carlini wrote: shall we do something like the below? Something similar, yes. Though it would also be nice to avoid the redundant checking in the two functions: we only want to do constexpr folding if we did the tsubst. Kai is working on folding changes, so I think let's let him weigh in on how this will interact with his work. Kai says this is fine with him. I think I'd like to rename the current fold_non_dependent_expr* to instantiate_non_dependent_expr* and make your new function fold_non_dependent_expr, since it's the one that's doing full constant folding. Good. Then I'm finishing sanity checking the below. While we are at it, can you double check that in end_maybe_infinite_loop we really want the non-sfinae version (which in principle can emit hard errors): the inconsistency with begin_maybe_infinite_loop seems weird to me... Thanks! Paolo. 2014-11-13 Paolo Carlini paolo.carl...@oracle.com * constexpr.c (fold_non_dependent_expr): Add. * cp-tree.h (fold_non_dependent_expr): Declare it. * call.c (null_ptr_cst_p): Use it. * pt.c (tsubst_copy_and_build, build_non_dependent_expr): Likewise. * semantics.c (begin_maybe_infinite_loop): Likewise. * typeck.c (cp_build_binary_op): Likewise. * typeck2.c (check_narrowing): Likewise. * pt.c (fold_non_dependent_expr): Rename to instantiate_non_dependent_expr. (fold_non_dependent_expr_sfinae): Rename to instantiate_non_dependent_expr_sfinae. (convert_nontype_argument, build_non_dependent_expr): Adjust. * decl.c (compute_array_index_type): Likewise. * parser.c (cp_parser_parenthesized_expression_list, cp_parser_enumerator_definition, cp_parser_omp_clause_collapse): Likewise. * semantics.c (end_maybe_infinite_loop, finish_static_assert): Likewise. * typeck.c (cxx_alignas_expr): Likewise. * typeck2.c (store_init_value, massage_init_elt): Likewise. * call.c: Adjust comments. * class.c: Likewise. * constexpr.c: Likewise. * decl2.c: Likewise. * tree.c: Likewise. Index: call.c === --- call.c (revision 217503) +++ call.c (working copy) @@ -572,7 +572,7 @@ null_ptr_cst_p (tree t) { /* Core issue 903 says only literal 0 is a null pointer constant. */ if (cxx_dialect cxx11) - t = maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none)); + t = fold_non_dependent_expr (t); STRIP_NOPS (t); if (integer_zerop (t) !TREE_OVERFLOW (t)) return true; @@ -7437,8 +7437,8 @@ build_over_call (struct z_candidate *cand, int fla return error_mark_node; if (DECL_VINDEX (fn) (flags LOOKUP_NONVIRTUAL) == 0 - /* Don't mess with virtual lookup in fold_non_dependent_expr; virtual -functions can't be constexpr. */ + /* Don't mess with virtual lookup in instantiate_non_dependent_expr; +virtual functions can't be constexpr. */ !in_template_function ()) { tree t; @@ -9361,7 +9361,7 @@ perform_implicit_conversion_flags (tree type, tree type of non-dependent expressions, so we do not have to perform the actual conversion. But for initializers, we need to be able to perform it at instantiation -(or fold_non_dependent_expr) time. */ +(or instantiate_non_dependent_expr) time. */ expr = build1 (IMPLICIT_CONV_EXPR, type, expr); if (!(flags LOOKUP_ONLYCONVERTING)) IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true; Index: class.c === --- class.c (revision 217503) +++ class.c (working copy) @@ -359,9 +359,9 @@ build_base_path (enum tree_code code, /* Don't bother with the calculations inside sizeof; they'll ICE if the source type is incomplete and the pointer value doesn't matter. In a - template (even in fold_non_dependent_expr), we don't have vtables set - up properly yet, and the value doesn't matter there either; we're just - interested in the result of overload resolution. */ + template (even in instantiate_non_dependent_expr), we don't have vtables + set up properly yet, and the value doesn't matter there either; we're + just interested in the result of overload resolution. */ if (cp_unevaluated_operand != 0 || in_template_function ()) { @@ -6933,7 +6933,8 @@ resolves_to_fixed_type_p (tree instance, int* nonn tree fixed; /* processing_template_decl can be false in a template if we're in - fold_non_dependent_expr, but we still want to suppress this check. */ + instantiate_non_dependent_expr, but we still want to suppress + this check
Re: [C++ Patch] Add maybe_constant_folded_value
Hi, On 11/13/2014 07:31 PM, Jason Merrill wrote: On 11/13/2014 12:48 PM, Paolo Carlini wrote: While we are at it, can you double check that in end_maybe_infinite_loop we really want the non-sfinae version (which in principle can emit hard errors): the inconsistency with begin_maybe_infinite_loop seems weird to me... I agree, let's use the sfinae version there too. Ok. @@ -15998,7 +15998,7 @@ cp_parser_enumerator_definition (cp_parser* parser /* integral_constant_value will pull out this expression, so make sure it's folded as appropriate. */ - value = fold_non_dependent_expr (value); + value = instantiate_non_dependent_expr (value); I think this should be replaced with fold_ if (processing_template_decl) in build_enumerator. Ok. The value can be NULL_TREE, thus in a straightforward change (per the below) I have to check for that, otherwise we crash in maybe_constant_value. Either that or just check for NULL_TREE at the beginning of maybe_constant_value itself, I guess. @@ -27724,7 +27724,7 @@ cp_parser_omp_clause_collapse (cp_parser *parser, if (num == error_mark_node) return list; - num = fold_non_dependent_expr (num); + num = instantiate_non_dependent_expr (num); I think we want fold_ here. Ok. /* When we defer constant folding within a statement, we may want to defer this folding as well. */ - tree t = fold_non_dependent_expr_sfinae (init, complain); + tree t = instantiate_non_dependent_expr_sfinae (init, complain); t = maybe_constant_init (t); Let's use it here, too. This is the relatively most tricky change: we have a regression for init/array11.C, because the gcc_assert at the end of maybe_constant_value (called by maybe_constant_init) triggers: gcc_assert (r == t || CONVERT_EXPR_P (t) || (TREE_CONSTANT (t) !TREE_CONSTANT (r)) || !cp_tree_equal (r, t)); we have VIEW_CONVERT_EXPRs, neither is constant, r != t and cp_tree_equal is true. Wild guess: are VIEW_CONVERT_EXPRs also Ok? I'm attaching what I have so far. Thanks, Paolo. / Index: call.c === --- call.c (revision 217503) +++ call.c (working copy) @@ -572,7 +572,7 @@ null_ptr_cst_p (tree t) { /* Core issue 903 says only literal 0 is a null pointer constant. */ if (cxx_dialect cxx11) - t = maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none)); + t = fold_non_dependent_expr (t); STRIP_NOPS (t); if (integer_zerop (t) !TREE_OVERFLOW (t)) return true; @@ -7437,8 +7437,8 @@ build_over_call (struct z_candidate *cand, int fla return error_mark_node; if (DECL_VINDEX (fn) (flags LOOKUP_NONVIRTUAL) == 0 - /* Don't mess with virtual lookup in fold_non_dependent_expr; virtual -functions can't be constexpr. */ + /* Don't mess with virtual lookup in instantiate_non_dependent_expr; +virtual functions can't be constexpr. */ !in_template_function ()) { tree t; @@ -9361,7 +9361,7 @@ perform_implicit_conversion_flags (tree type, tree type of non-dependent expressions, so we do not have to perform the actual conversion. But for initializers, we need to be able to perform it at instantiation -(or fold_non_dependent_expr) time. */ +(or instantiate_non_dependent_expr) time. */ expr = build1 (IMPLICIT_CONV_EXPR, type, expr); if (!(flags LOOKUP_ONLYCONVERTING)) IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true; Index: class.c === --- class.c (revision 217503) +++ class.c (working copy) @@ -359,9 +359,9 @@ build_base_path (enum tree_code code, /* Don't bother with the calculations inside sizeof; they'll ICE if the source type is incomplete and the pointer value doesn't matter. In a - template (even in fold_non_dependent_expr), we don't have vtables set - up properly yet, and the value doesn't matter there either; we're just - interested in the result of overload resolution. */ + template (even in instantiate_non_dependent_expr), we don't have vtables + set up properly yet, and the value doesn't matter there either; we're + just interested in the result of overload resolution. */ if (cp_unevaluated_operand != 0 || in_template_function ()) { @@ -6933,7 +6933,8 @@ resolves_to_fixed_type_p (tree instance, int* nonn tree fixed; /* processing_template_decl can be false in a template if we're in - fold_non_dependent_expr, but we still want to suppress this check. */ + instantiate_non_dependent_expr, but we still want to suppress + this check. */ if (in_template_function ()) { /* In a template we only care about the type of the result. */ Index: constexpr.c
Re: [C++ Patch] Add maybe_constant_folded_value
Hi, On 11/14/2014 03:35 AM, Jason Merrill wrote: On 11/13/2014 04:31 PM, Paolo Carlini wrote: I think this should be replaced with fold_ if (processing_template_decl) in build_enumerator. Ok. The value can be NULL_TREE, thus in a straightforward change (per the below) I have to check for that, otherwise we crash in maybe_constant_value. Either that or just check for NULL_TREE at the beginning of maybe_constant_value itself, I guess. The current fold_ already checks for NULL_TREE; I think we want to preserve that behavior. Ok, I added it to the new fold_. This is the relatively most tricky change: we have a regression for init/array11.C, because the gcc_assert at the end of maybe_constant_value (called by maybe_constant_init) triggers: gcc_assert (r == t || CONVERT_EXPR_P (t) || (TREE_CONSTANT (t) !TREE_CONSTANT (r)) || !cp_tree_equal (r, t)); we have VIEW_CONVERT_EXPRs, neither is constant, r != t and cp_tree_equal is true. Wild guess: are VIEW_CONVERT_EXPRs also Ok? Yes. Ok. What did you think about avoiding the duplicate instantiation_dependent_expression_p and potential_constant_expression checks? Frankly at some point I forgot that, sorry. Today I figured out the below: the new fold_non_dependent_expr is much bigger but definitely calls instantiation_dependent_expression_p and potential_constant_expression at most once and should be always logically equivalent to instantiate_non_dependent_expr_sfinae followed by maybe_constant_value, even in the special cases of those TREE_OVERFLOW_Ps. Note: among various other simplifications, I tried removing the early return via the conditional: if (type_unknown_p (t) || BRACE_ENCLOSED_INITIALIZER_P (t)) but it's actually used by eg, g++.dg/cpp0x/constexpr-initlist5.C. I'm attaching what passed testing on x86_64-linux. Thanks! Paolo. // Index: cp/call.c === --- cp/call.c (revision 217547) +++ cp/call.c (working copy) @@ -572,7 +572,7 @@ null_ptr_cst_p (tree t) { /* Core issue 903 says only literal 0 is a null pointer constant. */ if (cxx_dialect cxx11) - t = maybe_constant_value (fold_non_dependent_expr_sfinae (t, tf_none)); + t = fold_non_dependent_expr (t); STRIP_NOPS (t); if (integer_zerop (t) !TREE_OVERFLOW (t)) return true; @@ -7437,8 +7437,8 @@ build_over_call (struct z_candidate *cand, int fla return error_mark_node; if (DECL_VINDEX (fn) (flags LOOKUP_NONVIRTUAL) == 0 - /* Don't mess with virtual lookup in fold_non_dependent_expr; virtual -functions can't be constexpr. */ + /* Don't mess with virtual lookup in instantiate_non_dependent_expr; +virtual functions can't be constexpr. */ !in_template_function ()) { tree t; @@ -9361,7 +9361,7 @@ perform_implicit_conversion_flags (tree type, tree type of non-dependent expressions, so we do not have to perform the actual conversion. But for initializers, we need to be able to perform it at instantiation -(or fold_non_dependent_expr) time. */ +(or instantiate_non_dependent_expr) time. */ expr = build1 (IMPLICIT_CONV_EXPR, type, expr); if (!(flags LOOKUP_ONLYCONVERTING)) IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true; Index: cp/class.c === --- cp/class.c (revision 217547) +++ cp/class.c (working copy) @@ -359,9 +359,9 @@ build_base_path (enum tree_code code, /* Don't bother with the calculations inside sizeof; they'll ICE if the source type is incomplete and the pointer value doesn't matter. In a - template (even in fold_non_dependent_expr), we don't have vtables set - up properly yet, and the value doesn't matter there either; we're just - interested in the result of overload resolution. */ + template (even in instantiate_non_dependent_expr), we don't have vtables + set up properly yet, and the value doesn't matter there either; we're + just interested in the result of overload resolution. */ if (cp_unevaluated_operand != 0 || in_template_function ()) { @@ -6933,7 +6933,8 @@ resolves_to_fixed_type_p (tree instance, int* nonn tree fixed; /* processing_template_decl can be false in a template if we're in - fold_non_dependent_expr, but we still want to suppress this check. */ + instantiate_non_dependent_expr, but we still want to suppress + this check. */ if (in_template_function ()) { /* In a template we only care about the type of the result. */ Index: cp/constexpr.c === --- cp/constexpr.c (revision 217547) +++ cp/constexpr.c (working copy) @@ -2908,6 +2908,7 @@ maybe_constant_value (tree t, tree decl) /* cp_tree_equal looks
Re: C++ PATCH for c++/58102 (constexpr and mutable)
On 11/18/2014 02:35 PM, Jason Merrill wrote: We need to allow copy-list-initialization of constexpr variables with mutable members, too. The thing we need to avoid is not so much an full-expression with mutable-containing type as assuming that a mutable member of a variable hasn't changed since the variable was initialized. Thanks. You suggest a similar fix a while ago but I failed to pursue it, sorry. Paolo.
Re: [Patch, libstdc++/63920] Fix regex_constants::match_not_null behavior
Hi, On 11/18/2014 08:12 PM, Tim Shen wrote: Bootstrapped and tested. Jonathan lately is following your work much better than me, but naively seems weird that _M_begin is non-const and _M_end is const, a different type anyway. Paolo.
[C++ Patch] PR 55425
Hi, today I wanted to simply close this Bug as fixed, but then I noticed that Richard Smith in the audit trail argued, correctly in my opinion, that we should accept things like: constexpr const char* x() { return __func__; } in C++11 mode too, because the as if local variable specification of __func__ in the Standard doesn't matter for the purpose of constexpr, because otherwise in C++11 no constexpr function would be valid: the Standard does *not* say that __func__ is only predefined if it is used. That said, I think a quick way to accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__ is checking whether DECL_ARTIFICIAL (decl) is true on the decl. Tested x86_64-linux. Thanks, Paolo. /// /cp 2014-11-19 Paolo Carlini paolo.carl...@oracle.com PR c++/55425 * constexpr.c (constexpr_fn_retval): Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__. /testsuite 2014-11-19 Paolo Carlini paolo.carl...@oracle.com PR c++/55425 * g++.dg/cpp0x/constexpr-__func__.C Index: cp/constexpr.c === --- cp/constexpr.c (revision 217755) +++ cp/constexpr.c (working copy) @@ -616,9 +616,14 @@ constexpr_fn_retval (tree body) return break_out_target_exprs (TREE_OPERAND (body, 0)); case DECL_EXPR: - if (TREE_CODE (DECL_EXPR_DECL (body)) == USING_DECL) - return NULL_TREE; - return error_mark_node; + { + tree decl = DECL_EXPR_DECL (body); + if (TREE_CODE (decl) == USING_DECL + /* Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__. */ + || DECL_ARTIFICIAL (decl)) + return NULL_TREE; + return error_mark_node; + } case CLEANUP_POINT_EXPR: return constexpr_fn_retval (TREE_OPERAND (body, 0)); Index: testsuite/g++.dg/cpp0x/constexpr-__func__.C === --- testsuite/g++.dg/cpp0x/constexpr-__func__.C (revision 0) +++ testsuite/g++.dg/cpp0x/constexpr-__func__.C (working copy) @@ -0,0 +1,6 @@ +// PR c++/55425 +// { dg-do compile { target c++11 } } + +constexpr const char* x() { return __func__; } +constexpr const char* y() { return __FUNCTION__; } +constexpr const char* z() { return __PRETTY_FUNCTION__; }
Re: [Patch, libstdc++/63920] Fix regex_constants::match_not_null behavior
Hi Tim, On 11/19/2014 08:27 AM, Tim Shen wrote: On Tue, Nov 18, 2014 at 11:19 AM, Paolo Carlini paolo.carl...@oracle.com wrote: Jonathan lately is following your work much better than me, but naively seems weird that _M_begin is non-const and _M_end is const, a different type anyway. Hmm. The current regex_search algorithm is implemented as try match starting from _M_begin; if it doesn't match, start over from _M_begin+1, ... As we can tell, _M_begin is never changed, and it's const. The problem is when the executer reaches the accept state (which indicates a match) we use _M_current == _M_begin to verify if it's an empty match. It is possible that, when we are not in the first iteration, say, in the second iteration actually, _M_current is initialized with _M_begin+1. It turns out even _M_current has never been increased (no chars are eaten, aka empty match), _M_current != _M_begin is still true. This fix is making each regex_search iteration more thorough, with increased _M_begin, as if it's a new regex _M_search_from_first. I've carefully (admittedly, after sending this patch) inspect everywhere when _M_begin is used. It turns out _M_begin is under well-defined (the initial position of _M_current when current iteration starts) invariants (see _Executor::_M_at_begin), indicated by the use of regex_constants::match_prev_avail. This flag actually implies that __begin iterator passed into regex_search is not always the physical boundary who matches ^. Boost (and we) conforms this behavior: std::regex_search(asdf, std::regex(^asdf), std::regex_constants::match_prev_avail) returns false. It's more elegant to move _Executor::_M_search out of its class and make _M_begin still const, but _Executor costs too much to initialize. Good. To be clear, not having carefully analyzed whatsoever, my point was more about changing _M_end too, to non-const, than about not touching _M_begin. Would that make sense? Thanks, Paolo.
Re: [Patch, libstdc++/63920] Fix regex_constants::match_not_null behavior
Hi, On 11/19/2014 07:43 PM, Daniel Krügler wrote: 2014-11-19 19:42 GMT+01:00 Tim Shen tims...@google.com: On Wed, Nov 19, 2014 at 8:16 AM, Paolo Carlini paolo.carl...@oracle.com wrote: Good. To be clear, not having carefully analyzed whatsoever, my point was more about changing _M_end too, to non-const, than about not touching _M_begin. Would that make sense? Currently we never mutate _M_end. I *believe* that we still won't in the future, since _M_end is not as volatile as _M_begin. I agree with Tim here, why shouldn't the const member and the non-const member coexist? I was just aiming for consistency, from a very, very, general point of view. Jon will review the substance of the patch, anyway. Thanks! Paolo.
Re: C++ PATCH for c++/63657 (missed unused reference warning)
On 11/22/2014 03:18 AM, Jason Merrill wrote: The earlier fix for 38958 was too broad; we don't want to suppress the unused warning for all references to type with non-trivial destructor, just references bound to a temporary. Thanks! Paolo.
[C++ Patch, trivial?] PR 63905
Hi, submitter noticed that when Honza in r201994 changed DECL_CONSTRUCTOR_P/DECL_DESTRUCTOR_P to use middle-end flags forgot to remove the unused front-end flags. Tested x86_64-linux. Thanks! Paolo. PS: FWIW, the issue still exists in 4_9-branch too. /// 2014-11-23 Paolo Carlini paolo.carl...@oracle.com PR c++/63905 * cp-tree.h (lang_decl_fn): Remove constructor_attr, destructor_attr. Index: cp-tree.h === --- cp-tree.h (revision 217980) +++ cp-tree.h (working copy) @@ -2051,8 +2051,6 @@ struct GTY(()) lang_decl_fn { unsigned global_ctor_p : 1; unsigned global_dtor_p : 1; - unsigned constructor_attr : 1; - unsigned destructor_attr : 1; unsigned assignment_operator_p : 1; unsigned static_function : 1; unsigned pure_virtual : 1; @@ -2066,7 +2064,7 @@ struct GTY(()) lang_decl_fn { unsigned this_thunk_p : 1; unsigned hidden_friend_p : 1; unsigned omp_declare_reduction_p : 1; - /* No spare bits on 32-bit hosts, 32 on 64-bit hosts. */ + /* 2 spare bits on 32-bit hosts, 34 on 64-bit hosts. */ /* For a non-thunk function decl, this is a tree list of friendly classes. For a thunk function decl, it is the
[C++ Patch] PR 63203
Hi, in the audit trail Jon argued that we should have code specifically checking for references initialized with themselves (because one can't rebind references). I added to his draft a STRIP_NOPS, which manages to get back to the decl on the right hand side which we are looking for + minor tweaks. To make sure that the patch is safe from the false positives point of view, I also ran the testsuite with -Winit-self enabled by default and only g++.dg/init/ref6.C, correctly, showed up. Tested x86_64-linux. Thanks, Paolo. /cp 2014-11-24 Jonathan Wakely jwak...@redhat.com Paolo Carlini paolo.carl...@oracle.com PR c++/63203 * decl.c (initialize_local_var): Add -Winit-self warning for references initialized with themselves. /testsuite 2014-11-24 Jonathan Wakely jwak...@redhat.com Paolo Carlini paolo.carl...@oracle.com PR c++/63203 * g++.dg/warn/Winit-self-2.C: New. Index: cp/decl.c === --- cp/decl.c (revision 217980) +++ cp/decl.c (working copy) @@ -6132,13 +6132,23 @@ initialize_local_var (tree decl, tree init) /* Perform the initialization. */ if (init) { - if (TREE_CODE (init) == INIT_EXPR - !TREE_SIDE_EFFECTS (TREE_OPERAND (init, 1))) + tree rinit = (TREE_CODE (init) == INIT_EXPR + ? TREE_OPERAND (init, 1) : NULL_TREE); + if (rinit !TREE_SIDE_EFFECTS (rinit)) { /* Stick simple initializers in DECL_INITIAL so that -Wno-init-self works (c++/34772). */ gcc_assert (TREE_OPERAND (init, 0) == decl); - DECL_INITIAL (decl) = TREE_OPERAND (init, 1); + DECL_INITIAL (decl) = rinit; + + if (warn_init_self TREE_CODE (type) == REFERENCE_TYPE) + { + STRIP_NOPS (rinit); + if (rinit == decl) + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Winit_self, + reference %qD is initialized with itself, decl); + } } else { Index: testsuite/g++.dg/warn/Winit-self-2.C === --- testsuite/g++.dg/warn/Winit-self-2.C(revision 0) +++ testsuite/g++.dg/warn/Winit-self-2.C(working copy) @@ -0,0 +1,12 @@ +// PR c++/63203 +// { dg-options -Winit-self } + +struct string { }; + +int main() +{ + for (int ii = 0; ii 1; ++ii) + { +const string str = str; // { dg-warning is initialized with itself } + } +}
Re: [PATCH] Fix dump scan in test devirt-40.C
Hi, On 11/12/2014 03:02 AM, H.J. Lu wrote: I am checking in this. Looks like devirt-42.C is failing again and reverting your tweak would fix it?!? Thanks, Paolo.
Re: [PATCH] Fix dump scan in test devirt-40.C
Hi again, On 11/24/2014 07:33 PM, Paolo Carlini wrote: Hi, On 11/12/2014 03:02 AM, H.J. Lu wrote: I am checking in this. Looks like devirt-42.C is failing again and reverting your tweak would fix it?!? Sorry, in fact now the line failing is First type is base of second 3, a different one. Paolo.
[C++ Patch/RFC] PR 63757
Hi, in this rejects-valid, as part of build_user_type_conversion_1, standard_conversion is called by implicit_conversion with a *null* expr, thus the condition in standard_conversion /* [conv.ptr] A null pointer constant can be converted to a pointer type; ... A null pointer constant of integral type can be converted to an rvalue of type std::nullptr_t. */ if ((tcode == POINTER_TYPE || TYPE_PTRMEM_P (to) || NULLPTR_TYPE_P (to)) expr null_ptr_cst_p (expr)) conv = build_conv (ck_std, to, conv); is false and the snippet is rejected. Should we pass a nullptr_node as expr in such cases, ie, when handling conversions functions returning std::nullptr_t?!? The below passes testing. Thanks, Paolo. // Index: cp/call.c === --- cp/call.c (revision 218022) +++ cp/call.c (working copy) @@ -3685,7 +3685,8 @@ build_user_type_conversion_1 (tree totype, tree ex conversion *ics = implicit_conversion (totype, rettype, - 0, + NULLPTR_TYPE_P (rettype) + ? nullptr_node : NULL_TREE, /*c_cast_p=*/false, convflags, complain); Index: testsuite/g++.dg/cpp0x/nullptr33.C === --- testsuite/g++.dg/cpp0x/nullptr33.C (revision 0) +++ testsuite/g++.dg/cpp0x/nullptr33.C (working copy) @@ -0,0 +1,19 @@ +// PR c++/63757 +// { dg-do compile { target c++11 } } + +typedef decltype(nullptr) nullptr_t; + +void bar(void*) {} + +struct foo +{ + operator nullptr_t() + { +return nullptr; + } +}; + +int main() +{ + bar(foo()); +}
[C++ Patch] PR 63786
Hi, we are crashing on this kind of invalid code because we don't early check the case with check_for_bare_parameter_packs. Tested x86_64-linux. Thanks, Paolo. // /cp 2014-11-25 Paolo Carlini paolo.carl...@oracle.com PR c++/63786 * parser.c (cp_parser_label_for_labeled_statement): Check the case with check_for_bare_parameter_packs. /testsuite 2014-11-25 Paolo Carlini paolo.carl...@oracle.com PR c++/63786 * g++.dg/cpp0x/variadic163.C: New. Index: cp/parser.c === --- cp/parser.c (revision 218039) +++ cp/parser.c (working copy) @@ -9820,6 +9820,8 @@ cp_parser_label_for_labeled_statement (cp_parser* cp_lexer_consume_token (parser-lexer); /* Parse the constant-expression. */ expr = cp_parser_constant_expression (parser); + if (check_for_bare_parameter_packs (expr)) + expr = error_mark_node; ellipsis = cp_lexer_peek_token (parser-lexer); if (ellipsis-type == CPP_ELLIPSIS) @@ -9826,8 +9828,9 @@ cp_parser_label_for_labeled_statement (cp_parser* { /* Consume the `...' token. */ cp_lexer_consume_token (parser-lexer); - expr_hi = - cp_parser_constant_expression (parser); + expr_hi = cp_parser_constant_expression (parser); + if (check_for_bare_parameter_packs (expr_hi)) + expr_hi = error_mark_node; /* We don't need to emit warnings here, as the common code will do this for us. */ Index: testsuite/g++.dg/cpp0x/variadic163.C === --- testsuite/g++.dg/cpp0x/variadic163.C(revision 0) +++ testsuite/g++.dg/cpp0x/variadic163.C(working copy) @@ -0,0 +1,21 @@ +// PR c++/63786 +// { dg-do compile { target c++11 } } +// { dg-options } + +template int... Is +int f(int i) { +switch (i) { +case Is: // { dg-error not expanded } +return 0; +} + +switch (i) { +case 0 ...Is: // { dg-error not expanded } +return 0; +} +return 0; +} + +int main() { +f1,2,3(1); +}
Re: [C++ Patch/RFC] PR 63757
Hi, On 11/26/2014 05:24 PM, Jason Merrill wrote: On 11/24/2014 01:55 PM, Paolo Carlini wrote: in this rejects-valid, as part of build_user_type_conversion_1, standard_conversion is called by implicit_conversion with a *null* expr, thus the condition in standard_conversion /* [conv.ptr] A null pointer constant can be converted to a pointer type; ... A null pointer constant of integral type can be converted to an rvalue of type std::nullptr_t. */ if ((tcode == POINTER_TYPE || TYPE_PTRMEM_P (to) || NULLPTR_TYPE_P (to)) expr null_ptr_cst_p (expr)) conv = build_conv (ck_std, to, conv); is false and the snippet is rejected. Should we pass a nullptr_node as expr in such cases, ie, when handling conversions functions returning std::nullptr_t?!? I'd prefer to change the test quoted above to not require expr to be non-null in the case of NULLPTR_TYPE_P. Oh good, I was unsure about that. The below also passes testing. Thanks, Paolo. /// Index: cp/call.c === --- cp/call.c (revision 218089) +++ cp/call.c (working copy) @@ -1194,7 +1194,8 @@ standard_conversion (tree to, tree from, tree expr rvalue of type std::nullptr_t. */ if ((tcode == POINTER_TYPE || TYPE_PTRMEM_P (to) || NULLPTR_TYPE_P (to)) - expr null_ptr_cst_p (expr)) + ((expr null_ptr_cst_p (expr)) + || NULLPTR_TYPE_P (from))) conv = build_conv (ck_std, to, conv); else if ((tcode == INTEGER_TYPE fcode == POINTER_TYPE) || (tcode == POINTER_TYPE fcode == INTEGER_TYPE)) Index: testsuite/g++.dg/cpp0x/nullptr33.C === --- testsuite/g++.dg/cpp0x/nullptr33.C (revision 0) +++ testsuite/g++.dg/cpp0x/nullptr33.C (working copy) @@ -0,0 +1,19 @@ +// PR c++/63757 +// { dg-do compile { target c++11 } } + +typedef decltype(nullptr) nullptr_t; + +void bar(void*) {} + +struct foo +{ + operator nullptr_t() + { +return nullptr; + } +}; + +int main() +{ + bar(foo()); +}
[C++ Patch PING] Re: [PATCH] make excessive template instantiation depth a fatal error
Hi all, hi Jason, On 08/24/2014 12:11 PM, Manuel López-Ibáñez wrote: PING: https://gcc.gnu.org/ml/gcc-patches/2014-08/msg01709.html Today, I picked this unreviewed patch prepared by Manuel back in August and trivially completed it by adjusting the testcases (all the tweaks seem the expected ones given the patch proper, no surprises). How does it look? Thanks! Paolo. // 2014-09-30 Paolo Carlini paolo.carl...@oracle.com * g++.dg/cpp0x/decltype26.C: Adjust. * g++.dg/cpp0x/decltype28.C: Likewise. * g++.dg/cpp0x/decltype29.C: Likewise. * g++.dg/cpp0x/decltype32.C: Likewise. * g++.dg/cpp0x/enum11.C: Likewise. * g++.dg/template/arrow1.C: Likewise. * g++.dg/template/pr23510.C: Likewise. * g++.dg/template/recurse.C: Likewise. * g++.dg/template/recurse2.C: Likewise. * g++.dg/template/vtable2.C: Likewise. * g++.old-deja/g++.pt/infinite1.C: Likewise.
Re: [C++ Patch PING] Re: [PATCH] make excessive template instantiation depth a fatal error
... forgot to attach the complete patch ;) Paolo. Index: cp/cp-tree.h === --- cp/cp-tree.h(revision 215710) +++ cp/cp-tree.h(working copy) @@ -5418,7 +5418,6 @@ extern const char *lang_decl_name (tree, int, boo extern const char *lang_decl_dwarf_name(tree, int, bool); extern const char *language_to_string (enum languages); extern const char *class_key_or_enum_as_string (tree); -extern void print_instantiation_context(void); extern void maybe_warn_variadic_templates (void); extern void maybe_warn_cpp0x (cpp0x_warn_str str); extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); @@ -5633,7 +5632,7 @@ extern tree tsubst_copy_and_build (tree, tree, ts tree, bool, bool); extern tree most_general_template (tree); extern tree get_mostly_instantiated_function_type (tree); -extern int problematic_instantiation_changed (void); +extern bool problematic_instantiation_changed (void); extern void record_last_problematic_instantiation (void); extern struct tinst_level *current_instantiation(void); extern tree maybe_get_template_decl_from_type_decl (tree); @@ -5661,7 +5660,8 @@ extern tree fold_non_dependent_expr_sfinae(tree, extern bool alias_type_or_template_p(tree); extern bool alias_template_specialization_p (const_tree); extern bool explicit_class_specialization_p (tree); -extern int push_tinst_level (tree); +extern bool push_tinst_level(tree); +extern bool push_tinst_level_loc(tree, location_t); extern void pop_tinst_level (void); extern struct tinst_level *outermost_tinst_level(void); extern void init_template_processing (void); Index: cp/error.c === --- cp/error.c (revision 215710) +++ cp/error.c (working copy) @@ -3360,16 +3360,6 @@ maybe_print_instantiation_context (diagnostic_cont record_last_problematic_instantiation (); print_instantiation_full_context (context); } - -/* Report the bare minimum context of a template instantiation. */ -void -print_instantiation_context (void) -{ - print_instantiation_partial_context -(global_dc, current_instantiation (), input_location); - pp_newline (global_dc-printer); - diagnostic_flush_buffer (global_dc); -} /* Report what constexpr call(s) we're trying to expand, if any. */ Index: cp/pt.c === --- cp/pt.c (revision 215710) +++ cp/pt.c (working copy) @@ -8347,26 +8347,26 @@ static GTY(()) struct tinst_level *last_error_tins /* We're starting to instantiate D; record the template instantiation context for diagnostics and to restore it later. */ -int +bool push_tinst_level (tree d) { + return push_tinst_level_loc (d, input_location); +} + +/* We're starting to instantiate D; record the template instantiation context + at LOC for diagnostics and to restore it later. */ + +bool +push_tinst_level_loc (tree d, location_t loc) +{ struct tinst_level *new_level; if (tinst_depth = max_tinst_depth) { - last_error_tinst_level = current_tinst_level; - if (TREE_CODE (d) == TREE_LIST) - error (template instantiation depth exceeds maximum of %d (use - -ftemplate-depth= to increase the maximum) substituting %qS, - max_tinst_depth, d); - else - error (template instantiation depth exceeds maximum of %d (use - -ftemplate-depth= to increase the maximum) instantiating %qD, - max_tinst_depth, d); - - print_instantiation_context (); - - return 0; + fatal_error (template instantiation depth exceeds maximum of %d +(use -ftemplate-depth= to increase the maximum), + max_tinst_depth); + return false; } /* If the current instantiation caused problems, don't let it instantiate @@ -8373,11 +8373,11 @@ push_tinst_level (tree d) anything else. Do allow deduction substitution and decls usable in constant expressions. */ if (limit_bad_template_recursion (d)) -return 0; +return false; new_level = ggc_alloctinst_level (); new_level-decl = d; - new_level-locus = input_location; + new_level-locus = loc; new_level-errors = errorcount+sorrycount; new_level-in_system_header_p = in_system_header_at (input_location); new_level-next = current_tinst_level; @@ -8387,7 +8387,7 @@ push_tinst_level (tree d) if (GATHER_STATISTICS (tinst_depth depth_reached)) depth_reached = tinst_depth; - return 1; + return true; } /* We're done instantiating this template; return to the instantiation @@ -20291,10
Re: [C++ Patch PING] Re: [PATCH] make excessive template instantiation depth a fatal error
Hi, On 09/30/2014 04:51 PM, Manuel López-Ibáñez wrote: I don't want to cause you more work Paolo, but perhaps this should be documented in https://gcc.gnu.org/gcc-5/changes.html. ? Something like: * Excessive template instantiation depth is now a fatal error. This prevents excessive diagnostics that usually do not help to identify the problem. Thanks for taking care of this! You are welcome. No problem about the changes.html bits, I'll take care of that too. Paolo.
Re: C++ PATCHes to add __is_trivially_*
Hi, On 09/30/2014 07:13 PM, Jason Merrill wrote: Ville asked for help with the necessary compiler intrinsics for the is_trivially_* C++11 library traits. The first patch cleans up a few oddities I noticed with the existing intrinsics. __is_convertible_to was never implemented and isn't needed. There's no need for a second grokdeclarator in trait parsing since cp_parser_type_id already does a grokdeclarator. And the assert at the top of finish_trait_expr is redundant with the gcc_unreachable in the switch. The second patch adds __is_trivially_copyable, which just uses the existing trivially_copyable_p predicate in the compiler. The third patch adds __is_trivially_assignable and __is_trivially_constructible, which work by building up an expression representing assignment or object declaration and then scanning it for calls to functions other than trivial special member functions. Note that there are still bugs in trivial_fn_p that are exposed by this intrinsic. Great. I think this can be as well marked as PR c++/26099. By the way, if I remember correctly, the idea of having __is_convertible_to leading to unimplemented instead of simply being not recognized, goes back to this kind of idea: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2518.html and Intel too was in favor of somewhat standardizing those intrinsics. In fact, both current icc and clang++ accept and implement __is_convertible_to. Paolo.
Re: C++ PATCHes to add __is_trivially_*
Hi, On 10/01/2014 12:48 AM, Ville Voutilainen wrote: Ville asked for help with the necessary compiler intrinsics for the is_trivially_* C++11 library traits. The first patch cleans up a few oddities I noticed with the Great. I think this can be as well marked as PR c++/26099. There's also PR c++/63362. I see. Then we can resolve both, I'll do that. Thanks! Paolo.
Re: C++ PATCHes to add __is_trivially_*
Hi again, On 10/01/2014 12:48 AM, Ville Voutilainen wrote: The intrinsics still fail to support certain variadic cases, such as template class T, class... Args void bar() { static_assert(__is_trivially_constructible(T, Args...), ); } ... depending on your arrangements with Jason you may or may not want to open a separate bug report for this... Paolo.
[C++ Patch/RFC] PR 53025
Hi, in this issue Daniel argued that the value of a noexcept expression should not depend on constructor elision. Then, in the audit trail Marc tentatively suggested something like the parser.c hunk below, which just disables our -felide-constructors optimization when parsing the noexcept expression. Over the last couple of days, I had a look, noticed that in any case we still have to handle templates, thus the pt.c hunk, and also that maybe we can avoid completely disabling -felide-constructors in noexcept expressions when we know for sure that the constructor at issue doen't throw: for that in call.s I'm further abusing the flag_elide_constructors global, in terms of using a special value of 2 when flag_elide_constructor is found == 1 when handling the expression. The below passes testing, anyway. Thanks! Paolo. /// Index: cp/call.c === --- cp/call.c (revision 215750) +++ cp/call.c (working copy) @@ -7249,9 +7249,14 @@ build_over_call (struct z_candidate *cand, int fla if (! flag_elide_constructors) /* Do things the hard way. */; - else if (cand-num_convs == 1 -(DECL_COPY_CONSTRUCTOR_P (fn) - || DECL_MOVE_CONSTRUCTOR_P (fn))) + else if ((cand-num_convs == 1 +(DECL_COPY_CONSTRUCTOR_P (fn) + || DECL_MOVE_CONSTRUCTOR_P (fn))) + (flag_elide_constructors == 1 + || (flag_elide_constructors == 2 + (!DEFERRED_NOEXCEPT_SPEC_P + (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))) + type_noexcept_p (TREE_TYPE (fn)) { tree targ; tree arg = argarray[num_artificial_parms_for (fn)]; Index: cp/parser.c === --- cp/parser.c (revision 215750) +++ cp/parser.c (working copy) @@ -7136,10 +7136,15 @@ cp_parser_unary_expression (cp_parser *parser, boo bool saved_integral_constant_expression_p; bool saved_non_integral_constant_expression_p; bool saved_greater_than_is_operator_p; + int saved_flag_elide_constructors; cp_lexer_consume_token (parser-lexer); cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); + saved_flag_elide_constructors = flag_elide_constructors; + if (flag_elide_constructors == 1) + flag_elide_constructors = 2; + saved_message = parser-type_definition_forbidden_message; parser-type_definition_forbidden_message = G_(types may not be defined in %noexcept% expressions); @@ -7170,6 +7175,8 @@ cp_parser_unary_expression (cp_parser *parser, boo parser-type_definition_forbidden_message = saved_message; + flag_elide_constructors = saved_flag_elide_constructors; + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); return finish_noexcept_expr (expr, tf_warning_or_error); } Index: cp/pt.c === --- cp/pt.c (revision 215750) +++ cp/pt.c (working copy) @@ -14766,15 +14766,22 @@ tsubst_copy_and_build (tree t, } case NOEXCEPT_EXPR: - op1 = TREE_OPERAND (t, 0); - ++cp_unevaluated_operand; - ++c_inhibit_evaluation_warnings; - op1 = tsubst_copy_and_build (op1, args, complain, in_decl, - /*function_p=*/false, - /*integral_constant_expression_p=*/false); - --cp_unevaluated_operand; - --c_inhibit_evaluation_warnings; - RETURN (finish_noexcept_expr (op1, complain)); + { + int saved_flag_elide_constructors; + op1 = TREE_OPERAND (t, 0); + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; + saved_flag_elide_constructors = flag_elide_constructors; + if (flag_elide_constructors == 1) + flag_elide_constructors = 2; + op1 = tsubst_copy_and_build (op1, args, complain, in_decl, +/*function_p=*/false, +/*integral_constant_expression_p=*/false); + flag_elide_constructors = saved_flag_elide_constructors; + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; + RETURN (finish_noexcept_expr (op1, complain)); + } case MODOP_EXPR: { Index: testsuite/g++.dg/cpp0x/noexcept23.C === --- testsuite/g++.dg/cpp0x/noexcept23.C (revision 0) +++ testsuite/g++.dg/cpp0x/noexcept23.C (working copy) @@ -0,0 +1,14 @@ +// PR c++/53025 +// { dg-do compile { target c++11 } } + +struct A { + A() noexcept {} + A(const A) noexcept(false) {} +}; + +void a(A) noexcept {} + +void f() +{ + static_assert(!noexcept(a(A{})), ); +} Index: testsuite/g++.dg/cpp0x/noexcept24.C
Re: [C++ Patch/RFC] PR 53025
Hi, On 10/02/2014 05:22 AM, Jason Merrill wrote: On 10/01/2014 12:31 PM, Paolo Carlini wrote: in this issue Daniel argued that the value of a noexcept expression should not depend on constructor elision. I'm open to that, but I don't think it's at all clear in the standard. Ok. Personally, I find the analysis in the audit trail rather convincing. In practice, clang++ definitely agrees, likewise SolarisStudio. Current EDG seems inconsistent, the templated and non-templated cases are handled differently. Then, in the audit trail Marc tentatively suggested something like the parser.c hunk below, which just disables our -felide-constructors optimization when parsing the noexcept expression. Over the last couple of days, I had a look, noticed that in any case we still have to handle templates, thus the pt.c hunk, and also that maybe we can avoid completely disabling -felide-constructors in noexcept expressions when we know for sure that the constructor at issue doen't throw: for that in call.s I'm further abusing the flag_elide_constructors global, in terms of using a special value of 2 when flag_elide_constructor is found == 1 when handling the expression. The below passes testing, anyway. Why do we want to avoid completely disabling -felide-constructors, since it's an unevaluated context anyway? Agreed. If you're going to mess with this flag you need to save/restore it in push/pop_to_top_level as well. I see. But then if we have to do take care of that I find much more clean to just add a global?!? In any case, if I understand correctly the logic at the end of push_to_top_level, it would be tricky to reset the flag to a sensible value (by default would be 1, but the user may have passed -fno-elide-constructors on the command line). The below passes testing. Thanks! Paolo. Index: cp/call.c === --- cp/call.c (revision 215797) +++ cp/call.c (working copy) @@ -7251,7 +7251,11 @@ build_over_call (struct z_candidate *cand, int fla /* Do things the hard way. */; else if (cand-num_convs == 1 (DECL_COPY_CONSTRUCTOR_P (fn) - || DECL_MOVE_CONSTRUCTOR_P (fn))) + || DECL_MOVE_CONSTRUCTOR_P (fn)) + /* It's unsafe to elide the constructor when handling + a noexcept-expression, it may evaluate to the wrong + value (c++/53025). */ + cp_noexcept_operand == 0) { tree targ; tree arg = argarray[num_artificial_parms_for (fn)]; Index: cp/cp-tree.h === --- cp/cp-tree.h(revision 215797) +++ cp/cp-tree.h(working copy) @@ -1058,6 +1058,7 @@ struct GTY(()) saved_scope { int unevaluated_operand; int inhibit_evaluation_warnings; + int noexcept_operand; /* If non-zero, implicit omp declare target attribute is added into the attribute lists. */ int omp_declare_target_attribute; @@ -4399,6 +4400,10 @@ extern int comparing_specializations; extern int cp_unevaluated_operand; +/* Nonzero if we are parsing the operand of a noexcept operator. */ + +extern int cp_noexcept_operand; + /* in pt.c */ /* These values are used for the `STRICT' parameter to type_unification and Index: cp/name-lookup.c === --- cp/name-lookup.c(revision 215797) +++ cp/name-lookup.c(working copy) @@ -6139,6 +6139,7 @@ push_to_top_level (void) s-function_decl = current_function_decl; s-unevaluated_operand = cp_unevaluated_operand; s-inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + s-noexcept_operand = cp_noexcept_operand; s-x_stmt_tree.stmts_are_full_exprs_p = true; scope_chain = s; @@ -6149,6 +6150,7 @@ push_to_top_level (void) push_class_stack (); cp_unevaluated_operand = 0; c_inhibit_evaluation_warnings = 0; + cp_noexcept_operand = 0; timevar_cond_stop (TV_NAME_LOOKUP, subtime); } @@ -6182,6 +6184,7 @@ pop_from_top_level_1 (void) current_function_decl = s-function_decl; cp_unevaluated_operand = s-unevaluated_operand; c_inhibit_evaluation_warnings = s-inhibit_evaluation_warnings; + cp_noexcept_operand = s-noexcept_operand; } /* Wrapper for pop_from_top_level_1. */ Index: cp/parser.c === --- cp/parser.c (revision 215797) +++ cp/parser.c (working copy) @@ -259,6 +259,9 @@ static FILE *cp_lexer_debug_stream; sizeof, typeof, or alignof. */ int cp_unevaluated_operand; +/* Nonzero if we are parsing the operand of a noexcept operator. */ +int cp_noexcept_operand; + /* Dump up to NUM tokens in BUFFER to FILE starting with token START_TOKEN. If START_TOKEN is NULL, the dump starts with the first token in BUFFER. If NUM is 0, dump all the tokens. If @@ -7156,7 +7159,9 @@ cp_parser_unary_expression (cp_parser *parser, boo
Re: [C++ Patch/RFC] PR 53025
Hi, On 10/02/2014 04:26 PM, Jason Merrill wrote: On 10/02/2014 08:11 AM, Paolo Carlini wrote: +/* Nonzero if we are parsing the operand of a noexcept operator. */ + +extern int cp_noexcept_operand; Rather than add a global variable, let's look it up in scope_chain directly, like current_namespace and such. I see, thanks (I'm not very familiar with scope_chain). Thus something like the below? It passes testing. Thanks again, Paolo. / Index: cp/call.c === --- cp/call.c (revision 215801) +++ cp/call.c (working copy) @@ -7251,7 +7251,11 @@ build_over_call (struct z_candidate *cand, int fla /* Do things the hard way. */; else if (cand-num_convs == 1 (DECL_COPY_CONSTRUCTOR_P (fn) - || DECL_MOVE_CONSTRUCTOR_P (fn))) + || DECL_MOVE_CONSTRUCTOR_P (fn)) + /* It's unsafe to elide the constructor when handling + a noexcept-expression, it may evaluate to the wrong + value (c++/53025). */ + cp_noexcept_operand == 0) { tree targ; tree arg = argarray[num_artificial_parms_for (fn)]; Index: cp/cp-tree.h === --- cp/cp-tree.h(revision 215801) +++ cp/cp-tree.h(working copy) @@ -1058,6 +1058,7 @@ struct GTY(()) saved_scope { int unevaluated_operand; int inhibit_evaluation_warnings; + int noexcept_operand; /* If non-zero, implicit omp declare target attribute is added into the attribute lists. */ int omp_declare_target_attribute; @@ -1124,6 +1125,10 @@ struct GTY(()) saved_scope { #define local_specializations scope_chain-x_local_specializations +/* Nonzero if we are parsing the operand of a noexcept operator. */ + +#define cp_noexcept_operand scope_chain-noexcept_operand + /* A list of private types mentioned, for deferred access checking. */ extern GTY(()) struct saved_scope *scope_chain; Index: cp/name-lookup.c === --- cp/name-lookup.c(revision 215801) +++ cp/name-lookup.c(working copy) @@ -6139,6 +6139,7 @@ push_to_top_level (void) s-function_decl = current_function_decl; s-unevaluated_operand = cp_unevaluated_operand; s-inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + s-noexcept_operand = scope_chain ? cp_noexcept_operand : 0; s-x_stmt_tree.stmts_are_full_exprs_p = true; scope_chain = s; @@ -6182,6 +6183,7 @@ pop_from_top_level_1 (void) current_function_decl = s-function_decl; cp_unevaluated_operand = s-unevaluated_operand; c_inhibit_evaluation_warnings = s-inhibit_evaluation_warnings; + cp_noexcept_operand = s-noexcept_operand; } /* Wrapper for pop_from_top_level_1. */ Index: cp/parser.c === --- cp/parser.c (revision 215801) +++ cp/parser.c (working copy) @@ -7156,7 +7156,9 @@ cp_parser_unary_expression (cp_parser *parser, boo ++cp_unevaluated_operand; ++c_inhibit_evaluation_warnings; + ++cp_noexcept_operand; expr = cp_parser_expression (parser); + --cp_noexcept_operand; --c_inhibit_evaluation_warnings; --cp_unevaluated_operand; Index: cp/pt.c === --- cp/pt.c (revision 215801) +++ cp/pt.c (working copy) @@ -14769,11 +14769,13 @@ tsubst_copy_and_build (tree t, op1 = TREE_OPERAND (t, 0); ++cp_unevaluated_operand; ++c_inhibit_evaluation_warnings; + ++cp_noexcept_operand; op1 = tsubst_copy_and_build (op1, args, complain, in_decl, /*function_p=*/false, /*integral_constant_expression_p=*/false); --cp_unevaluated_operand; --c_inhibit_evaluation_warnings; + --cp_noexcept_operand; RETURN (finish_noexcept_expr (op1, complain)); case MODOP_EXPR: Index: testsuite/g++.dg/cpp0x/noexcept23.C === --- testsuite/g++.dg/cpp0x/noexcept23.C (revision 0) +++ testsuite/g++.dg/cpp0x/noexcept23.C (working copy) @@ -0,0 +1,14 @@ +// PR c++/53025 +// { dg-do compile { target c++11 } } + +struct A { + A() noexcept {} + A(const A) noexcept(false) {} +}; + +void a(A) noexcept {} + +void f() +{ + static_assert(!noexcept(a(A{})), ); +} Index: testsuite/g++.dg/cpp0x/noexcept24.C === --- testsuite/g++.dg/cpp0x/noexcept24.C (revision 0) +++ testsuite/g++.dg/cpp0x/noexcept24.C (working copy) @@ -0,0 +1,22 @@ +// PR c++/53025 +// { dg-do compile { target c++11 } } + +templatetypename T +struct A { + A() noexcept {} + A(const A) noexcept(false) {} +}; + +templatetypename T +void a(AT) noexcept {} + +templatetypename T +void f
Re: [C++ Patch/RFC] PR 53025
Hi, On 10/02/2014 07:37 PM, Jason Merrill wrote: On 10/02/2014 12:44 PM, Paolo Carlini wrote: + s-noexcept_operand = scope_chain ? cp_noexcept_operand : 0; s-x_stmt_tree.stmts_are_full_exprs_p = true; scope_chain = s; @@ -6182,6 +6183,7 @@ pop_from_top_level_1 (void) current_function_decl = s-function_decl; cp_unevaluated_operand = s-unevaluated_operand; c_inhibit_evaluation_warnings = s-inhibit_evaluation_warnings; + cp_noexcept_operand = s-noexcept_operand; The benefit of putting it in scope_chain directly is that you don't need to change anything here. OK without these changes. Oh, nice. Then I'm going to apply the below and resolve the bug. Thanks, Paolo. /// /cp 2014-10-02 Paolo Carlini paolo.carl...@oracle.com PR c++/53025 * cp-tree.h (struct saved_scope): Add noexcept_operand. (cp_noexcept_operand): Define. * call.c (build_over_call): Use it. * parser.c (cp_parser_unary_expression, [RID_NOEXCEPT]): Likewise. * pt.c (tsubst_copy_and_build, [NOEXCEPT_EXPR]): Likewise. /testsuite 2014-10-02 Paolo Carlini paolo.carl...@oracle.com PR c++/53025 * g++.dg/cpp0x/noexcept23.C: New. * g++.dg/cpp0x/noexcept24.C: Likewise. Index: cp/call.c === --- cp/call.c (revision 215801) +++ cp/call.c (working copy) @@ -7251,7 +7251,11 @@ build_over_call (struct z_candidate *cand, int fla /* Do things the hard way. */; else if (cand-num_convs == 1 (DECL_COPY_CONSTRUCTOR_P (fn) - || DECL_MOVE_CONSTRUCTOR_P (fn))) + || DECL_MOVE_CONSTRUCTOR_P (fn)) + /* It's unsafe to elide the constructor when handling + a noexcept-expression, it may evaluate to the wrong + value (c++/53025). */ + cp_noexcept_operand == 0) { tree targ; tree arg = argarray[num_artificial_parms_for (fn)]; Index: cp/cp-tree.h === --- cp/cp-tree.h(revision 215801) +++ cp/cp-tree.h(working copy) @@ -1058,6 +1058,7 @@ struct GTY(()) saved_scope { int unevaluated_operand; int inhibit_evaluation_warnings; + int noexcept_operand; /* If non-zero, implicit omp declare target attribute is added into the attribute lists. */ int omp_declare_target_attribute; @@ -1124,6 +1125,10 @@ struct GTY(()) saved_scope { #define local_specializations scope_chain-x_local_specializations +/* Nonzero if we are parsing the operand of a noexcept operator. */ + +#define cp_noexcept_operand scope_chain-noexcept_operand + /* A list of private types mentioned, for deferred access checking. */ extern GTY(()) struct saved_scope *scope_chain; Index: cp/parser.c === --- cp/parser.c (revision 215801) +++ cp/parser.c (working copy) @@ -7156,7 +7156,9 @@ cp_parser_unary_expression (cp_parser *parser, boo ++cp_unevaluated_operand; ++c_inhibit_evaluation_warnings; + ++cp_noexcept_operand; expr = cp_parser_expression (parser); + --cp_noexcept_operand; --c_inhibit_evaluation_warnings; --cp_unevaluated_operand; Index: cp/pt.c === --- cp/pt.c (revision 215801) +++ cp/pt.c (working copy) @@ -14769,11 +14769,13 @@ tsubst_copy_and_build (tree t, op1 = TREE_OPERAND (t, 0); ++cp_unevaluated_operand; ++c_inhibit_evaluation_warnings; + ++cp_noexcept_operand; op1 = tsubst_copy_and_build (op1, args, complain, in_decl, /*function_p=*/false, /*integral_constant_expression_p=*/false); --cp_unevaluated_operand; --c_inhibit_evaluation_warnings; + --cp_noexcept_operand; RETURN (finish_noexcept_expr (op1, complain)); case MODOP_EXPR: Index: testsuite/g++.dg/cpp0x/noexcept23.C === --- testsuite/g++.dg/cpp0x/noexcept23.C (revision 0) +++ testsuite/g++.dg/cpp0x/noexcept23.C (working copy) @@ -0,0 +1,14 @@ +// PR c++/53025 +// { dg-do compile { target c++11 } } + +struct A { + A() noexcept {} + A(const A) noexcept(false) {} +}; + +void a(A) noexcept {} + +void f() +{ + static_assert(!noexcept(a(A{})), ); +} Index: testsuite/g++.dg/cpp0x/noexcept24.C === --- testsuite/g++.dg/cpp0x/noexcept24.C (revision 0) +++ testsuite/g++.dg/cpp0x/noexcept24.C (working copy) @@ -0,0 +1,22 @@ +// PR c++/53025 +// { dg-do compile { target c++11 } } + +templatetypename T +struct A { + A() noexcept {} + A(const A) noexcept(false) {} +}; + +templatetypename T +void a(AT) noexcept {} + +templatetypename T +void f() +{ + static_assert(!noexcept
Re: [C++ Patch] Add default arguments to cp_parser_assignment_expression and cp_parser_constant_expression
Hi, On 10/02/2014 08:03 PM, Jason Merrill wrote: On 08/19/2014 08:18 AM, Paolo Carlini wrote: - /*non_constant_p=*/dummy); + dummy); Why remove the comment? Oh well, the rationale was that normally we use that sort of comment only to explain integer literals, boolean literals. But I don't have a strong opinion ;) The rest of the patch is OK. Good, thanks! Paolo.
Re: [PATCH C++] - SD-6 Implementation Part 3 - .
Hi, On 10/02/2014 10:08 AM, Ed Smith-Rowland wrote: On 10/02/2014 02:51 AM, Ed Smith-Rowland wrote: On 10/01/2014 11:28 AM, Jonathan Wakely wrote: On 02/09/14 10:24 +0100, Jonathan Wakely wrote: On 01/09/14 21:46 -0400, Ed Smith-Rowland wrote: Index: include/bits/stl_function.h === --- include/bits/stl_function.h(revision 214680) +++ include/bits/stl_function.h(working copy) @@ -217,6 +217,10 @@ }; #if __cplusplus 201103L + +#define __cpp_lib_transparent_operators 201210 +#define __cpp_lib_generic_associative_lookup 201304 The generic associative lookup feature is not supported. Index: testsuite/experimental/feat-lib-fund.cc === --- testsuite/experimental/feat-lib-fund.cc(revision 0) +++ testsuite/experimental/feat-lib-fund.cc(working copy) @@ -0,0 +1,25 @@ +// { dg-options -std=gnu++14 } +// { dg-do compile } + +#include experimental/optional +#include experimental/string_view + +#if !__has_include(experimental/optional) +# error experimental/optional +#endif + +//#if !__has_include(experimental/net) +//# error experimental/net +//#endif + +//#if !__has_include(experimental/any) +//# error experimental/any +//#endif This can be uncommented, experimental/any is available. OK with those changes. Ed, the commit at http://gcc.gnu.org/r215752 doesn't have the corrections I asked for above and causes a number of test failures, could you look into it please? OK, Here is the patch. Built and tested on x86_64-linux. OK? Ed FWIW, I remember a svn tree corruption while getting this patch ready. I should have retested everything in the new tree. Sorry everyone! Here is a front-end test patch. Built and tested on x86_64-linux. OK? Having double checked that it works to avoid the spurious fail, I'm going to apply the patch as obvious. Thanks, Paolo.
Re: [PATCH 2/2] Add illegal cilk checks to C++ front.
Hi, On 10/03/2014 04:08 PM, Andi Kleen wrote: + if (check_no_cilk (destination, +Cilk array notation cannot be used as a computed goto expression, +%_Cilk_spawn% statement cannot be used as a computed goto expression)) + destination = error_mark_node; Are you sure this kind of error messages will be automatically translated without helping the machinery by wrapping the string literals in G_() ? Paolo.
Re: [PATCH 2/2] Add illegal cilk checks to C++ front.
Hi, On 10/03/2014 07:13 PM, Andi Kleen wrote: On Fri, Oct 03, 2014 at 07:10:05PM +0200, Paolo Carlini wrote: Hi, On 10/03/2014 04:08 PM, Andi Kleen wrote: + if (check_no_cilk (destination, +Cilk array notation cannot be used as a computed goto expression, +%_Cilk_spawn% statement cannot be used as a computed goto expression)) + destination = error_mark_node; Are you sure this kind of error messages will be automatically translated without helping the machinery by wrapping the string literals in G_() ? I have no idea, but there are lots of error_at() all over while don't use _. So I just follow precedence. The problem is, you are *not* calling error_at directly, you are using check_no_cilk and passing pointers. In fact, I think you actually do need G_, as in many other places of the front-end. If unsure, double check: https://gcc.gnu.org/translation.html Paolo.
Re: [PATCH 2/2] Add illegal cilk checks to C++ front.
Hi, On 10/03/2014 07:50 PM, Andi Kleen wrote: I have no idea, but there are lots of error_at() all over while don't use _. So I just follow precedence. The problem is, you are *not* calling error_at directly, you are According to Joseph it's ok because I named the arguments _msgid. Ok then, I didn't notice that. Sorry for the false alarm. Paolo.
Re: [Bug libstdc++/63456] unordered_map incorrectly frees _M_single_bucket. Patch Included
Hi, On 10/05/2014 08:50 PM, François Dumont wrote: +#include testsuite_hooks.h Seems redundant. Thanks! Paolo.
[C++ Patch] PR 55250
Hi, the second half of the bug report is about C++14 variable declarations in constexpr functions, an implementation request which should be already done by Jason's recent commit. The first half is about us not rejecting in C++11 mode type declarations in constexpr functions outside, per 7.1.5/3/4: typedef declarations and alias-declarations that do not define classes or enumerations, In fact, however, while working on the issue, I noticed that conversely we reject *all* type declarations in constructors (actually we used to ICE on those, which a while ago I turned to reject valid), eg: struct S { constexpr S() { typedef int T; } }; Thus I prepared the below, which in C++11 mode checks the exact requirements above, both for constructors and all the other functions. I had to add handling of BIND_EXPRs to the main conditional of build_constexpr_constructor_member_initializers, otherwise we ICE immediately on something as simple as the snippet above: I think all is fine because we get to the conditional having checked the BIND_EXPR_VARS part with the new checking function. Tested x86_64-linux. Thanks! Paolo. / /cp 2014-10-06 Paolo Carlini paolo.carl...@oracle.com PR c++/55250 * semantics.c (check_constexpr_bind_expr_vars): New. (check_constexpr_ctor_body, massage_constexpr_body): Use it. (build_constexpr_constructor_member_initializers): Handle BIND_EXPR in the main conditional. /testsuite 2014-10-06 Paolo Carlini paolo.carl...@oracle.com PR c++/55250 * g++.dg/cpp0x/constexpr-type-decl1.C: New. * g++.dg/cpp0x/constexpr-type-def1.C: Likewise. * g++.dg/cpp1y/constexpr-type-def1.C: Likewise. Index: cp/semantics.c === --- cp/semantics.c (revision 215914) +++ cp/semantics.c (working copy) @@ -7833,6 +7833,26 @@ build_data_member_initialization (tree t, veccons return true; } +/* Subroutine of check_constexpr_ctor_body and massage_constexpr_body. + In C++11 mode checks that the TYPE_DECLs in the BIND_EXPR_VARS of a + BIND_EXPR conform to 7.1.5/3/4 on typedef and alias declarations. */ + +static bool +check_constexpr_bind_expr_vars (tree t) +{ + gcc_assert (TREE_CODE (t) == BIND_EXPR); + + if (cxx_dialect = cxx14) +return true; + + for (tree var = BIND_EXPR_VARS (t); var; var = DECL_CHAIN (var)) +if (TREE_CODE (var) == TYPE_DECL +! is_typedef_decl (var) +! TYPE_DECL_ALIAS_P (var)) + return false; + return true; +} + /* Make sure that there are no statements after LAST in the constructor body represented by LIST. */ @@ -7850,7 +7870,7 @@ check_constexpr_ctor_body (tree last, tree list) break; if (TREE_CODE (t) == BIND_EXPR) { - if (BIND_EXPR_VARS (t)) + if (!check_constexpr_bind_expr_vars (t)) { ok = false; break; @@ -7860,8 +7880,6 @@ check_constexpr_ctor_body (tree last, tree list) else continue; } - /* We currently allow typedefs and static_assert. -FIXME allow them in the standard, too. */ if (TREE_CODE (t) != STATIC_ASSERT) { ok = false; @@ -7964,6 +7982,8 @@ build_constexpr_constructor_member_initializers (t a function-try-block); return error_mark_node; } + else if (TREE_CODE (body) == BIND_EXPR) +ok = build_data_member_initialization (BIND_EXPR_BODY (body), vec); else if (EXPR_P (body)) ok = build_data_member_initialization (body, vec); else @@ -8055,7 +8075,8 @@ massage_constexpr_body (tree fun, tree body) body = EH_SPEC_STMTS (body); if (TREE_CODE (body) == MUST_NOT_THROW_EXPR) body = TREE_OPERAND (body, 0); - if (TREE_CODE (body) == BIND_EXPR) + if (TREE_CODE (body) == BIND_EXPR + check_constexpr_bind_expr_vars (body)) body = BIND_EXPR_BODY (body); body = constexpr_fn_retval (body); } Index: testsuite/g++.dg/cpp0x/constexpr-type-decl1.C === --- testsuite/g++.dg/cpp0x/constexpr-type-decl1.C (revision 0) +++ testsuite/g++.dg/cpp0x/constexpr-type-decl1.C (working copy) @@ -0,0 +1,58 @@ +// PR c++/55250 +// { dg-do compile { target c++11 } } + +#define SA(X) static_assert((X),#X) + +struct GS { constexpr operator int() { return 1; } }; +enum GE { y = 1 }; + +constexpr int Test1(int x) { typedef int T; return T(x) + 1; } +constexpr int Test2(int x) { using T = int; return T(x) + 1; } +constexpr int Test3(int x) { typedef GS T; return x + T(); } +constexpr int Test4(int x) { using T = GS; return x + T(); } +constexpr int Test5(int x) { typedef GE T; return x + T::y; } +constexpr int Test6(int x) { using T = GE; return x + T::y; } + +SA(Test1(2) == 3); +SA