[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