mirror of
https://github.com/intel/llvm.git
synced 2026-01-28 19:43:38 +08:00
Revert "PR24076, PR33655, C++ CWG 1558: Consider the instantiation-dependence of"
This reverts commit d3bf0bb189.
This causes compilation in certain cases to fail.
Reproducer TBD.
This commit is contained in:
@@ -5411,9 +5411,7 @@ class ElaboratedType final
|
||||
ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
|
||||
QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl)
|
||||
: TypeWithKeyword(Keyword, Elaborated, CanonType,
|
||||
NamedType->getDependence() |
|
||||
(NNS ? toTypeDependence(NNS->getDependence())
|
||||
: TypeDependence::None)),
|
||||
NamedType->getDependence()),
|
||||
NNS(NNS), NamedType(NamedType) {
|
||||
ElaboratedTypeBits.HasOwnedTagDecl = false;
|
||||
if (OwnedTagDecl) {
|
||||
|
||||
@@ -2578,10 +2578,6 @@ void CXXNameMangler::mangleType(QualType T) {
|
||||
if (!TST->isTypeAlias())
|
||||
break;
|
||||
|
||||
// FIXME: We presumably shouldn't strip off ElaboratedTypes with
|
||||
// instantation-dependent qualifiers. See
|
||||
// https://github.com/itanium-cxx-abi/cxx-abi/issues/114.
|
||||
|
||||
QualType Desugared
|
||||
= T.getSingleStepDesugaredType(Context.getASTContext());
|
||||
if (Desugared == T)
|
||||
|
||||
@@ -239,20 +239,6 @@ namespace dr1550 { // dr1550: yes
|
||||
}
|
||||
}
|
||||
|
||||
namespace dr1558 { // dr1558: 12
|
||||
#if __cplusplus >= 201103L
|
||||
template<class T, class...> using first_of = T;
|
||||
template<class T> first_of<void, typename T::type> f(int); // expected-note {{'int' cannot be used prior to '::'}}
|
||||
template<class T> void f(...) = delete; // expected-note {{deleted}}
|
||||
|
||||
struct X { typedef void type; };
|
||||
void test() {
|
||||
f<X>(0);
|
||||
f<int>(0); // expected-error {{deleted}}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace dr1560 { // dr1560: 3.5
|
||||
void f(bool b, int n) {
|
||||
(b ? throw 0 : n) = (b ? n : throw 0) = 0;
|
||||
|
||||
@@ -342,23 +342,3 @@ namespace fixed_size_parameter_pack {
|
||||
template<int ...Ns> void f(A<unsigned, char, long long>::B<0, Ns...>);
|
||||
void g() { f<1, 2>({}); }
|
||||
}
|
||||
|
||||
namespace type_qualifier {
|
||||
template<typename T> using int_t = int;
|
||||
template<typename T> void f(decltype(int_t<T*>() + 1)) {}
|
||||
// FIXME: This mangling doesn't work: we need to mangle the
|
||||
// instantiation-dependent 'int_t' operand.
|
||||
// CHECK: @_ZN14type_qualifier1fIPiEEvDTplcvi_ELi1EE
|
||||
template void f<int*>(int);
|
||||
|
||||
// Note that this template has different constraints but would mangle the
|
||||
// same:
|
||||
//template<typename T> void f(decltype(int_t<typename T::type>() + 1)) {}
|
||||
|
||||
struct impl { using type = void; };
|
||||
template<typename T> using alias = impl;
|
||||
template<typename T> void g(decltype(alias<T*>::type(), 1)) {}
|
||||
// FIXME: Similarly we need to mangle the `T*` in here.
|
||||
// CHECK: @_ZN14type_qualifier1gIPiEEvDTcmcvv_ELi1EE
|
||||
template void g<int*>(int);
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
// RUN: %clang_cc1 -std=c++2b -verify %s
|
||||
|
||||
// Ensure we substitute into instantiation-dependent but non-dependent
|
||||
// constructs. The poster-child for this is...
|
||||
template<class ...> using void_t = void;
|
||||
|
||||
namespace PR24076 {
|
||||
template<class T> T declval();
|
||||
struct s {};
|
||||
|
||||
template<class T,
|
||||
class = void_t<decltype(declval<T>() + 1)>>
|
||||
void foo(T) {} // expected-note {{invalid operands to binary expression}}
|
||||
|
||||
void f() {
|
||||
foo(s{}); // expected-error {{no matching function}}
|
||||
}
|
||||
|
||||
template<class T,
|
||||
class = void_t<decltype(declval<T>() + 1)>> // expected-error {{invalid operands to binary expression}}
|
||||
struct bar {};
|
||||
|
||||
bar<s> bar; // expected-note {{in instantiation of}}
|
||||
}
|
||||
|
||||
namespace PR33655 {
|
||||
struct One { using x = int; };
|
||||
struct Two { using y = int; };
|
||||
|
||||
template<typename T, void_t<typename T::x> * = nullptr> int &func() {}
|
||||
template<typename T, void_t<typename T::y> * = nullptr> float &func() {}
|
||||
|
||||
int &test1 = func<One>();
|
||||
float &test2 = func<Two>();
|
||||
|
||||
template<class ...Args> struct indirect_void_t_imp { using type = void; };
|
||||
template<class ...Args> using indirect_void_t = typename indirect_void_t_imp<Args...>::type;
|
||||
|
||||
template<class T> void foo() {
|
||||
static_assert(!__is_void(indirect_void_t<T>)); // "ok", dependent
|
||||
static_assert(!__is_void(void_t<T>)); // expected-error {{failed}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace PR46791 { // also PR45782
|
||||
template<typename T, typename = void>
|
||||
struct trait {
|
||||
static constexpr int specialization = 0;
|
||||
};
|
||||
|
||||
// FIXME: Per a strict interpretation of the C++ rules, the two void_t<...>
|
||||
// types below are equivalent -- we only (effectively) do token-by-token
|
||||
// comparison for *expressions* appearing within types. But all other
|
||||
// implementations accept this, using rules that are unclear.
|
||||
template<typename T>
|
||||
struct trait<T, void_t<typename T::value_type>> { // expected-note {{previous}} FIXME-note {{matches}}
|
||||
static constexpr int specialization = 1;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct trait<T, void_t<typename T::element_type>> { // expected-error {{redefinition}} FIXME-note {{matches}}
|
||||
static constexpr int specialization = 2;
|
||||
};
|
||||
|
||||
struct A {};
|
||||
struct B { typedef int value_type; };
|
||||
struct C { typedef int element_type; };
|
||||
struct D : B, C {};
|
||||
|
||||
static_assert(trait<A>::specialization == 0);
|
||||
static_assert(trait<B>::specialization == 1); // FIXME expected-error {{failed}}
|
||||
static_assert(trait<C>::specialization == 2); // FIXME expected-error {{failed}}
|
||||
static_assert(trait<D>::specialization == 0); // FIXME-error {{ambiguous partial specialization}}
|
||||
}
|
||||
@@ -51,6 +51,8 @@ namespace rdar9169404 {
|
||||
X<bool, -1>::type value;
|
||||
#if __cplusplus >= 201103L
|
||||
// expected-error@-2 {{non-type template argument evaluates to -1, which cannot be narrowed to type 'bool'}}
|
||||
#else
|
||||
// expected-no-diagnostics
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -96,19 +98,3 @@ namespace rdar39524996 {
|
||||
takesWrapperInContainer(c);
|
||||
}
|
||||
}
|
||||
|
||||
namespace InstantiationDependent {
|
||||
template<typename> using ignore = void; // expected-warning 0-1{{extension}}
|
||||
template<typename T, typename = void> struct A {
|
||||
static const bool specialized = false;
|
||||
};
|
||||
template<typename T> struct Hide { typedef void type; };
|
||||
template<typename T> struct A<T, Hide<ignore<typename T::type> >::type> {
|
||||
static const bool specialized = true;
|
||||
};
|
||||
|
||||
struct X {};
|
||||
struct Y { typedef int type; };
|
||||
_Static_assert(!A<X>::specialized, "");
|
||||
_Static_assert(A<Y>::specialized, "");
|
||||
}
|
||||
|
||||
@@ -9162,7 +9162,7 @@ and <I>POD class</I></td>
|
||||
<td><a href="https://wg21.link/cwg1558">1558</a></td>
|
||||
<td>CD4</td>
|
||||
<td>Unused arguments in alias template specializations</td>
|
||||
<td class="unreleased" align="center">Clang 12</td>
|
||||
<td class="none" align="center">Unknown</td>
|
||||
</tr>
|
||||
<tr id="1559">
|
||||
<td><a href="https://wg21.link/cwg1559">1559</a></td>
|
||||
|
||||
Reference in New Issue
Block a user