[PATCH][libsanitizer] Cherry-pick r211008 [Was: Re: libsanitizer merge from upstream r208536]

2014-06-23 Thread Paolo Carlini

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

2014-06-24 Thread Paolo Carlini

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

2014-06-24 Thread Paolo Carlini

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

2014-06-24 Thread Paolo Carlini
... 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

2014-06-24 Thread Paolo Carlini

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

2014-06-26 Thread Paolo Carlini

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

2014-06-26 Thread Paolo Carlini

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

2014-06-27 Thread Paolo Carlini

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

2014-06-27 Thread Paolo Carlini

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

2014-06-27 Thread Paolo Carlini

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

2014-06-27 Thread Paolo Carlini

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

2014-06-27 Thread Paolo Carlini

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

2014-06-27 Thread Paolo Carlini

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

2014-06-28 Thread Paolo Carlini

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

2014-06-28 Thread Paolo Carlini

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

2014-06-30 Thread Paolo Carlini

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

2014-07-01 Thread Paolo Carlini
... 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

2014-07-01 Thread Paolo Carlini

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?

2014-07-01 Thread Paolo Carlini

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

2014-07-01 Thread Paolo Carlini

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

2014-07-02 Thread Paolo Carlini
.. 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

2014-07-02 Thread Paolo Carlini

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)

2014-07-03 Thread Paolo Carlini

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

2014-07-06 Thread Paolo Carlini

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

2014-07-07 Thread Paolo Carlini

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

2014-07-07 Thread Paolo Carlini

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

2014-07-07 Thread Paolo Carlini

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

2014-07-07 Thread Paolo Carlini

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)

2014-07-08 Thread Paolo Carlini

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

2014-07-09 Thread Paolo Carlini

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

2014-07-09 Thread Paolo Carlini

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)

2014-07-09 Thread Paolo Carlini

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

2014-07-09 Thread Paolo Carlini

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

2014-07-09 Thread Paolo Carlini

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

2014-07-10 Thread Paolo Carlini

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

2014-07-10 Thread Paolo Carlini

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

2014-07-10 Thread Paolo Carlini

.. 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

2014-07-10 Thread Paolo Carlini

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

2014-07-10 Thread Paolo Carlini

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

2014-07-10 Thread Paolo Carlini
... 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

2014-07-10 Thread Paolo Carlini
... 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)

2014-07-11 Thread Paolo Carlini

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

2014-07-11 Thread Paolo Carlini

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)

2014-07-11 Thread Paolo Carlini

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

2014-07-13 Thread Paolo Carlini

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

2014-07-13 Thread Paolo Carlini

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

2014-07-13 Thread Paolo Carlini

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

2014-07-13 Thread Paolo Carlini

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

2014-07-13 Thread Paolo Carlini

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

2014-07-13 Thread Paolo Carlini

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

2014-07-14 Thread Paolo Carlini

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

2014-07-14 Thread Paolo Carlini

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

2014-07-14 Thread Paolo Carlini

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

2014-07-15 Thread Paolo Carlini

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

2014-07-15 Thread Paolo Carlini

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

2014-07-16 Thread Paolo Carlini

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

2014-07-16 Thread Paolo Carlini

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

2014-07-17 Thread Paolo Carlini

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

2014-07-26 Thread Paolo Carlini

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

2014-07-29 Thread Paolo Carlini

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

2014-07-29 Thread Paolo Carlini

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

2014-07-29 Thread Paolo Carlini

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

2014-11-11 Thread Paolo Carlini

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

2014-11-11 Thread Paolo Carlini

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

2014-11-11 Thread Paolo Carlini

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

2014-11-12 Thread Paolo Carlini

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

2014-11-13 Thread Paolo Carlini

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

2014-11-13 Thread Paolo Carlini

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

2014-11-13 Thread Paolo Carlini

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

2014-11-14 Thread Paolo Carlini

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)

2014-11-18 Thread Paolo Carlini

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

2014-11-18 Thread Paolo Carlini

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

2014-11-19 Thread Paolo Carlini

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

2014-11-19 Thread Paolo Carlini

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

2014-11-19 Thread Paolo Carlini

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)

2014-11-22 Thread Paolo Carlini

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

2014-11-23 Thread Paolo Carlini

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

2014-11-24 Thread Paolo Carlini

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

2014-11-24 Thread Paolo Carlini

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

2014-11-24 Thread Paolo Carlini

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

2014-11-24 Thread Paolo Carlini

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

2014-11-25 Thread Paolo Carlini

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

2014-11-26 Thread Paolo Carlini

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

2014-09-30 Thread Paolo Carlini

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

2014-09-30 Thread Paolo Carlini

... 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

2014-09-30 Thread Paolo Carlini

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_*

2014-09-30 Thread Paolo Carlini

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_*

2014-10-01 Thread Paolo Carlini

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_*

2014-10-01 Thread Paolo Carlini

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

2014-10-01 Thread Paolo Carlini

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

2014-10-02 Thread Paolo Carlini

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

2014-10-02 Thread Paolo Carlini

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

2014-10-02 Thread Paolo Carlini

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

2014-10-02 Thread Paolo Carlini

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 - .

2014-10-02 Thread Paolo Carlini

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.

2014-10-03 Thread Paolo Carlini

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.

2014-10-03 Thread Paolo Carlini

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.

2014-10-03 Thread Paolo Carlini

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

2014-10-05 Thread Paolo Carlini

Hi,

On 10/05/2014 08:50 PM, François Dumont wrote:

+#include testsuite_hooks.h

Seems redundant.

Thanks!
Paolo.


[C++ Patch] PR 55250

2014-10-06 Thread Paolo Carlini

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

  1   2   3   4   5   6   7   8   9   10   >