diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b1df987227d222fcba5b6b5846e742c7e8814dbf..a4403a38da8bef4b30a7e87a1eabbc24260a2ebd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2006-10-16 Mark Mitchell <mark@codesourcery.com> + + 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 <mark@codesourcery.com> PR c++/28506 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index cb357cfd59565dd689ded83d36a9fe2ef7ccc1fb..691b742fd831ae039afe09775f0733173573ae18 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 3106023d89a678c4cf0b5eb81f8e086656e928af..744871f35a1466b7668bc962e8208bedc6628caf 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 519a2c40011ff24a153c49672c81a909a1a90b0e..31144a8ce6e0482472a53bae7815f9c0a56a8b17 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2006-10-16 Mark Mitchell <mark@codesourcery.com> + + PR c++/28211 + * g++.dg/tc1/dr49.C: Tweak error messages. + * g++.dg/parse/template21.C: New test. + 2006-10-15 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 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 0000000000000000000000000000000000000000..e1ac76916e7bbf013a01efcd65b8dce544d82b4e --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/template21.C @@ -0,0 +1,5 @@ +// PR c++/28211 + +template <const int*> 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 f880e2ac36ac6c164a288e4a449c8d8276ee6662..753d96b6977174804e3f2ea0caa1bf5256cfb23e 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<ptr>; // { dg-error "constant" } -template struct S<ptr>; // { dg-error "constant" } +template struct R<ptr>; // { dg-error "argument" } +template struct S<ptr>; // { dg-error "argument" } int v[5]; template struct R<v>; // OK due to implicit argument conversion