Bug 20647 - Wrong typeid for incomplete types
Summary: Wrong typeid for incomplete types
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: 4.1.2
Assignee: Nathan Sidwell
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-03-26 15:46 UTC by Frederic Riss
Modified: 2006-10-24 09:48 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-11-06 17:54:46


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Frederic Riss 2005-03-26 15:46:39 UTC
On linux x86, using the following 2 little sources files :

---------- 1.C --------------------
#include <typeinfo>

class A {
public:
        A() {}
};

extern void foo(const std::type_info&);

int main()
{
        foo(typeid(A*));
        return 0;
}
-----------------------------------

---------- 2.C --------------------
#include <iostream>
#include <typeinfo>

class A;

void foo(const std::type_info& t)
{
        if (t == typeid(A*))
        {
                std::cout << "OK\n";
        }
        else
        {
                std::cout << "KO\n";
        }
}
-----------------------------------

and compiling with "g++ 1.C 2.C" gives me KO output. This means that the
comparison of the type_info passed to foo and the one computed by typeid(A*)
where A* is an incomplete type failed. 

In the binary there are 2 type_info symbols for A* :
 % nm a.out| grep TIP1A
0804884c r _ZTIP1A
0804882c V _ZTIP1A

I tried this test with many compilers and it worked with g++ 3.2 and failed with
g++ 3.3, 3.4 and pre4.0 (with the same binutils). Precise versions :

 % gcc-3.2 --version
gcc-3.2 (GCC) 3.2.3 (Debian)

 % gcc-3.3 --version
gcc-3.3 (GCC) 3.3.5 (Debian 1:3.3.5-8ubuntu2)

 % gcc-3.4 --version
gcc-3.4 (GCC) 3.4.4 20050209 (prerelease) (Debian 3.4.3-9ubuntu3)

 % gcc-4.0 --version
