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
This commit is contained in:
Mark Mitchell 2006-10-16 17:02:07 +00:00 committed by Mark Mitchell
parent 0573fa421a
commit 1082fd1084
6 changed files with 62 additions and 14 deletions

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
// PR c++/28211
template <const int*> class Helper { };
const int foo = 0;
typedef Helper<&foo> HelperType; // { dg-error "linkage|type" }

View File

@ -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