Hello, Consider this code snippet:
struct Outer { static const int value = 1 ; template< int value > struct Inner { static const int* get_value() { return &value ; } // #1 -> Error! } ; }; template class Outer::Inner<2>; The line #1 should yield an error because the name "value" should resolve to the template parameter, not the static member of the outer class. The problem seems to be that parameter_of_template_p (notably used by binding_to_template_parms_of_scope_p) fails to detect that the template parm it gets in argument is a member of the template. For each PARM_DECL representing a non-type template parameter, process_template_parm and push_inline_template_parms_recursive actually create a CONST_DECL that is added to the symbol table for that PARM_DECL. The patch below updates parameter_of_template_p to handle non-type template parameters. Tested on x86_64-unknown-linux-gnu against trunk. gcc/cp/ * pt.c (parameter_of_template_p): Handle comparison with DECLs of template parameters as created by process_template_parm. gcc/testsuite/ * g++.dg/lookup/hidden-var1.C: New test case. --- gcc/cp/pt.c | 9 +++++++-- gcc/testsuite/g++.dg/lookup/hidden-var1.C | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/hidden-var1.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9ab110a..ed4fe72 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7890,8 +7890,13 @@ parameter_of_template_p (tree parm, tree templ) parms = INNERMOST_TEMPLATE_PARMS (parms); for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) - if (parm == TREE_VALUE (TREE_VEC_ELT (parms, i))) - return true; + { + tree p = TREE_VALUE (TREE_VEC_ELT (parms, i)); + if (parm == p + || (DECL_INITIAL (parm) + && DECL_INITIAL (parm) == DECL_INITIAL (p))) + return true; + } return false; } diff --git a/gcc/testsuite/g++.dg/lookup/hidden-var1.C b/gcc/testsuite/g++.dg/lookup/hidden-var1.C new file mode 100644 index 0000000..6be32b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/hidden-var1.C @@ -0,0 +1,19 @@ +// Origin PR c++/45625 +// { dg-do compile } + +struct Outer +{ + static const int value = 1 ; + + template< int value > + struct Inner + { + static const int* + get_value() + { + return &value ;// { dg-error "lvalue required" } + } + }; +}; + +template class Outer::Inner<2>; -- Dodji