diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-10-16 17:02:07 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2006-10-16 17:02:07 +0000 |
commit | 1082fd1084c181f2dfe01b482be65f00691f895f (patch) | |
tree | b80e749957205e5b3b97ac86578383e1f1d210c0 /gcc | |
parent | 0573fa421a606a6c76468c8bcd813e02f71283d1 (diff) | |
download | gcc-1082fd1084c181f2dfe01b482be65f00691f895f.zip gcc-1082fd1084c181f2dfe01b482be65f00691f895f.tar.gz gcc-1082fd1084c181f2dfe01b482be65f00691f895f.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/parser.c | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 51 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/template21.C | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tc1/dr49.C | 4 |
6 files changed, 62 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b1df987..a4403a3 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 cb357cf..691b742 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 3106023..744871f 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 519a2c4..31144a8 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 0000000..e1ac769 --- /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 f880e2a..753d96b 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 |