Bug 24657 - [3.4/4.0/4.1 Regression] bizarre diagnostic when a member variable and a template parameter have the same name
Summary: [3.4/4.0/4.1 Regression] bizarre diagnostic when a member variable and a temp...
Status: RESOLVED DUPLICATE of bug 13967
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.0
: P3 normal
Target Milestone: 4.0.3
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2005-11-03 15:34 UTC by Ivan Godard
Modified: 2005-11-08 05:23 UTC (History)
6 users (show)

See Also:
Known to work: 3.3.3
Known to fail: 2.95.3 3.0.4 3.4.0 4.0.0 4.1.0 3.2.3
Last reconfirmed: 2005-11-08 05:14:36

compiler output (1.21 KB, application/octet-stream)
2005-11-03 15:36 UTC, Ivan Godard
source code (compressed) (122.55 KB, application/x-gzip)
2005-11-03 15:36 UTC, Ivan Godard

Note You need to log in before you can comment on or make changes to this bug.
Description Ivan Godard 2005-11-03 15:34:11 UTC
The first error reported in the attached is:

/home/ivan/ootbc/common/include/bitRow.hh:752: error: argument of type `size_t (
bitRow<bool, 1u,  bigEndian>::)(bitReference<bool, 1u,  bigEndian>) const' does
not match `size_t'

Subsequent diagnostics are an ignorable cascade. The constructor is declared as:

    template<size_t count>
                bitRow(bitArray<count, T, bitWidth, ordering>& a)
                    : start(&a[0]), length(count) {}

and the invocation is:

    bitArray<256, T, bitWidth, ordering>
    bitRow_t    bd(data);

which appears innocuous. The type reported in the diagnostic seems completely
bogus to me, and I think that the code is valid in its context :-)
Comment 1 Ivan Godard 2005-11-03 15:36:02 UTC
Created attachment 10127 [details]
compiler output
Comment 2 Ivan Godard 2005-11-03 15:36:27 UTC
Created attachment 10128 [details]
source code (compressed)
Comment 3 Ivan Godard 2005-11-03 16:43:01 UTC
Here's a reduced case:

template<int x> struct B {};

struct A {
    template<int i>
        A(const B<i>& b) : j(i) {}
    void    i() {}
int     j;

int main() {
    B<5> b;
    A a(b);

which gets you:

~/ootbc/members/src$ g++ foo.cc
foo.cc: In constructor `A::A(const B<i>&) [with int i = 5]':
foo.cc:12:   instantiated from here
foo.cc:5: error: argument of type `void (A::)()' does not match `int'

The compiler is picking up the member function "i" as the initializer for "j", rather than the template argument "i". (In the original the template argument "count" similarly matched a member function name). Yet it has the right "i" in the constructor's argument type "B<i>", or there would have been an earlier error.

FWIW, Comeau accepts this code.


Comment 4 Andrew Pinski 2005-11-03 17:04:11 UTC
I tested a few different versions of gcc and added the results to known to work/fail.  3.3.3 accepted this code.  before in 3.2.3 (and below), the error message was :
t.cc:6: declaration of `void A::i()'
t.cc:4: changes meaning of `i' from `int i'

I don't know if this is valid or not, the issue is a namelookup issue.
Comment 5 Wolfgang Bangerth 2005-11-08 05:14:36 UTC
This can of course be made even simpler:
struct A {
    template<int i> A(int (*)[i]) : j(i) {}
    int * i;
    int   j;

int i[3];
A a(&i);

g/x> /home/bangerth/bin/gcc-3.4.5-pre/bin/c++ -c x.cc
x.cc: In constructor `A::A(int (*)[i]) [with int i = 3]':
x.cc:8:   instantiated from here
x.cc:2: error: invalid conversion from `int*' to `int'

I'm pretty sure I've seen this somewhere before -- the question was indeed
which name should be looked up, the template name or the name of a member

In any case, the error message is not particularly helpful, and I know of
at least one other compiler that accepts this.

Comment 6 Wolfgang Bangerth 2005-11-08 05:23:47 UTC
This is PR 13967. See in particular comment #11 in the audit trail there.

Not that that PR would be particularly enlightening, but the situation is
at least discussed at length there.


*** This bug has been marked as a duplicate of 13967 ***
Comment 7 Gabriel Dos Reis 2005-11-16 19:14:58 UTC
Subject: Re:  [3.4/4.0/4.1 Regression] bizarre diagnostic on valid (?) constructor

"bangerth at dealii dot org" <gcc-bugzilla@gcc.gnu.org> writes:

| I'm pretty sure I've seen this somewhere before -- the question was indeed
| which name should be looked up, the template name or the name of a member
| variable.

Indeed this is an issue.  Discussion in on the -core reached the
consensus that we could change the lookup rules for member templates
so that template parameters for *member* templates  would be searched,
before members of the enclosing class. But I don't recall the issue
has attained an advanced state yet.  Note that in the older "issue",
there actually are TWO separate issues.

-- Gaby