[clang] 638867a - DR2064: decltype(E) is only a dependent type if E is type-dependent, not
Arthur Eubanks via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 21 19:43:38 PST 2020
I've bisected https://crbug.com/1161059 down to this change. Would you like
a reduced repro?
clang++:
/b/s/w/ir/cache/builder/src/third_party/llvm/clang/lib/AST/ItaniumMangle.cpp:5763:
void {anonymous}::CXXNameMangler::addSubstitution(uintptr_t): Assertion
`!Substitutions.count(Ptr) && "Substitution already exists!"' failed.
On Thu, Dec 17, 2020 at 11:23 PM Richard Smith via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
>
> Author: Richard Smith
> Date: 2020-12-17T23:23:05-08:00
> New Revision: 638867afd4bce4a2c56dea041299428af3727d61
>
> URL:
> https://github.com/llvm/llvm-project/commit/638867afd4bce4a2c56dea041299428af3727d61
> DIFF:
> https://github.com/llvm/llvm-project/commit/638867afd4bce4a2c56dea041299428af3727d61.diff
>
> LOG: DR2064: decltype(E) is only a dependent type if E is type-dependent,
> not
> if E is merely instantiation-dependent.
>
> Added:
>
>
> Modified:
> clang/include/clang/AST/DependenceFlags.h
> clang/lib/AST/ASTContext.cpp
> clang/lib/AST/ItaniumMangle.cpp
> clang/lib/AST/Type.cpp
> clang/test/CXX/drs/dr20xx.cpp
> clang/test/Sema/invalid-bitwidth-expr.mm
> clang/test/SemaCXX/invalid-template-base-specifier.cpp
> clang/test/SemaTemplate/dependent-expr.cpp
> clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp
> clang/www/cxx_dr_status.html
>
> Removed:
>
>
>
>
> ################################################################################
> diff --git a/clang/include/clang/AST/DependenceFlags.h
> b/clang/include/clang/AST/DependenceFlags.h
> index ca96b65574bd..8c47047a7526 100644
> --- a/clang/include/clang/AST/DependenceFlags.h
> +++ b/clang/include/clang/AST/DependenceFlags.h
> @@ -255,6 +255,12 @@ inline TypeDependence
> toTypeDependence(TemplateNameDependence D) {
> inline TypeDependence toTypeDependence(TemplateArgumentDependence D) {
> return Dependence(D).type();
> }
> +/// Compute the dependence of a type that depends on the type of an
> expression,
> +/// given the dependence of that expression and of its type.
> +inline TypeDependence typeToTypeDependence(ExprDependence ED,
> TypeDependence TD) {
> + return Dependence(ED & ~ExprDependence::Value).type() |
> + (TD & TypeDependence::VariablyModified);
> +}
>
> inline NestedNameSpecifierDependence
> toNestedNameSpecifierDependendence(TypeDependence D) {
>
> diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
> index 44545f00b146..0190573fe36e 100644
> --- a/clang/lib/AST/ASTContext.cpp
> +++ b/clang/lib/AST/ASTContext.cpp
> @@ -5383,10 +5383,10 @@ QualType ASTContext::getDecltypeType(Expr *e,
> QualType UnderlyingType) const {
> DecltypeType *dt;
>
> // C++11 [temp.type]p2:
> - // If an expression e involves a template parameter, decltype(e)
> denotes a
> - // unique dependent type. Two such decltype-specifiers refer to the
> same
> - // type only if their expressions are equivalent (14.5.6.1).
> - if (e->isInstantiationDependent()) {
> + // If an expression e is type-dependent, decltype(e) denotes a unique
> + // dependent type. Two such decltype-specifiers refer to the same
> type only
> + // if their expressions are equivalent (14.5.6.1).
> + if (e->isTypeDependent()) {
> llvm::FoldingSetNodeID ID;
> DependentDecltypeType::Profile(ID, *this, e);
>
>
> diff --git a/clang/lib/AST/ItaniumMangle.cpp
> b/clang/lib/AST/ItaniumMangle.cpp
> index 6c8d5687c64a..01deb598a078 100644
> --- a/clang/lib/AST/ItaniumMangle.cpp
> +++ b/clang/lib/AST/ItaniumMangle.cpp
> @@ -2582,6 +2582,11 @@ void CXXNameMangler::mangleType(QualType T) {
> // instantation-dependent qualifiers. See
> // https://github.com/itanium-cxx-abi/cxx-abi/issues/114.
>
> + // Don't desugar instantiation-dependent decltype / typeof types.
> We need
> + // to mangle the expression as written.
> + if (isa<DecltypeType, TypeOfType>(T))
> + break;
> +
> QualType Desugared
> = T.getSingleStepDesugaredType(Context.getASTContext());
> if (Desugared == T)
>
> diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
> index af39b80ef9e4..e5811dbc44c5 100644
> --- a/clang/lib/AST/Type.cpp
> +++ b/clang/lib/AST/Type.cpp
> @@ -125,8 +125,7 @@ ArrayType::ArrayType(TypeClass tc, QualType et,
> QualType can,
> // template<int ...N> int arr[] = {N...};
> : Type(tc, can,
> et->getDependence() |
> - (sz ? toTypeDependence(
> - turnValueToTypeDependence(sz->getDependence()))
> + (sz ? toTypeDependence(sz->getDependence())
> : TypeDependence::None) |
> (tc == VariableArray ? TypeDependence::VariablyModified
> : TypeDependence::None) |
> @@ -3396,9 +3395,8 @@ QualType MacroQualifiedType::getModifiedType() const
> {
>
> TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
> : Type(TypeOfExpr, can,
> - toTypeDependence(E->getDependence()) |
> - (E->getType()->getDependence() &
> - TypeDependence::VariablyModified)),
> + typeToTypeDependence(E->getDependence(),
> + E->getType()->getDependence())),
> TOExpr(E) {}
>
> bool TypeOfExprType::isSugared() const {
> @@ -3418,18 +3416,12 @@ void
> DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID,
> }
>
> DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
> - // C++11 [temp.type]p2: "If an expression e involves a template
> parameter,
> - // decltype(e) denotes a unique dependent type." Hence a decltype
> type is
> - // type-dependent even if its expression is only
> instantiation-dependent.
> : Type(Decltype, can,
> - toTypeDependence(E->getDependence()) |
> - (E->isInstantiationDependent() ? TypeDependence::Dependent
> - : TypeDependence::None) |
> - (E->getType()->getDependence() &
> - TypeDependence::VariablyModified)),
> + typeToTypeDependence(E->getDependence(),
> + E->getType()->getDependence())),
> E(E), UnderlyingType(underlyingType) {}
>
> -bool DecltypeType::isSugared() const { return
> !E->isInstantiationDependent(); }
> +bool DecltypeType::isSugared() const { return !E->isTypeDependent(); }
>
> QualType DecltypeType::desugar() const {
> if (isSugared())
>
> diff --git a/clang/test/CXX/drs/dr20xx.cpp b/clang/test/CXX/drs/dr20xx.cpp
> index 56cc1161a00c..6e1c0505a5ec 100644
> --- a/clang/test/CXX/drs/dr20xx.cpp
> +++ b/clang/test/CXX/drs/dr20xx.cpp
> @@ -49,6 +49,18 @@ namespace dr2026 { // dr2026: 11
> }
> }
>
> +namespace dr2064 { // dr2064: 12
> +#if __cplusplus >= 201103L
> + template<typename T> struct X {
> + template<typename U> struct Y {};
> + };
> + template<typename T> void f() {
> + X<decltype(sizeof(T))>::Y<int> y; // ok
> + return X<decltype(sizeof(T))>::f(); // expected-error {{no member
> named 'f' in 'dr2064::X<unsigned}}
> + }
> +#endif
> +}
> +
> namespace dr2082 { // dr2082: 11
> void test1(int x, int = sizeof(x)); // ok
> #if __cplusplus >= 201103L
>
> diff --git a/clang/test/Sema/invalid-bitwidth-expr.mm b/clang/test/Sema/
> invalid-bitwidth-expr.mm
> index 41ca9496de4f..8ce498feb4af 100644
> --- a/clang/test/Sema/invalid-bitwidth-expr.mm
> +++ b/clang/test/Sema/invalid-bitwidth-expr.mm
> @@ -26,6 +26,7 @@ auto func() {
> auto func() {
> // error-bit should be propagated from TemplateArgument to
> NestNameSpecifier.
> class Base<decltype(Foo(T()))>::type C; // expected-error {{no matching
> function for call to 'Foo'}}
> + // expected-error at -1 {{no class named 'type' in 'Base<bool>'}}
> return C;
> }
> struct Z {
>
> diff --git a/clang/test/SemaCXX/invalid-template-base-specifier.cpp
> b/clang/test/SemaCXX/invalid-template-base-specifier.cpp
> index 7a1a7f801c45..77601402a85c 100644
> --- a/clang/test/SemaCXX/invalid-template-base-specifier.cpp
> +++ b/clang/test/SemaCXX/invalid-template-base-specifier.cpp
> @@ -12,11 +12,11 @@ void test() { Crash<int>(); } // expected-note {{in
> instantiation of template cl
> template <typename T>
> using Alias = decltype(Foo(T())); // expected-error {{no matching
> function for call to 'Foo'}}
> template <typename T>
> -struct Crash2 : decltype(Alias<T>()) { // expected-note {{in
> instantiation of template type alias 'Alias' requested here}}
> +struct Crash2 : decltype(Alias<T>()) { // expected-note {{in
> instantiation of template type alias 'Alias' requested here}}
> expected-error {{base specifier must name a class}}
> Crash2(){};
> };
>
> -void test2() { Crash2<int>(); } // expected-note {{in instantiation of
> template class 'Crash2<int>' requested here}}
> +void test2() { Crash2<int>(); } // expected-note 2{{in instantiation of
> template class 'Crash2<int>' requested here}}
>
> template <typename T>
> class Base {};
>
> diff --git a/clang/test/SemaTemplate/dependent-expr.cpp
> b/clang/test/SemaTemplate/dependent-expr.cpp
> index abdb8e9c4a9f..dace7e28788d 100644
> --- a/clang/test/SemaTemplate/dependent-expr.cpp
> +++ b/clang/test/SemaTemplate/dependent-expr.cpp
> @@ -129,7 +129,12 @@ namespace PR45083 {
> template<typename> void f() {
> decltype(({})) x; // expected-error {{incomplete type}}
> }
> - template void f<int>(); // expected-note {{instantiation of}}
> + template void f<int>();
> +
> + template<typename T> void f2() {
> + decltype(({T();})) x; // expected-error {{incomplete type}}
> + }
> + template void f2<void>(); // expected-note {{instantiation of}}
>
> template<typename> auto g() {
> auto c = [](auto, int) -> decltype(({})) {};
>
> diff --git a/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp
> b/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp
> index 03ef78f8cf14..b9a1c933560d 100644
> --- a/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp
> +++ b/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp
> @@ -115,6 +115,12 @@ namespace Auto {
>
> int n;
> template<auto A, decltype(A) B = &n> struct SubstFailure;
> - TInt<SubstFailure> isf; // FIXME: this should be ill-formed
> + TInt<SubstFailure> isf; // expected-error {{template template argument
> has
> diff erent template parameters than its corresponding template template
> parameter}}
> TIntPtr<SubstFailure> ipsf;
> +
> + template<template<auto A, auto B, decltype(A)> typename C> struct
> TAutoAutoFirst {};
> + template<auto A, auto B, decltype(A)> struct AutoAutoFirst;
> + template<auto A, auto B, decltype(B)> struct AutoAutoSecond;
> + TAutoAutoFirst<AutoAutoFirst> aaf;
> + TAutoAutoFirst<AutoAutoSecond> aas; // FIXME: this should be rejected
> due to parameter mismatch
> }
>
> diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
> index feac3c6dc2d0..b40d2c53bdec 100755
> --- a/clang/www/cxx_dr_status.html
> +++ b/clang/www/cxx_dr_status.html
> @@ -12199,7 +12199,7 @@ <h2 id="cxxdr">C++ defect report implementation
> status</h2>
> <td><a href="https://wg21.link/cwg2064">2064</a></td>
> <td>CD4</td>
> <td>Conflicting specifications for dependent
> <I>decltype-specifier</I>s</td>
> - <td class="none" align="center">Unknown</td>
> + <td class="unreleased" align="center">Clang 12</td>
> </tr>
> <tr class="open" id="2065">
> <td><a href="https://wg21.link/cwg2065">2065</a></td>
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201221/92e5f0c0/attachment-0001.html>
More information about the cfe-commits
mailing list