Bug 34824 - [4.1/4.2 Regression] ICE with explicit copy constructor
Summary: [4.1/4.2 Regression] ICE with explicit copy constructor
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.1.2
: P2 normal
Target Milestone: 4.3.0
Assignee: Jason Merrill
URL:
Keywords: diagnostic, ice-on-invalid-code
: 28475 (view as bug list)
Depends on:
Blocks:
 
Reported: 2008-01-17 05:38 UTC by Kristian Spangsege
Modified: 2008-02-21 21:07 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 2.95.4 4.3.0
Known to fail: 3.3.6 4.1.3
Last reconfirmed: 2008-02-13 03:56:26


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kristian Spangsege 2008-01-17 05:38:44 UTC
The following small test case causes GCC to ICE:

struct A;

struct B
{
  B(A const &);
  explicit B(B const &);
};

struct A
{
  A(B) {}
};

B f(A const &a) { return B(a); }


Same result (ICE) on the following two systems:

gcc (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
gcc (GCC) 4.1.1 20070105 (Red Hat 4.1.1-51)


If the "explicit" keyword is dropped the ICE disappears. The same is true if the argument to A's constructor is changed to an reference.
Comment 1 Kristian Spangsege 2008-01-17 07:37:15 UTC
Just tested it on the latest release 4.2.2 build from source with no patches and the ICE is still there.

System:
g++ (GCC) 4.2.2
Linux localhost.localdomain 2.6.20-1.2952.fc6 #1 SMP Wed May 16 18:59:18 EDT 2007 i686 i686 i386 GNU/Linux
Fedora Core release 6 (Zod)
Comment 2 Richard Biener 2008-01-17 12:26:53 UTC
Confirmed.  Even if it doesn't look like it makes sense to have an explicit
copy constructor, the standard does not seem to prohibit this.

But,

B f(A const &a) { return B(a); }

invokes the copy constructor for B, and thus would raise an error.

A diagnostic is missing.

Interestingly EDG ICEs as well ;)

/icpc -strict_ansi -S t.C
icpc: error: Fatal error in /suse/rguenther/bin/opt/intel/cce/9.1.039/bin/mcpcom, terminated by segmentation violation
compilation aborted for t.C (code 1)

2.95 wrongly accepts this code, but doesn't ICE.  So not a regression
IMHO.
Comment 3 Andrew Pinski 2008-01-20 05:38:13 UTC
(In reply to comment #2)
> 2.95 wrongly accepts this code, but doesn't ICE.  So not a regression
> IMHO.

No it is a regression as anything (besides another ICE) to ICE is considered a regression.    I remember we put these rules somewhere.
Comment 4 Jakub Jelinek 2008-01-21 20:29:31 UTC
Related testcase:
struct A;

struct B
{
  B (A const &);
  B (B &);
};

struct A
{
  A (B) {}
};

B
f (A const &a)
{
  return B (a);
}

which doesn't have explicit at all segfaults as well, also endless recursion.
In both cases the copy constructor can't be used,
so a conversion through A(B) constructor and then B(const A&) is attempted.
But that needs a temporary, so a B(const B &) copy constructor is needed and
we are back to the original problem.

If A's constructor is instead A (const B &) {}, then it compiles just fine
in both variants ( explicit B (const B &); and B (B &); ).  So I guess we just
need to detect recursion here.  I believe C++ will try only one hop through some
other class' constructor, so perhaps just remembering one parent type would
be enough to prevent the recursion.
Comment 5 Paolo Carlini 2008-01-21 23:23:45 UTC
Related to PR28475, then?
Comment 6 Jakub Jelinek 2008-01-22 13:49:35 UTC
Yes, probably even a dup of that.  I don't have 2.95 to verify this is a regression.
Comment 7 Jakub Jelinek 2008-01-23 20:26:49 UTC
*** Bug 28475 has been marked as a duplicate of this bug. ***
Comment 8 David Fang 2008-01-23 22:48:27 UTC
As long as we're digging back...
the test case in Comment #4

also ICEs:
gcc version 3.2 20020903 (Red Hat Linux 8.0 3.2-7)

also "works":
gcc version 2.95.3 [FreeBSD] 20010315 (release)
Comment 9 Jason Merrill 2008-02-13 04:06:47 UTC
Subject: Bug 34824

Author: jason
Date: Wed Feb 13 04:06:03 2008
New Revision: 132282

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132282
Log:
        PR c++/34824
        * call.c (convert_like_real): Pass LOOKUP_ONLYCONVERTING to build_temp
        if we're doing conversions to call a user-defined conversion function.

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

Comment 10 Jason Merrill 2008-02-13 05:00:02 UTC
Fixed for 4.3.0.  Bugs on invalid code don't seem worth backporting.
Comment 11 Volker Reichelt 2008-02-21 21:07:56 UTC
Adjust target milestone.