Skip to content

Commit da98651

Browse files
committed
Revert "DR2064: decltype(E) is only a dependent type if E is type-dependent, not
if E is merely instantiation-dependent." This change leaves us unable to distinguish between different function templates that differ in only instantiation-dependent ways, for example template<typename T> decltype(int(T())) f(); template<typename T> decltype(int(T(0))) f(); We'll need substantially better support for types that are instantiation-dependent but not dependent before we can go ahead with this change. This reverts commit e3065ce.
1 parent 5a684b7 commit da98651

File tree

12 files changed

+37
-74
lines changed

12 files changed

+37
-74
lines changed

clang/include/clang/AST/DependenceFlags.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -255,12 +255,6 @@ inline TypeDependence toTypeDependence(TemplateNameDependence D) {
255255
inline TypeDependence toTypeDependence(TemplateArgumentDependence D) {
256256
return Dependence(D).type();
257257
}
258-
/// Compute the dependence of a type that depends on the type of an expression,
259-
/// given the dependence of that expression and of its type.
260-
inline TypeDependence typeToTypeDependence(ExprDependence ED, TypeDependence TD) {
261-
return Dependence(ED & ~ExprDependence::Value).type() |
262-
(TD & TypeDependence::VariablyModified);
263-
}
264258

265259
inline NestedNameSpecifierDependence
266260
toNestedNameSpecifierDependendence(TypeDependence D) {

clang/lib/AST/ASTContext.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5383,10 +5383,10 @@ QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {
53835383
DecltypeType *dt;
53845384

53855385
// C++11 [temp.type]p2:
5386-
// If an expression e is type-dependent, decltype(e) denotes a unique
5387-
// dependent type. Two such decltype-specifiers refer to the same type only
5388-
// if their expressions are equivalent (14.5.6.1).
5389-
if (e->isTypeDependent()) {
5386+
// If an expression e involves a template parameter, decltype(e) denotes a
5387+
// unique dependent type. Two such decltype-specifiers refer to the same
5388+
// type only if their expressions are equivalent (14.5.6.1).
5389+
if (e->isInstantiationDependent()) {
53905390
llvm::FoldingSetNodeID ID;
53915391
DependentDecltypeType::Profile(ID, *this, e);
53925392

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2578,11 +2578,6 @@ void CXXNameMangler::mangleType(QualType T) {
25782578
if (!TST->isTypeAlias())
25792579
break;
25802580

2581-
// Don't desugar instantiation-dependent decltype / typeof types. We need
2582-
// to mangle the expression as written.
2583-
if (isa<DecltypeType, TypeOfType>(T))
2584-
break;
2585-
25862581
// FIXME: We presumably shouldn't strip off ElaboratedTypes with
25872582
// instantation-dependent qualifiers. See
25882583
// https://github.com/itanium-cxx-abi/cxx-abi/issues/114.
@@ -5612,11 +5607,12 @@ static bool hasMangledSubstitutionQualifiers(QualType T) {
56125607

56135608
bool CXXNameMangler::mangleSubstitution(QualType T) {
56145609
if (!hasMangledSubstitutionQualifiers(T)) {
5615-
if (const RecordType *RT = dyn_cast<RecordType>(T))
5610+
if (const RecordType *RT = T->getAs<RecordType>())
56165611
return mangleSubstitution(RT->getDecl());
56175612
}
56185613

56195614
uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
5615+
56205616
return mangleSubstitution(TypePtr);
56215617
}
56225618

@@ -5775,7 +5771,7 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
57755771

57765772
void CXXNameMangler::addSubstitution(QualType T) {
57775773
if (!hasMangledSubstitutionQualifiers(T)) {
5778-
if (const RecordType *RT = dyn_cast<RecordType>(T)) {
5774+
if (const RecordType *RT = T->getAs<RecordType>()) {
57795775
addSubstitution(RT->getDecl());
57805776
return;
57815777
}

clang/lib/AST/Type.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ ArrayType::ArrayType(TypeClass tc, QualType et, QualType can,
125125
// template<int ...N> int arr[] = {N...};
126126
: Type(tc, can,
127127
et->getDependence() |
128-
(sz ? toTypeDependence(sz->getDependence())
128+
(sz ? toTypeDependence(
129+
turnValueToTypeDependence(sz->getDependence()))
129130
: TypeDependence::None) |
130131
(tc == VariableArray ? TypeDependence::VariablyModified
131132
: TypeDependence::None) |
@@ -3395,8 +3396,9 @@ QualType MacroQualifiedType::getModifiedType() const {
33953396

33963397
TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
33973398
: Type(TypeOfExpr, can,
3398-
typeToTypeDependence(E->getDependence(),
3399-
E->getType()->getDependence())),
3399+
toTypeDependence(E->getDependence()) |
3400+
(E->getType()->getDependence() &
3401+
TypeDependence::VariablyModified)),
34003402
TOExpr(E) {}
34013403

34023404
bool TypeOfExprType::isSugared() const {
@@ -3416,12 +3418,18 @@ void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID,
34163418
}
34173419

34183420
DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
3421+
// C++11 [temp.type]p2: "If an expression e involves a template parameter,
3422+
// decltype(e) denotes a unique dependent type." Hence a decltype type is
3423+
// type-dependent even if its expression is only instantiation-dependent.
34193424
: Type(Decltype, can,
3420-
typeToTypeDependence(E->getDependence(),
3421-
E->getType()->getDependence())),
3425+
toTypeDependence(E->getDependence()) |
3426+
(E->isInstantiationDependent() ? TypeDependence::Dependent
3427+
: TypeDependence::None) |
3428+
(E->getType()->getDependence() &
3429+
TypeDependence::VariablyModified)),
34223430
E(E), UnderlyingType(underlyingType) {}
34233431

3424-
bool DecltypeType::isSugared() const { return !E->isTypeDependent(); }
3432+
bool DecltypeType::isSugared() const { return !E->isInstantiationDependent(); }
34253433

34263434
QualType DecltypeType::desugar() const {
34273435
if (isSugared())

clang/test/CXX/drs/dr20xx.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,6 @@ namespace dr2026 { // dr2026: 11
4949
}
5050
}
5151

52-
namespace dr2064 { // dr2064: 12
53-
#if __cplusplus >= 201103L
54-
template<typename T> struct X {
55-
template<typename U> struct Y {};
56-
};
57-
template<typename T> void f() {
58-
X<decltype(sizeof(T))>::Y<int> y; // ok
59-
return X<decltype(sizeof(T))>::f(); // expected-error {{no member named 'f' in 'dr2064::X<unsigned}}
60-
}
61-
#endif
62-
}
63-
6452
namespace dr2082 { // dr2082: 11
6553
void test1(int x, int = sizeof(x)); // ok
6654
#if __cplusplus >= 201103L

clang/test/CodeGenCXX/mangle-subst.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,3 @@ typename X<T>::template Y<T>::type f(typename X<T>::template Y<T>::type2) { retu
9696
// CHECK: @_ZN12ManglePrefix1fIiEENS_1XIT_E1YIS2_E4typeENS5_5type2E
9797
template int f<int>(int);
9898
}
99-
100-
namespace InstantiationDependentDecltype {
101-
struct a { a(char); };
102-
struct b { a c(); };
103-
// FIXME: This mangling is incorrect; the second decltype type should be a
104-
// substitution for the first.
105-
// CHECK: @_ZN30InstantiationDependentDecltype1fINS_1bEEEvDTcvNS_1aEcldtcvT__E1cEEDTcvS2_cldtcvS3__E1cEES3_S3_S2_S2_
106-
// FIXME: @_ZN30InstantiationDependentDecltype1fINS_1bEEEvDTcvNS_1aEcldtcvT__E1cEES4_S3_S3_S2_S2_
107-
template<typename d> void f(decltype(a(d().c())), decltype(a(d().c())), d, d, a, a);
108-
void g(a a, b b) { f(a, a, b, b, a, a); }
109-
}

clang/test/Sema/invalid-bitwidth-expr.mm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ auto func() {
2626
auto func() {
2727
// error-bit should be propagated from TemplateArgument to NestNameSpecifier.
2828
class Base<decltype(Foo(T()))>::type C; // expected-error {{no matching function for call to 'Foo'}}
29-
// expected-error@-1 {{no class named 'type' in 'Base<bool>'}}
3029
return C;
3130
}
3231
struct Z {

clang/test/SemaCXX/coroutines.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,8 +1179,8 @@ struct TestType {
11791179
static CoroMemberTag test_static_template(const char *volatile &, unsigned) {
11801180
auto TC = co_yield 0;
11811181
using TCT = decltype(TC);
1182-
static_assert(TCT::MatchesArgs<const char *volatile &, unsigned>, "");
1183-
static_assert(!TCT::MatchesArgs<TestType &, const char *volatile &, unsigned>, "");
1182+
static_assert(TCT::template MatchesArgs<const char *volatile &, unsigned>, "");
1183+
static_assert(!TCT::template MatchesArgs<TestType &, const char *volatile &, unsigned>, "");
11841184
}
11851185

11861186
BadCoroMemberTag test_diagnostics() {
@@ -1263,31 +1263,31 @@ struct DepTestType {
12631263
static CoroMemberTag test_static() {
12641264
auto TC = co_yield 0;
12651265
using TCT = decltype(TC);
1266-
static_assert(TCT::MatchesArgs<>, "");
1267-
static_assert(!TCT::MatchesArgs<DepTestType>, "");
1268-
static_assert(!TCT::MatchesArgs<DepTestType &>, "");
1269-
static_assert(!TCT::MatchesArgs<DepTestType *>, "");
1266+
static_assert(TCT::template MatchesArgs<>, "");
1267+
static_assert(!TCT::template MatchesArgs<DepTestType>, "");
1268+
static_assert(!TCT::template MatchesArgs<DepTestType &>, "");
1269+
static_assert(!TCT::template MatchesArgs<DepTestType *>, "");
12701270

12711271
// Ensure diagnostics are actually being generated here
1272-
static_assert(TCT::MatchesArgs<int>, ""); // expected-error {{static_assert failed}}
1272+
static_assert(TCT::template MatchesArgs<int>, ""); // expected-error {{static_assert failed}}
12731273
}
12741274

12751275
static CoroMemberTag test_static(volatile void *const, char &&) {
12761276
auto TC = co_yield 0;
12771277
using TCT = decltype(TC);
1278-
static_assert(TCT::MatchesArgs<volatile void *const, char &&>, "");
1278+
static_assert(TCT::template MatchesArgs<volatile void *const, char &&>, "");
12791279
}
12801280

12811281
template <class Dummy>
12821282
static CoroMemberTag test_static_template(const char *volatile &, unsigned) {
12831283
auto TC = co_yield 0;
12841284
using TCT = decltype(TC);
1285-
static_assert(TCT::MatchesArgs<const char *volatile &, unsigned>, "");
1286-
static_assert(!TCT::MatchesArgs<DepTestType &, const char *volatile &, unsigned>, "");
1285+
static_assert(TCT::template MatchesArgs<const char *volatile &, unsigned>, "");
1286+
static_assert(!TCT::template MatchesArgs<DepTestType &, const char *volatile &, unsigned>, "");
12871287
}
12881288
};
12891289

1290-
template struct DepTestType<int>; // expected-note {{requested here}}
1290+
template struct DepTestType<int>; // expected-note 2{{requested here}}
12911291
template CoroMemberTag DepTestType<int>::test_member_template(long, const char *) const &&;
12921292

12931293
template CoroMemberTag DepTestType<int>::test_static_template<void>(const char *volatile &, unsigned);

clang/test/SemaCXX/invalid-template-base-specifier.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ void test() { Crash<int>(); } // expected-note {{in instantiation of template cl
1212
template <typename T>
1313
using Alias = decltype(Foo(T())); // expected-error {{no matching function for call to 'Foo'}}
1414
template <typename T>
15-
struct Crash2 : decltype(Alias<T>()) { // expected-note {{in instantiation of template type alias 'Alias' requested here}} expected-error {{base specifier must name a class}}
15+
struct Crash2 : decltype(Alias<T>()) { // expected-note {{in instantiation of template type alias 'Alias' requested here}}
1616
Crash2(){};
1717
};
1818

19-
void test2() { Crash2<int>(); } // expected-note 2{{in instantiation of template class 'Crash2<int>' requested here}}
19+
void test2() { Crash2<int>(); } // expected-note {{in instantiation of template class 'Crash2<int>' requested here}}
2020

2121
template <typename T>
2222
class Base {};

clang/test/SemaTemplate/dependent-expr.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,7 @@ namespace PR45083 {
129129
template<typename> void f() {
130130
decltype(({})) x; // expected-error {{incomplete type}}
131131
}
132-
template void f<int>();
133-
134-
template<typename T> void f2() {
135-
decltype(({T();})) x; // expected-error {{incomplete type}}
136-
}
137-
template void f2<void>(); // expected-note {{instantiation of}}
132+
template void f<int>(); // expected-note {{instantiation of}}
138133

139134
template<typename> auto g() {
140135
auto c = [](auto, int) -> decltype(({})) {};

clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,6 @@ namespace Auto {
115115

116116
int n;
117117
template<auto A, decltype(A) B = &n> struct SubstFailure;
118-
TInt<SubstFailure> isf; // expected-error {{template template argument has different template parameters than its corresponding template template parameter}}
118+
TInt<SubstFailure> isf; // FIXME: this should be ill-formed
119119
TIntPtr<SubstFailure> ipsf;
120-
121-
template<template<auto A, auto B, decltype(A)> typename C> struct TAutoAutoFirst {};
122-
template<auto A, auto B, decltype(A)> struct AutoAutoFirst;
123-
template<auto A, auto B, decltype(B)> struct AutoAutoSecond;
124-
TAutoAutoFirst<AutoAutoFirst> aaf;
125-
TAutoAutoFirst<AutoAutoSecond> aas; // FIXME: this should be rejected due to parameter mismatch
126120
}

clang/www/cxx_dr_status.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12198,7 +12198,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
1219812198
<td><a href="https://wg21.link/cwg2064">2064</a></td>
1219912199
<td>CD4</td>
1220012200
<td>Conflicting specifications for dependent <I>decltype-specifier</I>s</td>
12201-
<td class="unreleased" align="center">Clang 12</td>
12201+
<td class="none" align="center">Unknown</td>
1220212202
</tr>
1220312203
<tr class="open" id="2065">
1220412204
<td><a href="https://wg21.link/cwg2065">2065</a></td>

0 commit comments

Comments
 (0)