mirror of git://gcc.gnu.org/git/gcc.git
re PR c++/66260 ([C++14] Failure to compile variable template with recursively defined partial specialization)
PR c++/66260 PR c++/66596 PR c++/66649 PR c++/66923 * pt.c (lookup_template_variable): Use NULL_TREE for type. (instantiate_template_1): Also set DECL_TI_ARGS based on the immediate parent. (tsubst_copy_and_build) [TEMPLATE_ID_EXPR]: Handle variable templates. (finish_template_variable): Add complain parm. * cp-tree.h: Adjust. From-SVN: r226642
This commit is contained in:
parent
85171e7877
commit
dc062b4986
|
|
@ -1,5 +1,16 @@
|
||||||
2015-08-05 Jason Merrill <jason@redhat.com>
|
2015-08-05 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
PR c++/66260
|
||||||
|
PR c++/66596
|
||||||
|
PR c++/66649
|
||||||
|
PR c++/66923
|
||||||
|
* pt.c (lookup_template_variable): Use NULL_TREE for type.
|
||||||
|
(instantiate_template_1): Also set DECL_TI_ARGS based on
|
||||||
|
the immediate parent.
|
||||||
|
(tsubst_copy_and_build) [TEMPLATE_ID_EXPR]: Handle variable templates.
|
||||||
|
(finish_template_variable): Add complain parm.
|
||||||
|
* cp-tree.h: Adjust.
|
||||||
|
|
||||||
PR c++/65195
|
PR c++/65195
|
||||||
PR c++/66619
|
PR c++/66619
|
||||||
* semantics.c (finish_id_expression): Call convert_from_reference
|
* semantics.c (finish_id_expression): Call convert_from_reference
|
||||||
|
|
|
||||||
|
|
@ -5954,7 +5954,7 @@ extern tree perform_koenig_lookup (tree, vec<tree, va_gc> *,
|
||||||
tsubst_flags_t);
|
tsubst_flags_t);
|
||||||
extern tree finish_call_expr (tree, vec<tree, va_gc> **, bool,
|
extern tree finish_call_expr (tree, vec<tree, va_gc> **, bool,
|
||||||
bool, tsubst_flags_t);
|
bool, tsubst_flags_t);
|
||||||
extern tree finish_template_variable (tree);
|
extern tree finish_template_variable (tree, tsubst_flags_t = tf_warning_or_error);
|
||||||
extern tree finish_increment_expr (tree, enum tree_code);
|
extern tree finish_increment_expr (tree, enum tree_code);
|
||||||
extern tree finish_this_expr (void);
|
extern tree finish_this_expr (void);
|
||||||
extern tree finish_pseudo_destructor_expr (tree, tree, tree, location_t);
|
extern tree finish_pseudo_destructor_expr (tree, tree, tree, location_t);
|
||||||
|
|
|
||||||
17
gcc/cp/pt.c
17
gcc/cp/pt.c
|
|
@ -8187,14 +8187,14 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context,
|
||||||
tree
|
tree
|
||||||
lookup_template_variable (tree templ, tree arglist)
|
lookup_template_variable (tree templ, tree arglist)
|
||||||
{
|
{
|
||||||
tree type = unknown_type_node;
|
tree type = NULL_TREE;
|
||||||
return build2 (TEMPLATE_ID_EXPR, type, templ, arglist);
|
return build2 (TEMPLATE_ID_EXPR, type, templ, arglist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Instantiate a variable declaration from a TEMPLATE_ID_EXPR for use. */
|
/* Instantiate a variable declaration from a TEMPLATE_ID_EXPR for use. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
finish_template_variable (tree var)
|
finish_template_variable (tree var, tsubst_flags_t complain)
|
||||||
{
|
{
|
||||||
tree templ = TREE_OPERAND (var, 0);
|
tree templ = TREE_OPERAND (var, 0);
|
||||||
|
|
||||||
|
|
@ -8203,7 +8203,6 @@ finish_template_variable (tree var)
|
||||||
arglist = add_outermost_template_args (tmpl_args, arglist);
|
arglist = add_outermost_template_args (tmpl_args, arglist);
|
||||||
|
|
||||||
tree parms = DECL_TEMPLATE_PARMS (templ);
|
tree parms = DECL_TEMPLATE_PARMS (templ);
|
||||||
tsubst_flags_t complain = tf_warning_or_error;
|
|
||||||
arglist = coerce_innermost_template_parms (parms, arglist, templ, complain,
|
arglist = coerce_innermost_template_parms (parms, arglist, templ, complain,
|
||||||
/*req_all*/true,
|
/*req_all*/true,
|
||||||
/*use_default*/true);
|
/*use_default*/true);
|
||||||
|
|
@ -14750,6 +14749,17 @@ tsubst_copy_and_build (tree t,
|
||||||
if (targs)
|
if (targs)
|
||||||
targs = tsubst_template_args (targs, args, complain, in_decl);
|
targs = tsubst_template_args (targs, args, complain, in_decl);
|
||||||
|
|
||||||
|
if (variable_template_p (templ))
|
||||||
|
{
|
||||||
|
templ = lookup_template_variable (templ, targs);
|
||||||
|
if (!any_dependent_template_arguments_p (targs))
|
||||||
|
{
|
||||||
|
templ = finish_template_variable (templ, complain);
|
||||||
|
mark_used (templ);
|
||||||
|
}
|
||||||
|
RETURN (convert_from_reference (templ));
|
||||||
|
}
|
||||||
|
|
||||||
if (TREE_CODE (templ) == COMPONENT_REF)
|
if (TREE_CODE (templ) == COMPONENT_REF)
|
||||||
{
|
{
|
||||||
object = TREE_OPERAND (templ, 0);
|
object = TREE_OPERAND (templ, 0);
|
||||||
|
|
@ -16153,6 +16163,7 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain)
|
||||||
/* The DECL_TI_TEMPLATE should always be the immediate parent
|
/* The DECL_TI_TEMPLATE should always be the immediate parent
|
||||||
template, not the most general template. */
|
template, not the most general template. */
|
||||||
DECL_TI_TEMPLATE (fndecl) = tmpl;
|
DECL_TI_TEMPLATE (fndecl) = tmpl;
|
||||||
|
DECL_TI_ARGS (fndecl) = targ_ptr;
|
||||||
|
|
||||||
/* Now we know the specialization, compute access previously
|
/* Now we know the specialization, compute access previously
|
||||||
deferred. */
|
deferred. */
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,4 @@ template<typename T>
|
||||||
bool V1 = true;
|
bool V1 = true;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool V1<int> = false; // { dg-error "primary template" }
|
bool V1<int> = false; // { dg-error "primary template|not deducible" }
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@
|
||||||
// { dg-do compile { target c++14 } }
|
// { dg-do compile { target c++14 } }
|
||||||
|
|
||||||
template<typename T> int typeID{42};
|
template<typename T> int typeID{42};
|
||||||
template<typename T> double typeID<double>{10.10}; // { dg-error "primary template|redeclaration" }
|
template<typename T> double typeID<double>{10.10}; // { dg-error "primary template|redeclaration|not deducible" }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// { dg-do compile { target c++14 } }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
constexpr T v = T();
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
constexpr T v<T*> = T();
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct A {
|
||||||
|
static constexpr decltype (v<T>) v = ::v<T>;
|
||||||
|
};
|
||||||
|
|
||||||
|
double d1 = v<double*>;
|
||||||
|
double d2 = A<double*>::v;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
// PR c++/66596
|
||||||
|
// { dg-do compile { target c++14 } }
|
||||||
|
|
||||||
|
struct U { void f() {} };
|
||||||
|
struct V { void f() {} };
|
||||||
|
template<class T> U t;
|
||||||
|
template<> V t<int>;
|
||||||
|
template<class T> void g() { t<T>.f(); }
|
||||||
|
int main() { g<int>(); }
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// PR c++/66260
|
||||||
|
// { dg-do compile { target c++14 } }
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
constexpr bool foo = false;
|
||||||
|
template <>
|
||||||
|
constexpr bool foo<int> = true;
|
||||||
|
template <class T, int N>
|
||||||
|
constexpr bool foo<T[N]> = foo<T>;
|
||||||
|
|
||||||
|
static_assert(foo<int>, "");
|
||||||
|
static_assert(!foo<double>, "");
|
||||||
|
static_assert(foo<int[3]>, "");
|
||||||
|
static_assert(!foo<double[3]>, "");
|
||||||
|
static_assert(foo<int[2][5][3]>, "");
|
||||||
|
static_assert(!foo<double[2][5][3]>, "");
|
||||||
Loading…
Reference in New Issue