[Bug c++/58063] default arguments evaluated twice per call

2018-04-30 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

Jason Merrill  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
  Known to work||4.9.4, 5.2.0, 6.0
 Resolution|--- |FIXED
   Target Milestone|--- |4.9.4

--- Comment #17 from Jason Merrill  ---
This was fixed a while back.

[Bug c++/58063] default arguments evaluated twice per call

2015-08-18 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #16 from Jason Merrill  ---
Author: jason
Date: Tue Aug 18 14:43:38 2015
New Revision: 226973

URL: https://gcc.gnu.org/viewcvs?rev=226973&root=gcc&view=rev
Log:
PR c++/58063
* tree.c (bot_manip): Remap SAVE_EXPR.

Added:
branches/gcc-4_9-branch/gcc/testsuite/g++.dg/overload/defarg10.C
Modified:
branches/gcc-4_9-branch/gcc/cp/ChangeLog
branches/gcc-4_9-branch/gcc/cp/tree.c


[Bug c++/58063] default arguments evaluated twice per call

2015-06-21 Thread ville.voutilainen at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

Ville Voutilainen  changed:

   What|Removed |Added

 CC||ville.voutilainen at gmail dot 
com

--- Comment #15 from Ville Voutilainen  ---
*** Bug 61856 has been marked as a duplicate of this bug. ***


[Bug c++/58063] default arguments evaluated twice per call

2015-06-17 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #14 from Jason Merrill  ---
Author: jason
Date: Wed Jun 17 14:33:17 2015
New Revision: 224559

URL: https://gcc.gnu.org/viewcvs?rev=224559&root=gcc&view=rev
Log:
PR c++/58063
* tree.c (bot_manip): Remap SAVE_EXPR.

Added:
branches/gcc-5-branch/gcc/testsuite/g++.dg/overload/defarg10.C
Modified:
branches/gcc-5-branch/gcc/cp/ChangeLog
branches/gcc-5-branch/gcc/cp/tree.c


[Bug c++/58063] default arguments evaluated twice per call

2015-06-16 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #13 from Jason Merrill  ---
Author: jason
Date: Tue Jun 16 19:29:09 2015
New Revision: 224533

URL: https://gcc.gnu.org/viewcvs?rev=224533&root=gcc&view=rev
Log:
PR c++/58063
* tree.c (bot_manip): Remap SAVE_EXPR.

Added:
trunk/gcc/testsuite/g++.dg/overload/defarg10.C
Modified:
trunk/gcc/cp/ChangeLog
trunk/gcc/cp/tree.c


[Bug c++/58063] default arguments evaluated twice per call

2015-06-14 Thread plokinom at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #12 from plokinom at gmail dot com ---
I can confirm this still happens with g++ 5.1.0.


[Bug c++/58063] default arguments evaluated twice per call

2013-08-04 Thread paolo.carlini at oracle dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

Paolo Carlini  changed:

   What|Removed |Added

   Keywords||wrong-code
   Priority|P3  |P2
 Status|UNCONFIRMED |NEW
   Last reconfirmed||2013-08-04
 CC||jason at gcc dot gnu.org
 Ever confirmed|0   |1

--- Comment #11 from Paolo Carlini  ---
Thanks!


[Bug c++/58063] default arguments evaluated twice per call

2013-08-04 Thread fanael4 at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

Fanael  changed:

   What|Removed |Added

 CC||fanael4 at gmail dot com

--- Comment #10 from Fanael  ---
My attempt at reducing:

struct basic_ios
{
  virtual ~basic_ios() {}
  bool operator!() const { return false; }
};

struct ostream : virtual basic_ios
{
  ostream() {}
  ~ostream() {}
private:
  ostream(const ostream&);
  ostream& operator=(const ostream&);
};

ostream& operator<<(ostream& os, const char* s) {
  __builtin_printf("%s", s);
  return os;
}

ostream cout;

void f(bool x = !(cout << "hi!\n")) {
  __builtin_printf("%d\n", static_cast(x));
}

int main() {
  f();
}

Seems like virtual inheritance is the culprit.


[Bug c++/58063] default arguments evaluated twice per call

2013-08-03 Thread paolo.carlini at oracle dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #9 from Paolo Carlini  ---
Your help is always very appreciated, Daniel. Here we have plenty of work to do
anyway, if when you will back the bug will be unchanged, consider helping more.


[Bug c++/58063] default arguments evaluated twice per call

2013-08-03 Thread daniel.kruegler at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #8 from Daniel Krügler  ---
(In reply to Paolo Carlini from comment #7)
> But it happens with -O0 too, right?

Yes.

> In any case we badly need a reduced testcase ;)

I agree. Unfortunately I'm on vacations from tomorrow on (1 week), so I cannot
look into it until next week.

