From 1082fd1084c181f2dfe01b482be65f00691f895f Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 16 Oct 2006 17:02:07 +0000 Subject: [PATCH] re PR c++/28211 (wrong linkage of template argument, diagnostic could be improved) PR c++/28211 * parser.c (cp_parser_template_argument): Don't consider "&var" a possible constant-expression. * pt.c (convert_nontype_argument): Refine handling of arguments of pointer type. PR c++/28211 * g++.dg/tc1/dr49.C: Tweak error messages. * g++.dg/parse/template21.C: New test. From-SVN: r117787 --- gcc/cp/ChangeLog | 8 ++++ gcc/cp/parser.c | 2 +- gcc/cp/pt.c | 51 +++++++++++++++++++------ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/g++.dg/parse/template21.C | 5 +++ gcc/testsuite/g++.dg/tc1/dr49.C | 4 +- 6 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/template21.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b1df987227d..a4403a38da8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2006-10-16 Mark Mitchell + + PR c++/28211 + * parser.c (cp_parser_template_argument): Don't consider "&var" a + possible constant-expression. + * pt.c (convert_nontype_argument): Refine handling of arguments of + pointer type. + 2006-10-13 Mark Mitchell PR c++/28506 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index cb357cfd595..691b742fd83 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -9285,7 +9285,7 @@ cp_parser_template_argument (cp_parser* parser) /* A variable without external linkage might still be a valid constant-expression, so no error is issued here if the external-linkage check fails. */ - if (!DECL_EXTERNAL_LINKAGE_P (argument)) + if (!address_p && !DECL_EXTERNAL_LINKAGE_P (argument)) cp_parser_simulate_error (parser); } else if (is_overloaded_fn (argument)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3106023d89a..744871f35a1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3655,10 +3655,46 @@ convert_nontype_argument (tree type, tree expr) Here, we do not care about functions, as they are invalid anyway for a parameter of type pointer-to-object. */ - bool constant_address_p = - (TREE_CODE (expr) == ADDR_EXPR - || TREE_CODE (expr_type) == ARRAY_TYPE - || (DECL_P (expr) && DECL_TEMPLATE_PARM_P (expr))); + + if (DECL_P (expr) && DECL_TEMPLATE_PARM_P (expr)) + /* Non-type template parameters are OK. */ + ; + else if (TREE_CODE (expr) != ADDR_EXPR + && TREE_CODE (expr_type) != ARRAY_TYPE) + { + if (TREE_CODE (expr) == VAR_DECL) + { + error ("%qD is not a valid template argument " + "because %qD is a variable, not the address of " + "a variable", + expr, expr); + return NULL_TREE; + } + /* Other values, like integer constants, might be valid + non-type arguments of some other type. */ + return error_mark_node; + } + else + { + tree decl; + + decl = ((TREE_CODE (expr) == ADDR_EXPR) + ? TREE_OPERAND (expr, 0) : expr); + if (TREE_CODE (decl) != VAR_DECL) + { + error ("%qE is not a valid template argument of type %qT " + "because %qE is not a variable", + expr, type, decl); + return NULL_TREE; + } + else if (!DECL_EXTERNAL_LINKAGE_P (decl)) + { + error ("%qE is not a valid template argument of type %qT " + "because %qD does not have external linkage", + expr, type, decl); + return NULL_TREE; + } + } expr = decay_conversion (expr); if (expr == error_mark_node) @@ -3667,13 +3703,6 @@ convert_nontype_argument (tree type, tree expr) expr = perform_qualification_conversions (type, expr); if (expr == error_mark_node) return error_mark_node; - - if (!constant_address_p) - { - error ("%qE is not a valid template argument for type %qT " - "because it is not a constant pointer", expr, type); - return NULL_TREE; - } } /* [temp.arg.nontype]/5, bullet 3 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 519a2c40011..31144a8ce6e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2006-10-16 Mark Mitchell + + PR c++/28211 + * g++.dg/tc1/dr49.C: Tweak error messages. + * g++.dg/parse/template21.C: New test. + 2006-10-15 John David Anglin PR middle-end/20491 diff --git a/gcc/testsuite/g++.dg/parse/template21.C b/gcc/testsuite/g++.dg/parse/template21.C new file mode 100644 index 00000000000..e1ac76916e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/template21.C @@ -0,0 +1,5 @@ +// PR c++/28211 + +template class Helper { }; +const int foo = 0; +typedef Helper<&foo> HelperType; // { dg-error "linkage|type" } diff --git a/gcc/testsuite/g++.dg/tc1/dr49.C b/gcc/testsuite/g++.dg/tc1/dr49.C index f880e2ac36a..753d96b6977 100644 --- a/gcc/testsuite/g++.dg/tc1/dr49.C +++ b/gcc/testsuite/g++.dg/tc1/dr49.C @@ -10,8 +10,8 @@ template struct R<&p>; // OK template struct S<&p>; // OK due to parameter adjustment int *ptr; -template struct R; // { dg-error "constant" } -template struct S; // { dg-error "constant" } +template struct R; // { dg-error "argument" } +template struct S; // { dg-error "argument" } int v[5]; template struct R; // OK due to implicit argument conversion -- 2.30.2