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:
parent
0573fa421a
commit
1082fd1084
6 changed files with 62 additions and 14 deletions
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
51
gcc/cp/pt.c
51
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
5
gcc/testsuite/g++.dg/parse/template21.C
Normal file
5
gcc/testsuite/g++.dg/parse/template21.C
Normal 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" }
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue