PR c++/87748 - substitution failure error with decltype.
This issue is similar to PR 87480; in both cases we were doing non-dependent substitution with processing_template_decl set, leading to member access expressions seeming still instantiation-dependent, and therefore decltype not being simplified to its actual type. And as in that PR, the fix is to clear processing_template_decl while substituting a default template argument. * pt.c (most_specialized_partial_spec): Clear processing_template_decl. From-SVN: r269921
This commit is contained in:
parent
51e471ae61
commit
b25e675d7d
3 changed files with 80 additions and 0 deletions
|
@ -1,3 +1,9 @@
|
|||
2019-03-25 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/87748 - substitution failure error with decltype.
|
||||
* pt.c (most_specialized_partial_spec): Clear
|
||||
processing_template_decl.
|
||||
|
||||
2019-03-25 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/89214 - ICE when initializing aggregates with bases.
|
||||
|
|
|
@ -23550,6 +23550,11 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain)
|
|||
args = INNERMOST_TEMPLATE_ARGS (args);
|
||||
}
|
||||
|
||||
/* The caller hasn't called push_to_top_level yet, but we need
|
||||
get_partial_spec_bindings to be done in non-template context so that we'll
|
||||
fully resolve everything. */
|
||||
processing_template_decl_sentinel ptds;
|
||||
|
||||
for (t = DECL_TEMPLATE_SPECIALIZATIONS (main_tmpl); t; t = TREE_CHAIN (t))
|
||||
{
|
||||
tree spec_args;
|
||||
|
|
69
gcc/testsuite/g++.dg/cpp0x/sfinae64.C
Normal file
69
gcc/testsuite/g++.dg/cpp0x/sfinae64.C
Normal file
|
@ -0,0 +1,69 @@
|
|||
// PR c++/87748
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
template <class T> T&& declval();
|
||||
template <bool B, class T> struct enable_if;
|
||||
template <class T> struct enable_if <true, T> { typedef T type; };
|
||||
struct true_type { static const bool value = true; };
|
||||
struct false_type { static const bool value = false; };
|
||||
|
||||
struct string
|
||||
{
|
||||
string (const char *p);
|
||||
};
|
||||
|
||||
/// Template to map all type arguments to void, useful for SFINAE, see also WG21 N3911.
|
||||
template<class...> using void_t = void;
|
||||
|
||||
/// REQUIRES<value> - Simplified version of enable_if<> to use SFINAE in function templates.
|
||||
template<bool value> using REQUIRES = typename ::enable_if<value, bool>::type;
|
||||
|
||||
/// DerivesString<T> - Check if @a T is of type 'string'.
|
||||
template<class T> struct DerivesString
|
||||
{
|
||||
static const int value = __is_same_as (T, string);
|
||||
};
|
||||
|
||||
/// Has__aida_visit__<T,Visitor> - Check if @a T provides a member template __aida_visit__<>(Visitor).
|
||||
template<class, class, class = void> struct Has__aida_visit__ : false_type {};
|
||||
template<class T, class V>
|
||||
struct Has__aida_visit__<T, V, void_t< decltype (declval<T>().template __aida_visit__<V> (*(V*) 0)) >> : true_type {};
|
||||
|
||||
struct Foo {
|
||||
template<class V> void __accept__ (V*);
|
||||
};
|
||||
|
||||
/// Base template for Visitor classes, dispatches operator() to visit_<type>() methods.
|
||||
template<class DerivedVisitor>
|
||||
class VisitorDispatcher {
|
||||
DerivedVisitor* derived () { return static_cast<DerivedVisitor*> (this); }
|
||||
protected:
|
||||
typedef const char* Name; ///< Member name argument type for visit() methods.
|
||||
public:
|
||||
|
||||
// dispatch for calls like: visitor (field, "field");
|
||||
|
||||
template<class A,
|
||||
REQUIRES< (!Has__aida_visit__<A, DerivedVisitor>::value) > = true>
|
||||
void operator() (A &a, Name n)
|
||||
{ return derived()->visit_string (a, n); }
|
||||
};
|
||||
|
||||
class PspecVisitor : public VisitorDispatcher<PspecVisitor> {
|
||||
public:
|
||||
void visit_string (::string &a, Name name);
|
||||
};
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
#ifdef WITHASSERT // define this to fix g++-8.1.1
|
||||
static_assert (Has__aida_visit__<string, PspecVisitor>::value == false, "");
|
||||
#endif
|
||||
PspecVisitor v;
|
||||
string str ("A string");
|
||||
v (str, "some_string");
|
||||
static_assert (Has__aida_visit__<string, PspecVisitor>::value == false, "");
|
||||
return 0;
|
||||
}
|
||||
// g++ -std=gnu++14 -Wall -O2 aidavisit.cc && ./a.out
|
Loading…
Add table
Reference in a new issue