Bug 42018 - Template specialization in wrong namespace accepted if it matches template arguments of an earlier specialization
Summary: Template specialization in wrong namespace accepted if it matches template ar...
Status: RESOLVED DUPLICATE of bug 56480
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.3.4
: P3 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid, patch
Depends on:
Blocks:
 
Reported: 2009-11-12 12:36 UTC by Simon Richter
Modified: 2021-09-02 02:14 UTC (History)
5 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work: 7.1.0
Known to fail: 4.1.2, 4.3.4, 4.4.3, 4.5.1, 4.6.0, 6.4.0
Last reconfirmed: 2010-10-01 11:52:43


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Richter 2009-11-12 12:36:51 UTC
The following code should fail to compile due to ambiguity (the non-template case properly fails):

template<typename>
void foo(void);

template<>
void foo<int>(void);

namespace {
  template<>
  void foo<int>(void) { return; }
}

int main(int, char **) { foo<int>(); }
Comment 1 Jonathan Wakely 2009-11-12 13:24:30 UTC
It should fail to compile because you are specializing a template which was never declared, not because it is ambiguous.

namespace {
  template<>
  void foo<int>(void) { return; }
}

That is a specialization, but there is no matching primary template.

This fails due to ambiguous overloads:

template<typename>
void foo(void);

template<>
void foo<int>(void);

namespace {
  template<class>
  void foo(void) { return; }
}

Comment 2 Jonathan Wakely 2009-11-12 13:28:19 UTC
This fails:

template<typename>
void foo(void);

template<>
void foo<int>(void);

namespace {
  template<>
  void foo<int>(void) { return; }
}

int main(int, char **) { foo<int>(); }

ttt.cc:6: error: specialization of 'template<class> void foo()' in different namespace
ttt.cc:2: error:   from definition of 'template<class> void foo()'


But if a valid specialization already exists, the one in the anon namespace is not rejected. That's a bug.
Comment 3 Jonathan Wakely 2010-10-01 11:52:43 UTC
Oops, I've just realised I pasted the wrong code in comment 2, I meant to say that this fails:

template<typename>
void foo(void);

namespace {
  template<>
  void foo<int>(void) { return; }
}

template<>
void foo<int>(void);

int main(int, char **) { foo<int>(); }

i.e. if the invalid specialization comes before the valid specialization, it's rejected.

But in the original example, where the invalid specialization comes later, it's incorrectly accepted. The same error should be given in both cases: the specialization in the anon namespace does not match any primary template declaration.
Comment 4 Jonathan Wakely 2010-10-01 12:00:51 UTC
It doesn't even depend on unnamed namespaces!

This is also accepted:

template<typename>
void foo(void);

template<>
void foo<int>(void);

namespace xxx {
  template<>
  void foo<int>(void) { return; }
}


I've adjusted the summary accordingly.
Comment 5 Jonathan Wakely 2010-10-01 21:21:03 UTC
incomplete patch posted to
http://gcc.gnu.org/ml/gcc-patches/2010-10/msg00054.html
Comment 6 Eric Gallager 2018-03-10 03:17:36 UTC
(In reply to Jonathan Wakely from comment #5)
> incomplete patch posted to
> http://gcc.gnu.org/ml/gcc-patches/2010-10/msg00054.html

adding the "patch" keyword
Comment 7 Andrew Pinski 2021-08-23 08:31:42 UTC
Fixed by r7-4488
Comment 8 Andrew Pinski 2021-08-23 08:33:28 UTC
Dup of bug 56480.

*** This bug has been marked as a duplicate of bug 56480 ***