Bug 29131 - [DR 225] Bad name lookup for templates due to fundamental types namespace for ADL.
Summary: [DR 225] Bad name lookup for templates due to fundamental types namespace for...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.1.1
: P3 normal
Target Milestone: 4.7.0
Assignee: Jason Merrill
URL:
Keywords:
: 31816 34886 36883 41995 42281 43261 43506 45132 46075 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-09-18 16:39 UTC by Andrew Stubbs
Modified: 2014-11-18 07:47 UTC (History)
17 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-09-19 04:06:38


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Stubbs 2006-09-18 16:39:13 UTC
The following C++ code should not compile:

template<class T>
int t(T i)
{
  return f (i);  // error: f not visible here
}

int
f (int i)
{
  return i;
}

int
main()
{
  return t(1);
}

The C++ standard clause 14.6.3 states that names should be looked up from the
point they are used. I.e. functions defined after that point are not visible.
This is true for regular functions, but GCC does not get this right for
template functions.
Comment 1 Andrew Pinski 2006-09-18 17:28:21 UTC
(In reply to comment #0)
> The C++ standard clause 14.6.3 states that names should be looked up from the
> point they are used. I.e. functions defined after that point are not visible.
> This is true for regular functions, but GCC does not get this right for
> template functions.

No you missed something but I don't have the standard in front of me.
14.6.3 is talking about something different.  Anyways this is unqualified function call that is dependent on a template arguments.

I think 14.6.3 is really talking about what PR 2922 is about and not this one.
Comment 2 Andrew Pinski 2006-09-19 03:47:40 UTC
Actually wait, what is happening here is ADL is happening for fundemantal types which is a question of a Defect report, I forgot which one now.
Comment 3 Andrew Pinski 2006-09-19 03:49:04 UTC
Actually you missed 14.6.4.2.  This really has nothing to do with 14.6.3.
Comment 4 Andrew Pinski 2006-09-19 03:51:19 UTC
Also "f (i)" is a dependent expression because of 14.6.2/1 as i is (obviously) dependent so 14.6.3 does not apply.
Comment 5 Andrew Pinski 2006-09-19 04:06:37 UTC
So GCC does not implement 14.6.4.2/1, part 1:
- For the part of look using unqualified name lookup (3.4.1), only function declareations with external linkage from the template context are found.

And since ADL on fundalment types not exist, that is the only part that happens so this is invalid code based on that and nothing else.

Next time becareful when trying to figuring out why something is invalid code because it is easy to get it wrong and then have a someone else having to look at the standard to prove you wrong.  In fact the following is valid code because of ADL (since template instantiation conext is also included for ADL):
template<class T>
int t(T i)
{
  return f (i);  // error: f not visible here
}

struct a{};

int
f (a i)
{
  return 0;
}

int
main()
{
  a b;
  return t(b);
}

Comment 6 Andrew Pinski 2006-09-19 04:30:13 UTC
This is DR 225 really.
http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#225
Which means there is a question if this is really invalid code after all.
Comment 7 Andrew Pinski 2009-12-05 00:13:33 UTC
*** Bug 42281 has been marked as a duplicate of this bug. ***
Comment 8 Andrew Pinski 2009-12-08 22:02:59 UTC
*** Bug 34886 has been marked as a duplicate of this bug. ***
Comment 9 Paolo Carlini 2010-02-05 12:52:00 UTC
*** Bug 31816 has been marked as a duplicate of this bug. ***
Comment 10 Andrew Pinski 2010-03-04 20:28:24 UTC
*** Bug 43261 has been marked as a duplicate of this bug. ***
Comment 11 Andrew Pinski 2010-03-24 16:45:22 UTC
*** Bug 43506 has been marked as a duplicate of this bug. ***
Comment 12 Andrew Pinski 2010-03-29 20:53:40 UTC
*** Bug 43506 has been marked as a duplicate of this bug. ***
Comment 13 Andrew Pinski 2010-07-29 15:19:47 UTC
*** Bug 45132 has been marked as a duplicate of this bug. ***
Comment 14 Andrew Pinski 2010-10-18 20:27:20 UTC
*** Bug 46075 has been marked as a duplicate of this bug. ***
Comment 15 Jonathan Wakely 2011-05-05 00:58:04 UTC
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#225 is now NAD
(I think that should un-suspend several PRs)
Comment 16 Jason Merrill 2011-05-20 15:56:21 UTC
*** Bug 36883 has been marked as a duplicate of this bug. ***
Comment 17 Jason Merrill 2011-05-20 18:01:27 UTC
Author: jason
Date: Fri May 20 18:01:22 2011
New Revision: 173965

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=173965
Log:
	PR c++/24163
	PR c++/29131
gcc/cp/
	* pt.c (tsubst_copy_and_build) [CALL_EXPR]: Avoid repeating
	unqualified lookup.
	* semantics.c (perform_koenig_lookup): Add complain parm.
	* cp-tree.h: Adjust.
	* parser.c (cp_parser_postfix_expression): Adjust.
	(cp_parser_perform_range_for_lookup): Adjust.
libstdc++-v3/
	* include/ext/pb_ds/assoc_container.hpp: Explicitly qualify calls to
	functions from dependent bases.
	* include/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp: Likewise.
	* include/ext/pb_ds/detail/rb_tree_map_/
	split_join_fn_imps.hpp: Likewise.
	* include/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp: Likewise.
	* include/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp: Likewise.
	* include/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp: Likewise.
	* include/ext/pb_ds/detail/splay_tree_/
	split_join_fn_imps.hpp: Likewise.
	* include/ext/pb_ds/detail/tree_policy/
	order_statistics_imp.hpp: Likewise.
	* include/ext/pb_ds/detail/trie_policy/
	prefix_search_node_update_imp.hpp: Likewise.
	* include/ext/rc_string_base.h: Likewise.
	* include/ext/rope: Likewise.
	* include/ext/ropeimpl.h: Likewise.
	* testsuite/util/exception/safety.h: Likewise.
	* testsuite/util/native_type/native_priority_queue.hpp: Likewise.
	* testsuite/util/testsuite_io.h: Likewise.
	* include/std/functional: Declare mem_fn earlier.
	* include/tr1/functional: Likewise.
	* include/tr1/exp_integral.tcc: Declare __expint_E1 earlier.

Added:
    trunk/gcc/testsuite/g++.dg/template/koenig9.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/parser.c
    trunk/gcc/cp/pt.c
    trunk/gcc/cp/semantics.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/opt/pr47615.C
    trunk/gcc/testsuite/g++.dg/overload/defarg1.C
    trunk/gcc/testsuite/g++.dg/tc1/dr213.C
    trunk/gcc/testsuite/g++.dg/torture/pr34850.C
    trunk/gcc/testsuite/g++.dg/torture/pr39362.C
    trunk/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C
    trunk/gcc/testsuite/g++.old-deja/g++.pt/memtemp47.C
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/ext/pb_ds/assoc_container.hpp
    trunk/libstdc++-v3/include/ext/pb_ds/detail/rb_tree_map_/erase_fn_imps.hpp
    trunk/libstdc++-v3/include/ext/pb_ds/detail/rb_tree_map_/split_join_fn_imps.hpp
    trunk/libstdc++-v3/include/ext/pb_ds/detail/splay_tree_/erase_fn_imps.hpp
    trunk/libstdc++-v3/include/ext/pb_ds/detail/splay_tree_/insert_fn_imps.hpp
    trunk/libstdc++-v3/include/ext/pb_ds/detail/splay_tree_/splay_fn_imps.hpp
    trunk/libstdc++-v3/include/ext/pb_ds/detail/splay_tree_/split_join_fn_imps.hpp
    trunk/libstdc++-v3/include/ext/pb_ds/detail/tree_policy/order_statistics_imp.hpp
    trunk/libstdc++-v3/include/ext/pb_ds/detail/trie_policy/prefix_search_node_update_imp.hpp
    trunk/libstdc++-v3/include/ext/rc_string_base.h
    trunk/libstdc++-v3/include/ext/rope
    trunk/libstdc++-v3/include/ext/ropeimpl.h
    trunk/libstdc++-v3/include/std/functional
    trunk/libstdc++-v3/include/tr1/exp_integral.tcc
    trunk/libstdc++-v3/include/tr1/functional
    trunk/libstdc++-v3/testsuite/util/exception/safety.h
    trunk/libstdc++-v3/testsuite/util/native_type/native_priority_queue.hpp
    trunk/libstdc++-v3/testsuite/util/testsuite_io.h
Comment 18 Jason Merrill 2011-05-20 18:56:23 UTC
Fixed for 4.7.
Comment 19 Jason Merrill 2011-09-26 17:07:22 UTC
*** Bug 41995 has been marked as a duplicate of this bug. ***
Comment 20 Nikos Platis 2012-04-25 17:33:24 UTC
I am having a problem using code similar to the one in comment #5, but using glm::vec3, from the glm library (http://glm.g-truc.net/), as the type used to instanciate the template.

Then I get an error message that "‘f’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation"

glm::vec3 does not seem like a fundamental type.


#include "glm/glm.hpp"

template<class T>
int t(T i)
{
  return f (i);
}

int
f (glm::vec3 i)
{
  return 0;
}

int
main()
{
  glm::vec3 b;
  return t(b);
}
Comment 21 Jason Merrill 2012-04-26 14:09:14 UTC
(In reply to comment #20)
> glm::vec3 does not seem like a fundamental type.

It isn't, but its associated namespace is glm, and your f isn't in glm.
Comment 22 Nikos Platis 2012-04-26 14:33:45 UTC
I am sorry if my knowledge on this issue is limited, but if I put t() and f() in namespace glm (re. the code in comment #20), should this compile? (That is what you comment #19 implies). Actually it does not.
Comment 23 Jason Merrill 2012-04-26 15:51:35 UTC
(In reply to comment #22)
> I am sorry if my knowledge on this issue is limited, but if I put t() and f()
> in namespace glm (re. the code in comment #20), should this compile? (That is
> what you comment #19 implies). Actually it does not.

That's surprising, but I would need a self-contained testcase to comment further.
Comment 24 Marc Glisse 2012-04-26 19:14:45 UTC
(In reply to comment #22)
> I am sorry if my knowledge on this issue is limited, but if I put t() and f()
> in namespace glm (re. the code in comment #20), should this compile? (That is
> what you comment #19 implies). Actually it does not.

So you are talking about this? Notice how vec3 isn't actually in glm. Interactions between namespaces and name lookup can be difficult.

namespace glm {
  namespace detail {
    struct vec3{};
  }
  using detail::vec3;
}

template<class T>
int t(T i)
{
  return f (i);
}

namespace glm {
  int
    f (glm::vec3 i)
    {
      return 0;
    }
}

int main()
{
  glm::vec3 b;
  return t(b);
}
Comment 25 Nikos Platis 2012-04-26 21:02:36 UTC
The situation in the actual glm is more like the following. We also put t() and f() in namespace glm as well, se we get the following code, which produces the error:

namespace glm {
  namespace detail {
    struct dvec3{};
  }
  typedef detail::dvec3 vec3;
}

namespace glm {
    template<class T>
    int t(T i)
    {
    return f (i);
    }

    int f (glm::vec3 i)
    {
      return 0;
    }
}

int main()
{
  glm::vec3 b;
  return glm::t(b);
}