aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-10-16 17:02:07 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2006-10-16 17:02:07 +0000
commit1082fd1084c181f2dfe01b482be65f00691f895f (patch)
treeb80e749957205e5b3b97ac86578383e1f1d210c0 /gcc
parent0573fa421a606a6c76468c8bcd813e02f71283d1 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/cp/pt.c51
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/parse/template21.C5
-rw-r--r--gcc/testsuite/g++.dg/tc1/dr49.C4
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