On Tue, Mar 24, 2015 at 01:14:50AM -0400, Jason Merrill wrote: Here's my shot at this.
> The problem is that the type is considered dependent in a template but is > not actually dependent, so we can see the exact same type outside a template Yeah, I think this is true... > and it's not dependent. So, this code is creating the difference: > > /* We can only call value_dependent_expression_p on integral constant > > expressions; treat non-constant expressions as dependent, too. */ > > if (processing_template_decl > > && (type_dependent_expression_p (size) > > || !TREE_CONSTANT (size) || value_dependent_expression_p (size))) > > Now that we have instantiation_dependent_expression_p, we should be able to > use that instead of checking type/value dependency separately. ...but I think there's another place where things go wrong. ISTM that in build_cplus_array_type we consider all arrays with non-constant index as dependent (when processing_template_decl) -- but as the testcase shows, this is not always true. The fix then could look like the following, though I wouldn't be surprised if this was a wrong way how to go about this. Bootstrapped/regtested on x86_64-linux. Not a regression, so we might want to defer this patch to the next stage1. 2015-03-31 Marek Polacek <pola...@redhat.com> PR c++/65390 * tree.c (build_cplus_array_type): Use dependent_type_p rather than checking for constness. * g++.dg/template/pr65390.C: New test. diff --git gcc/cp/tree.c gcc/cp/tree.c index ef53aff..97bccc0 100644 --- gcc/cp/tree.c +++ gcc/cp/tree.c @@ -822,10 +822,9 @@ build_cplus_array_type (tree elt_type, tree index_type) if (elt_type == error_mark_node || index_type == error_mark_node) return error_mark_node; - bool dependent - = (processing_template_decl - && (dependent_type_p (elt_type) - || (index_type && !TREE_CONSTANT (TYPE_MAX_VALUE (index_type))))); + bool dependent = (processing_template_decl + && (dependent_type_p (elt_type) + || (index_type && dependent_type_p (index_type)))); if (elt_type != TYPE_MAIN_VARIANT (elt_type)) /* Start with an array of the TYPE_MAIN_VARIANT. */ diff --git gcc/testsuite/g++.dg/template/pr65390.C gcc/testsuite/g++.dg/template/pr65390.C index e69de29..299d22a 100644 --- gcc/testsuite/g++.dg/template/pr65390.C +++ gcc/testsuite/g++.dg/template/pr65390.C @@ -0,0 +1,12 @@ +// PR c++/65390 +// { dg-do compile } +// { dg-options "" } + +template<typename T> struct shared_ptr { }; + +template<typename T, typename Arg> +shared_ptr<T> make_shared(Arg) { return shared_ptr<T>(); } // { dg-error "variably modified type|trying to instantiate" } + +void f(int n){ + make_shared<int[n]>(1); // { dg-error "no matching function" } +} Marek