re PR c++/28211 (wrong linkage of template argument, diagnostic could be improved)
authorMark Mitchell <mark@codesourcery.com>
Mon, 16 Oct 2006 17:02:07 +0000 (17:02 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 16 Oct 2006 17:02:07 +0000 (17:02 +0000)
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

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/template21.C [new file with mode: 0644]
gcc/testsuite/g++.dg/tc1/dr49.C

index b1df987227d222fcba5b6b5846e742c7e8814dbf..a4403a38da8bef4b30a7e87a1eabbc24260a2ebd 100644 (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
index cb357cfd59565dd689ded83d36a9fe2ef7ccc1fb..691b742fd831ae039afe09775f0733173573ae18 100644 (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))
index 3106023d89a678c4cf0b5eb81f8e086656e928af..744871f35a1466b7668bc962e8208bedc6628caf 100644 (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
 
index 519a2c40011ff24a153c49672c81a909a1a90b0e..31144a8ce6e0482472a53bae7815f9c0a56a8b17 100644 (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
diff --git a/gcc/testsuite/g++.dg/parse/template21.C b/gcc/testsuite/g++.dg/parse/template21.C
new file mode 100644 (file)
index 0000000..e1ac769
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/28211
+
+template <const int*> class Helper { };
+const int foo = 0;
+typedef Helper<&foo> HelperType; // { dg-error "linkage|type" }
index f880e2ac36ac6c164a288e4a449c8d8276ee6662..753d96b6977174804e3f2ea0caa1bf5256cfb23e 100644 (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