[Bug c++/58063] default arguments evaluated twice per call

2013-08-03 Thread paolo.carlini at oracle dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #7 from Paolo Carlini  ---
I'm not at all sure! But it happens with -O0 too, right?, thus at this point
the front-end seems more likely than the back-end, I would not change the
Component from c++ to something else. In any case we badly need a reduced
testcase ;)


[Bug c++/58063] default arguments evaluated twice per call

2013-08-03 Thread daniel.kruegler at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #6 from Daniel Krügler  ---
(In reply to Paolo Carlini from comment #5)
> Ah, in case isn't obvious already: it only happens when the "I/O expression"
> has the ! operator in front.

I suspected that and ensured that I added a similar operator! to my ostream
model type, but this hadn't any impact on the outcome for that type. Further, I
don't understand how it is related to ostream initialization, because the issue
also occurs when we invert the order of the function calls:

int main() {
 f2();
 std::cout << "--\n";
 f();
}

gives me:


hi!
0
--
hi!
hi!
0


Are you sure that this is not due to improper code generation?

[Bug c++/58063] default arguments evaluated twice per call

2013-08-03 Thread paolo.carlini at oracle dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #5 from Paolo Carlini  ---
Ah, in case isn't obvious already: it only happens when the "I/O expression"
has the ! operator in front.


[Bug c++/58063] default arguments evaluated twice per call

2013-08-03 Thread paolo.carlini at oracle dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #4 from Paolo Carlini  ---
Sorry, I didn't study it in sufficient detail. Anyway, no mysteries, this is
free software: libstdc++-v3/src/c++98/ios_init.cc etc.


[Bug c++/58063] default arguments evaluated twice per call

2013-08-03 Thread daniel.kruegler at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #3 from Daniel Krügler  ---
(In reply to Paolo Carlini from comment #2)
> I suppose a minimal reproducer could involve a file scope static of some 
> sort...

I'm a bit confused by your reply, Paolo: Isn't my_cout also a "file scope
static"? (Even, if I declare it to have static linkage, it still behaves
differently compared to std::cout)

[Bug c++/58063] default arguments evaluated twice per call

2013-08-03 Thread paolo.carlini at oracle dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

--- Comment #2 from Paolo Carlini  ---
The standard streams are indeed special, being constructed once and never
destroyed, see libstdc++-v3/src/c++98/ios_init.cc. I suppose a minimal
reproducer could involve a file scope static of some sort...


[Bug c++/58063] default arguments evaluated twice per call

2013-08-03 Thread daniel.kruegler at googlemail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58063

Daniel Krügler  changed:

   What|Removed |Added

 CC||daniel.kruegler@googlemail.
   ||com

--- Comment #1 from Daniel Krügler  ---
The behavior looks indeed odd to me (and I can confirm it for gcc 4.9 as well).
I suspect at the moment that it is somehow related to the very specific
definition of std::cout, because when I try to mimic the problem for a model
type like the following, I cannot produce this effect:

//-
#include 

struct my_ostream
{
  my_ostream(){}
  virtual ~my_ostream() {}
  operator void*() const { return const_cast(this); }
  bool operator!() const { return false; }
private:
  my_ostream(const my_ostream&);
  my_ostream& operator=(const my_ostream&);
 } my_cout;

my_ostream& operator<<(my_ostream& os, const char* s)
{
  std::cout << s;
  return os;
}

void f(bool x = !(std::cout << "hi!\n")) {
  std::cout << x << '\n';
}

void f2(bool x = !(my_cout << "hi!\n")) {
  std::cout << x << '\n';
}

int main() {
 f();
 std::cout << "--\n";
 f2();
}
//-

gives the output:


hi!
hi!
0
--
hi!
0


Looking at the generate assembly (mingw 64 but), I see the following relevant
lines:

0x004017ADlea0x7a86d(%rip),%rdx# 0x47c021

0x004017B4mov0x7e4a5(%rip),%rcx# 0x47fc60 <.refptr._ZSt4cout>
0x004017BBcallq  0x4624c0 
>(std::basic_ostream >&, char const*)>
0x004017C0mov%rax,%rbx
0x004017C3lea0x7a857(%rip),%rdx# 0x47c021

0x004017CAmov0x7e48f(%rip),%rcx# 0x47fc60 <.refptr._ZSt4cout>
0x004017D1callq  0x4624c0 
>(std::basic_ostream >&, char const*)>
0x004017D6mov(%rax),%rax
0x004017D9sub$0x18,%rax
0x004017DDmov(%rax),%rax
0x004017E0add%rbx,%rax
0x004017E3mov%rax,%rcx
0x004017E6callq  0x433f60 
>::operator!() const>
0x004017EBmovzbl %al,%eax
0x004017EEmov%eax,%ecx