gcc-4.0 (GCC) 4.0.0 20050301 (prerelease) (Debian 4.0-0pre6ubuntu6)
Comment 1 Andrew Pinski 2005-03-26 16:59:20 UTC
Hmm, this works without weak symbols.
Comment 2 Frederic Riss 2005-04-01 21:45:18 UTC
Andrew, I don't fully get what you mean and seeing no activity on this bug makes
me wonder if you expect some feedback from me... Experimenting based on your
comment I tried using -fno-weak, but it doesn't work nor seems recommended. So I
wonder if what I see is a real bug, me misusing C++ or maybe a bug in the
packages I use.
Comment 3 Andrew Pinski 2005-04-01 21:48:47 UTC
(In reply to comment #2)
> Andrew, I don't fully get what you mean and seeing no activity on this bug makes
> me wonder if you expect some feedback from me... Experimenting based on your
> comment I tried using -fno-weak, but it doesn't work nor seems recommended. So I
> wonder if what I see is a real bug, me misusing C++ or maybe a bug in the
> packages I use.

No I mean this works on targets without weak symbol support like say openbsd or older versions of gcc 
on darwin (Mac OS X).

I don't know the C++ rules to say this is correct or not.
Comment 4 Paolo Carlini 2005-11-06 15:58:41 UTC
FWIW, is also "KO" with ICC 9.0.
Comment 5 Paolo Carlini 2005-11-06 16:19:20 UTC
Nathan, can you have a look to this PR? (Googling reveals a lot of hits for
nathan & typeid ;) Thanks in advance.
Comment 6 Frederic Riss 2005-11-06 16:33:40 UTC
I nearly forgot that I submitted this bug report... 
I got myself a version of the C++ standard since I submitted that, and I just had a look at the part describing typeid :

5.2.8.4 reads : "When typeid is applied to a <i>type-id</i>, [...]. If the type of the type-id is a class type or a reference to a class type, the class shall be completely-defined."

I believe A* in 2.C qualifies a a reference to a not-completely defined class type, and thus shouldn't be passed to std::typeid. 

I'm not an expert in standard reading, but it seems to me that the current behaviour isn't really a bug. If possible, I would be glad to see a warning emited by GCC in that case, because I hit that problem in real-world code (generic callback system using boost::any behind the scenes) and I spent hours finding out what was happening. Maybe I should suggest adding a concept check to the boost code if it is possible to detect it.
Comment 7 Paolo Carlini 2005-11-06 17:03:22 UTC
(In reply to comment #6)
> I nearly forgot that I submitted this bug report... 
> [...]

At first, I was under the same impression - not a bug - however, I'm not sure
anymore... Have also a look to the ABI:

  http://www.codesourcery.com/cxx-abi/abi.html

section 2.9.3, and then the last sentence of 2.9.5/7... In your example the NTBS
addresses (returned by type_info::name()) seem equal... ?!?
Comment 8 Paolo Carlini 2005-11-06 17:10:42 UTC
(In reply to comment #7)

> section 2.9.3, and then the last sentence of 2.9.5/7... In your example the
> NTBS addresses (returned by type_info::name()) seem equal...

Sorry, I was wrong! The names, the strings, are equal, but the *addresses* are
not! Yes, it seems invalid... 
Comment 9 Paolo Carlini 2005-11-06 17:36:00 UTC
Ok, I'm closing this, because the ABI, if not the standard, seems really
unequivocal. About the warning, I don't know, probably it's not that easy
to implement, I also looked for it, but no other compiler I have at hand
apparently is able to emit it...
Comment 10 Nathan Sidwell 2005-11-06 17:54:31 UTC
A * is not a reference to an incomplete type, but a pointer to one, so 5.2.8.4 does not apply.  I'm fairly certain the correct output should be 'OK'.  The two type id objects should have different addresses (one should be weak, one should be local static).  The typeid strings should have the same address (and be emitted weak)
Comment 11 Paolo Carlini 2005-11-06 17:57:11 UTC
Ah, ah, the addresses should be equal in the first place! Ok, thanks for looking
into this.
Comment 12 Frederic Riss 2005-11-06 18:35:11 UTC
When I read the standard, I thought that 'reference to a class type' was used in a sort of general way covering pointers and C++ references. I interpreted this that way because I don't see what difference it could make to a compiler and/or a developper that typeid(A*) is valid while typeid(A&) isn't. 
So just for my personal knowledge, what could be the rationale behind this special casing ?
Comment 13 Paolo Carlini 2006-10-17 17:03:26 UTC
Nathan, any news about this PR? Thanks.
Comment 14 Nathan Sidwell 2006-10-22 16:07:53 UTC
Subject: Bug 20647

Author: nathan
Date: Sun Oct 22 16:07:41 2006
New Revision: 117957

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117957
Log:
cp/
	PR c++/20647
	* rtti.c (tinfo_base_init): The type info string is always global.
testsuite/
	PR c++/20647
	* g++.dg/abi/rtti3.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/abi/rtti3.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/rtti.c
    trunk/gcc/testsuite/ChangeLog

Comment 15 Nathan Sidwell 2006-10-22 16:09:58 UTC
2006-10-22  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/20647
	* rtti.c (tinfo_base_init): The type info string is always global.
Comment 16 Nathan Sidwell 2006-10-23 07:42:12 UTC
Subject: Bug 20647

Author: nathan
Date: Mon Oct 23 07:42:02 2006
New Revision: 117970

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117970
Log:
cp/
	PR c++/20647
	* rtti.c (tinfo_base_init): The type info string is always global.
testsuite/
	PR c++/20647
	* g++.dg/abi/rtti3.C: New.

Added:
    branches/gcc-4_1-branch/gcc/testsuite/g++.dg/abi/rtti3.C
Modified:
    branches/gcc-4_1-branch/gcc/cp/ChangeLog
    branches/gcc-4_1-branch/gcc/cp/rtti.c
    branches/gcc-4_1-branch/gcc/testsuite/ChangeLog

Comment 17 Nathan Sidwell 2006-10-24 08:38:37 UTC
Subject: Bug 20647

Author: nathan
Date: Tue Oct 24 08:38:26 2006
New Revision: 117999

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117999
Log:
cp/
	PR c++/20647
	* rtti.c (tinfo_base_init): The type info string is always global.
testsuite/
	PR c++/20647
	* g++.dg/abi/rtti3.C: New.

Added:
    branches/gcc-4_2-branch/gcc/testsuite/g++.dg/abi/rtti3.C
Modified:
    branches/gcc-4_2-branch/gcc/cp/ChangeLog
    branches/gcc-4_2-branch/gcc/cp/rtti.c
    branches/gcc-4_2-branch/gcc/testsuite/ChangeLog

Comment 18 Nathan Sidwell 2006-10-24 08:38:58 UTC
fixed on mainline, 4.1 & 4.2
Comment 19 Richard Biener 2006-10-24 09:48:35 UTC
Adjust target milestone.