PR c++/81045 - Wrong type-dependence with auto return type.
* pt.c (type_dependent_expression_p): An undeduced auto outside the template isn't dependent. * call.c (build_over_call): Instantiate undeduced auto even in a template. From-SVN: r249323
This commit is contained in:
parent
d4b1d43cec
commit
ccb7042db8
5 changed files with 85 additions and 10 deletions
|
@ -1,5 +1,11 @@
|
|||
2017-06-16 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/81045 - Wrong type-dependence with auto return type.
|
||||
* pt.c (type_dependent_expression_p): An undeduced auto outside the
|
||||
template isn't dependent.
|
||||
* call.c (build_over_call): Instantiate undeduced auto even in a
|
||||
template.
|
||||
|
||||
PR c++/80465 - ICE with generic lambda with noexcept-specifier.
|
||||
* lambda.c (maybe_add_lambda_conv_op): Keep processing_template_decl
|
||||
set longer for a generic lambda.
|
||||
|
|
|
@ -7584,6 +7584,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
|||
const tree *argarray;
|
||||
unsigned int nargs;
|
||||
|
||||
if (undeduced_auto_decl (fn))
|
||||
mark_used (fn, complain);
|
||||
|
||||
return_type = TREE_TYPE (TREE_TYPE (fn));
|
||||
nargs = vec_safe_length (args);
|
||||
if (first_arg == NULL_TREE)
|
||||
|
|
36
gcc/cp/pt.c
36
gcc/cp/pt.c
|
@ -24011,17 +24011,35 @@ type_dependent_expression_p (tree expression)
|
|||
return true;
|
||||
|
||||
/* A function or variable template-id is type-dependent if it has any
|
||||
dependent template arguments. Note that we only consider the innermost
|
||||
template arguments here, since those are the ones that come from the
|
||||
template-id; the template arguments for the enclosing class do not make it
|
||||
type-dependent, they only make a member function value-dependent. */
|
||||
dependent template arguments. */
|
||||
if (VAR_OR_FUNCTION_DECL_P (expression)
|
||||
&& DECL_LANG_SPECIFIC (expression)
|
||||
&& DECL_TEMPLATE_INFO (expression)
|
||||
&& PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (expression))
|
||||
&& (any_dependent_template_arguments_p
|
||||
(INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
|
||||
return true;
|
||||
&& DECL_TEMPLATE_INFO (expression))
|
||||
{
|
||||
/* Consider the innermost template arguments, since those are the ones
|
||||
that come from the template-id; the template arguments for the
|
||||
enclosing class do not make it type-dependent unless they are used in
|
||||
the type of the decl. */
|
||||
if (PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (expression))
|
||||
&& (any_dependent_template_arguments_p
|
||||
(INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
|
||||
return true;
|
||||
|
||||
/* Otherwise, if the decl isn't from a dependent scope, it can't be
|
||||
type-dependent. Checking this is important for functions with auto
|
||||
return type, which looks like a dependent type. */
|
||||
if (TREE_CODE (expression) == FUNCTION_DECL
|
||||
&& (!DECL_CLASS_SCOPE_P (expression)
|
||||
|| !dependent_type_p (DECL_CONTEXT (expression)))
|
||||
&& (!DECL_FRIEND_CONTEXT (expression)
|
||||
|| !dependent_type_p (DECL_FRIEND_CONTEXT (expression)))
|
||||
&& !DECL_LOCAL_FUNCTION_P (expression))
|
||||
{
|
||||
gcc_assert (!dependent_type_p (TREE_TYPE (expression))
|
||||
|| undeduced_auto_decl (expression));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Always dependent, on the number of arguments if nothing else. */
|
||||
if (TREE_CODE (expression) == EXPR_PACK_EXPANSION)
|
||||
|
|
|
@ -31,7 +31,7 @@ F<T>::bar (const G &)
|
|||
{
|
||||
auto s = I;
|
||||
typedef decltype (s) L;
|
||||
auto u =[&](L) { auto t = foo (J::K (), 0); }; // { dg-error "25:'void t' has incomplete type" }
|
||||
auto u =[&](L) { auto t = foo (J::K (), 0); }; // { dg-error "25:declared void" }
|
||||
}
|
||||
struct B {
|
||||
typedef int G;
|
||||
|
|
48
gcc/testsuite/g++.dg/cpp1y/auto-fn39.C
Normal file
48
gcc/testsuite/g++.dg/cpp1y/auto-fn39.C
Normal file
|
@ -0,0 +1,48 @@
|
|||
// PR c++/81045
|
||||
// { dg-do compile { target c++14 } }
|
||||
|
||||
template<typename T> class vectorIterator;
|
||||
|
||||
template<typename T> class vector {
|
||||
public:
|
||||
auto get(unsigned int i) { return data[i]; }
|
||||
|
||||
auto begin() { return vectorIterator<T>{*this, 0}; }
|
||||
auto end() { return vectorIterator<T>{*this, 10}; }
|
||||
|
||||
private:
|
||||
T data[10] = {};
|
||||
};
|
||||
|
||||
template<typename T> class vectorIterator {
|
||||
public:
|
||||
vectorIterator(vector<T>& self, unsigned int offset) : self(self), offset(offset) {}
|
||||
|
||||
auto operator*() -> T& { return self.get(offset); }
|
||||
auto operator!=(const vectorIterator& source) -> bool { return offset != source.offset; }
|
||||
auto operator++() -> vectorIterator& { ++offset; return *this; }
|
||||
|
||||
private:
|
||||
vector<T>& self;
|
||||
unsigned int offset;
|
||||
};
|
||||
|
||||
class Object {
|
||||
public:
|
||||
template<typename T> auto cast() -> T {
|
||||
return T();
|
||||
}
|
||||
};
|
||||
|
||||
class Group : public Object {
|
||||
public:
|
||||
template<typename T = Object> auto objects() const -> void {
|
||||
vector<Object> easyObjects;
|
||||
for(auto obj : easyObjects) {
|
||||
auto casted = obj.cast<T>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main() { return 0; }
|
||||
|
Loading…
Add table
Reference in a new issue