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