[Bug c++/23885] incorrect template two-stage name-lookup
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885 Paolo Carlini paolo.carlini at oracle dot com changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |INVALID --- Comment #12 from Paolo Carlini paolo.carlini at oracle dot com --- Closing.
[Bug c++/23885] incorrect template two-stage name-lookup
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885 Paolo Carlini paolo.carlini at oracle dot com changed: What|Removed |Added Status|SUSPENDED |NEW CC|gcc-bugs at gcc dot gnu.org | Known to fail|| --- Comment #11 from Paolo Carlini paolo.carlini at oracle dot com 2012-10-12 15:16:36 UTC --- Definitely unsuspending. Is this invalid like PR16635 then?
[Bug c++/23885] incorrect template two-stage name-lookup
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885 rockeet rockeet at gmail dot com changed: What|Removed |Added CC||rockeet at gmail dot com --- Comment #9 from rockeet rockeet at gmail dot com 2011-12-13 09:35:29 UTC --- / Code Begin #include stdio.h class A {}; void f(A) { printf(%s\n, __PRETTY_FUNCTION__); } class B {}; templateclass T void f(T) { printf(%s\n, __PRETTY_FUNCTION__); } // now g(T) knew A,B,int,... // phase 1 lookup just success for f(A) templateclass T void g(T x) { f(x); } // after definition of g(T) and class B void f(B) { printf(%s\n, __PRETTY_FUNCTION__); } void f(int x) { printf(%s\n, __PRETTY_FUNCTION__); } void f(int*x) { printf(%s\n, __PRETTY_FUNCTION__); } int main(int argc, char** argv) { g(A()); // should always(phase 1 and phase 2) be OK g(B()); // f(B) definition is after g(T) definition, phase 1 just got f(A) and f(T) g(B()); // but phase 2 got f(B) g(100); // intend to let g calling f(int), but got f(T) in g++ 4.1.2 and 4.6.0, 4.7.0, others not tested g(argc); // intention: similar as g(100) return 0; } / Code End The output of above code shown that associated sets of namespaces and classes of fundamental types are both empty is really true! But pre g++ 3.4.6 and clang treat fundamental types as same as user defined types. Begin Compile With g++ 4.6.0 $g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/opt/libexec/gcc/x86_64-unknown-linux-gnu/4.6.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ../gcc-4.6.0-src/configure --prefix=/opt --with-gmp=/opt --with-mpfr=/opt --with-mpc=/opt --with-ppl=/opt --with-cloog=/opt --with-local-prefix=/opt --enable-languages=c,c++ Thread model: posix gcc version 4.6.0 (GCC) $ g++ twophaselookup2.cpp $ ./a.out End Compile With g++ 4.6.0 Begin Compile With g++ 3.4.6 void f(A) void f(B) void f(B) void f(int) void f(int*) Begin Compile With g++ 3.4.6 apple clang produced the same result as g++ 3.4.6
[Bug c++/23885] incorrect template two-stage name-lookup
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885 --- Comment #10 from rockeet rockeet at gmail dot com 2011-12-13 09:38:45 UTC --- Sorry, missed output of g++ 4.6.0: Begin Output void f(A) void f(B) void f(B) void f(T) [with T = int] void f(T) [with T = int*] End Output
[Bug c++/23885] incorrect template two-stage name-lookup
--- Comment #8 from jason at gcc dot gnu dot org 2010-01-06 19:41 --- Suspending along with 16635. -- jason at gcc dot gnu dot org changed: What|Removed |Added Status|NEW |SUSPENDED http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885
[Bug c++/23885] incorrect template two-stage name-lookup
--- Comment #7 from andrew dot stubbs at st dot com 2007-05-31 09:49 --- See here: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#197 It would appear that only koenig lookup is done for functions defined after the template declaration. As the Intel statement says, koenig lookup does not apply to fundamental types. Koenig lookup is described in clause 3.4.2 Argument dependent name lookup. It is clause 14.6.4 Dependent name resolution that limits the lookup to Koenig only. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885
[Bug c++/23885] incorrect template two-stage name-lookup
--- Comment #5 from fang at csl dot cornell dot edu 2007-05-30 18:00 --- test case fails with 4.2.0 (release) test case works with 3.3.3 (x86 SuSE linux) test case fails with 3.3 (powerpc Apple's blds. 1760/1819) Yet 3.3.3 is currently listed under known to fail. The mixed results on 3.3 are still a little baffling... still not sure if this is a regression. blocks meta-bug 12944 (name-lookup issues), maybe 29843 (conformance)? -- fang at csl dot cornell dot edu changed: What|Removed |Added CC||fang at csl dot cornell dot ||edu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885
[Bug c++/23885] incorrect template two-stage name-lookup
--- Comment #6 from martin dot audet at imi dot cnrc-nrc dot gc dot ca 2007-05-30 21:02 --- I'm the original submiter of this bug and I'am not sure now if it's a bug in g++ template instantiation mechanism (e.g. problem with the two phase name lookup) or if the code example itself is standard compliant. We need a couple of C++ experts to look at this problem carefully to decide if the two phases template name binding process is incorrect as I reported or if the code sample is incorrect (if that's the case maybe g++ needs to emit a warning at least) or if g++ current behavior is correct. I'm now expressing doubts since I submited a similar issue with Intel C/C++ compiler using the following code sample (similar but slightly longer): #include iostream // f in gT(T) should bind to this function even if f // is overloaded later with a more natural version. void f(double) { std::cout Function f(double) std::endl; } templateclass T void g(T a) { f(123); // f is not a dependent name. Binding occurs at definition (e.g. here). h(a);// h is a dependent name. Binding will occurs at instantiation point. } // f in gT(T) should not bind to this function even if it is more natural. void f(int){ std::cout Function f(int) std::endl; } // h in gint() should be bound to this function even // if h is overloded later with a more natural version. void h(double) { std::cout Function h(double) std::endl; } // Instantiation point for gint(). void i(void) { extern void h(int);// Should not influence the choice of the h function. // because it is out of scope at instantiation point. // Note: the problem with h instantiation occur even // if this declaration is commented out. g(234);// gint(234) is called. } // h in gint() should be not be bound to this version of // h function even if it is more natural. This is because // its declaration occurs after instatiation point. void h(int) { std::cout Function h(int) std::endl; } int main(void) { // Should print: // Function f(double). // Function h(double). i(); return 0; } This code was taken from an example in a IBM Developer Works article where the author explained that the two phases template name binding process (the comments are added by me). The article stated that the correct result was to print: Function f(double) Function h(double) I remember at that time trying it on one AIX machine witch xlC C++ compiler and it effectively printed that result. I also tried it on a few other compilers/systems and I remember having the four possible outcomes (f(double)/f(int), h(double)/h(int)). Recent g++ and icpc (Intel C++ compiler v9.1) versions now prints: Function f(double) Function h(int) Since I was convinced that this was a bad result I submited this bug report for g++ and a bug report for Intel compiler. The answer I finally got from Intel compiler team (before closing the case) suggest that this code sample isn't standard compliant and therefore there wasn't a template instantiation problem. Here is the answer I got: Intel answer BEGIN Hi Martin, The development team has had another look at this and have determined that the test case is not standard conforming. The compiler is right to issue the error. There are two rules for the Dependent name resolution in C++ strandard. 14.6.4 Dependent name resolution [temp.dep.res] 1 In resolving dependent names, names from the following sources are considered: - Declarations that are visible at the point of definition of the template. - Declarations from namespaces associated with the types of the function arguments both from the instantiation context (14.6.4.1) and from the definition context. The first rule, said we need to have a declaration of h before definition of the template. But in this test case we don't have. For the second rule, the namespaces for type int is empty according 3.4.2 as following. So this test case does not match this rule too. The test case is not standard conforming. The compiler is right on it. 3.4.2. For each argument type T in the function call, there is a set of zero or more associated namespaces and a set of zero or more associated classes to be considered. The sets of namespaces and classes is determined entirely by the types of the function arguments (and the namespace of any template template argument). Typedef names and usingdeclarations used to specify the types do not contribute to this set. The sets of namespaces and classes are determined in the following way: - If T is a fundamental type, its associated sets of namespaces and classes are both empty. Thank you. -- Intel answer END So with this answer I don't know what to think, is the sample program standard compliant ? Is there a warning missing ? Is the current name binding process for template standard compliant
[Bug c++/23885] incorrect template two-stage name-lookup
--- Comment #4 from pinskia at gcc dot gnu dot org 2006-01-29 02:02 --- Confirmed, your 3.3.2 is redhat's and I don't trust it enough to consider this a regression. -- pinskia at gcc dot gnu dot org changed: What|Removed |Added Status|UNCONFIRMED |NEW Ever Confirmed|0 |1 Known to work|3.3.2 | Last reconfirmed|-00-00 00:00:00 |2006-01-29 02:02:33 date|| http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885
[Bug c++/23885] incorrect template two-stage name-lookup
-- What|Removed |Added CC||redi at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885
[Bug c++/23885] incorrect template two-stage name-lookup
-- What|Removed |Added GCC target triplet|i386-redhat-linux and | |x86_64-redhat-linux | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885
[Bug c++/23885] incorrect template two-stage name-lookup
--- Additional Comments From pinskia at gcc dot gnu dot org 2005-09-14 19:03 --- I think this is a dup of bug 16635. -- What|Removed |Added BugsThisDependsOn||16635 Keywords||wrong-code http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885
[Bug c++/23885] incorrect template two-stage name-lookup
--- Additional Comments From martin dot audet at imi dot cnrc-nrc dot gc dot ca 2005-09-14 20:36 --- Hi again, I agree with you, this bug and 16635 seems to be related to the same cause (which is I guess the two-stage name-lookup for templates). I also ran the three code examples provided in 16635 on a few machine here and I observed the same work/fail pattern: it works on 3.3.2 and fails on every other versions I tested. Martin -- What|Removed |Added Known to fail||4.0.1 4.0.0 3.4.3 3.4.2 ||3.2.3 2.96 Known to work||3.3.2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885
[Bug c++/23885] incorrect template two-stage name-lookup
--- Additional Comments From pinskia at gcc dot gnu dot org 2005-09-14 20:41 --- It fails on 3.3.3 also. -- What|Removed |Added Known to fail|4.0.1 4.0.0 3.4.3 3.4.2 |4.0.1 4.0.0 3.4.3 3.4.2 |3.2.3 2.96 |3.2.3 2.96 3.3.3 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23885