This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix ICE on variable template access without template args (PR c++/89512)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 13 Mar 2019 23:37:31 +0100
- Subject: [C++ PATCH] Fix ICE on variable template access without template args (PR c++/89512)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
When a variable template (both static data member of some class or at
namespace level) is accessed without template arguments,
finish_id_expression_1 handles it through:
/* If we didn't find anything, or what we found was a type,
then this wasn't really an id-expression. */
if (TREE_CODE (decl) == TEMPLATE_DECL
&& !DECL_FUNCTION_TEMPLATE_P (decl))
{
*error_msg = G_("missing template arguments");
return error_mark_node;
}
On the following invalid testcase the access is from within a template and
in that case finish_id_expression{,_1} isn't really called for that, instead
tsubst_qualified_id just calls finish_qualified_id_expr.
The ICE is because we pass over a TEMPLATE_DECL to the middle-end (e.g. on
rhs of an INIT_EXPR etc.).
The following patch does something similar to what finish_id_expression_1
does. Bootstrapped/regtested on x86_64-linux and i686-linux. Or should it
be done in tsubst_qualified_id instead (before or after the
finish_qualified_id_expr call?
2019-03-13 Jakub Jelinek <jakub@redhat.com>
PR c++/89512
* semantics.c (finish_qualified_id_expr): Reject variable templates.
* g++.dg/cpp1y/var-templ61.C: New test.
--- gcc/cp/semantics.c.jj 2019-03-08 11:45:27.556465237 +0100
+++ gcc/cp/semantics.c 2019-03-13 17:41:58.694698814 +0100
@@ -2112,6 +2112,14 @@ finish_qualified_id_expr (tree qualifyin
expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false,
complain);
}
+ else if (!template_p
+ && TREE_CODE (expr) == TEMPLATE_DECL
+ && !DECL_FUNCTION_TEMPLATE_P (expr))
+ {
+ if (complain & tf_error)
+ error ("%qE missing template arguments", expr);
+ return error_mark_node;
+ }
else
{
/* In a template, return a SCOPE_REF for most qualified-ids
--- gcc/testsuite/g++.dg/cpp1y/var-templ61.C.jj 2019-03-13 17:36:33.895936102 +0100
+++ gcc/testsuite/g++.dg/cpp1y/var-templ61.C 2019-03-13 17:41:30.868147514 +0100
@@ -0,0 +1,20 @@
+// PR c++/89512
+// { dg-do compile { target c++14 } }
+
+struct A {
+ template <typename T>
+ static const int a = 0;
+};
+
+struct B {
+ template <typename T>
+ static int foo ()
+ {
+ return T::a; // { dg-error "missing template arguments" }
+ }
+};
+
+int bar ()
+{
+ return B::foo<A> (); // { dg-message "required from here" }
+}
Jakub