This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 28211
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 16 Oct 2006 10:16:57 -0700
- Subject: C++ PATCH: PR 28211
- Reply-to: mark at codesourcery dot com
This patch fixes a diagnostic regression. For:
S<&v>
if v did not have external linkage, we gave a relatively cryptic error
message:
testcase.cc:4: error: missing '>' to terminate the template argument list
testcase.cc:4: error: template argument 1 is invalid
For "v" alone, if "v" does not have external linkage we cannot give an
error message, as "v" might be a constant-expression (e.g., "const int
v = 7"). But, "&v" is never a constant-expression, so we can accept
it as a valid non-type argument in the parser, and then issue an error
later, during semantic processing.
Tested on x86_64-unknown-linux-gnu, applied on the mainline. I don't
think there's enough bang-for-risk to backport this to older branches.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
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-16 Mark Mitchell <mark@codesourcery.com>
PR c++/28211
* g++.dg/tc1/dr49.C: Tweak error messages.
* g++.dg/parse/template21.C: New test.
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c (revision 117657)
+++ gcc/cp/pt.c (working copy)
@@ -3655,10 +3655,46 @@ convert_nontype_argument (tree type, tre
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, tre
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
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c (revision 117687)
+++ gcc/cp/parser.c (working copy)
@@ -9285,7 +9285,7 @@ cp_parser_template_argument (cp_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))
Index: gcc/testsuite/g++.dg/tc1/dr49.C
===================================================================
--- gcc/testsuite/g++.dg/tc1/dr49.C (revision 117657)
+++ gcc/testsuite/g++.dg/tc1/dr49.C (working copy)
@@ -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
Index: gcc/testsuite/g++.dg/parse/template21.C
===================================================================
--- gcc/testsuite/g++.dg/parse/template21.C (revision 0)
+++ gcc/testsuite/g++.dg/parse/template21.C (revision 0)
@@ -0,0 +1,5 @@
+// PR c++/28211
+
+template <const int*> class Helper { };
+const int foo = 0;
+typedef Helper<&foo> HelperType; // { dg-error "linkage|type" }