Bug 24215 - [4.0/4.1 Regression] pragma interface in included file with same name
Summary: [4.0/4.1 Regression] pragma interface in included file with same name
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: 4.0.3
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2005-10-05 15:05 UTC by Vladan Bato
Modified: 2005-10-11 06:49 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.4.0
Known to fail: 4.0.0 4.1.0
Last reconfirmed: 2005-10-05 16:27:49


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vladan Bato 2005-10-05 15:05:41 UTC
If in a .h file you include another file with the same name, but in a different directory, that contains a #pragma interface, it seems that the #pragma interface gets extended to the current file, past the end of the included file.

In the following example there are three files:
a.h   : contains the declaration of a class
a.cpp : includes a.h and contains the implementation of the class.
b/a.h : this is included in a.h. It has the same name as a.h, but is in a different directory. It contains a #pragma interface

When you compile a.cpp, it doesn't create the virtual table for the Test class.
It looks like the '#pragma interface' is extended to a.h, and since it doesn't find the corresponding '#pragma implementation' it doesn't include the virtual table for the class in the object file.

Here's the example:

=====
$ cat a.cpp
#include "a.h"

Test::Test(){}

void Test::f(){}

$ cat a.h
#include "b/a.h"

class Test
{
    public:
        Test();
        virtual void f();
};

$ cat b/a.h

#pragma interface "a.h"
===

If you compile a.cpp, the virtual table for class Test is not created in the object file:

$ g++ a.cpp
$ nm -C a.o
00000020 T Test::f()
00000010 T Test::Test()
00000000 T Test::Test()
         U vtable for Test

If you rename the file a.h to a2.h and change a.cpp accordingly, you get:
$ nm -C a.o
00000020 T Test::f()
00000010 T Test::Test()
00000000 T Test::Test()
00000000 V typeinfo for Test
00000000 V typeinfo name for Test
00000000 V vtable for Test
         U vtable for __cxxabiv1::__class_type_info

Which should be the correct behaviour.


I've seen this since 4.0. It wasn't present in 3.3.
I've tested it both with gcc 4.0.1 and with the latest 4.1 cvs snapshot:

$ g++ -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.1-20051001/configure --prefix=/home/vbato/gcc41
Thread model: posix
gcc version 4.1.0 20051001 (experimental)
Comment 1 Andrew Pinski 2005-10-05 16:27:49 UTC
Confirmed, a regression from 3.4.0.
Was introduced between "3.5.0 20040909" and "4.0.0 20041124".
Comment 2 janis187 2005-10-07 17:26:24 UTC
A regression hunt identified this large patch from Zack Weinberg and
Matt Austern:

  http://gcc.gnu.org/ml/gcc-cvs/2004-09/msg00920.html
Comment 3 Mark Mitchell 2005-10-11 06:49:28 UTC
The semantics of #pragma interface are not entirely well-specified in this case.  However, the documentation does suggest that you use an explicit subdirectory when you have multiple headers with the same name in different directories.  Indeed, using:

#pragma interface "b/a.h"

fixes the problem.

Therefore, I'm going to close this as INVALID.