[llvm-branch-commits] [clang] 34e72a1 - Revert "DR2064: decltype(E) is only a dependent type if E is type-dependent, not"

Arthur Eubanks via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Dec 22 10:27:46 PST 2020


Author: Arthur Eubanks
Date: 2020-12-22T10:18:08-08:00
New Revision: 34e72a146111dd986889a0f0ec8767b2ca6b2913

URL: https://github.com/llvm/llvm-project/commit/34e72a146111dd986889a0f0ec8767b2ca6b2913
DIFF: https://github.com/llvm/llvm-project/commit/34e72a146111dd986889a0f0ec8767b2ca6b2913.diff

LOG: Revert "DR2064: decltype(E) is only a dependent type if E is type-dependent, not"

This reverts commit 638867afd4bce4a2c56dea041299428af3727d61.

This is part of 5 commits being reverted due to https://crbug.com/1161059. See bug for repro.

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 8c47047a7526..ca96b65574bd 100644
--- a/clang/include/clang/AST/DependenceFlags.h
+++ b/clang/include/clang/AST/DependenceFlags.h
@@ -255,12 +255,6 @@ 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 0190573fe36e..44545f00b146 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 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()) {
+  //   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()) {
     llvm::FoldingSetNodeID ID;
     DependentDecltypeType::Profile(ID, *this, e);
 

diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 01deb598a078..6c8d5687c64a 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2582,11 +2582,6 @@ 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 5dec80be9ccb..034e175f1352 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -125,7 +125,8 @@ ArrayType::ArrayType(TypeClass tc, QualType et, QualType can,
     //   template<int ...N> int arr[] = {N...};
     : Type(tc, can,
            et->getDependence() |
-               (sz ? toTypeDependence(sz->getDependence())
+               (sz ? toTypeDependence(
+                         turnValueToTypeDependence(sz->getDependence()))
                    : TypeDependence::None) |
                (tc == VariableArray ? TypeDependence::VariablyModified
                                     : TypeDependence::None) |
@@ -3395,8 +3396,9 @@ QualType MacroQualifiedType::getModifiedType() const {
 
 TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
     : Type(TypeOfExpr, can,
-           typeToTypeDependence(E->getDependence(),
-                                E->getType()->getDependence())),
+           toTypeDependence(E->getDependence()) |
+               (E->getType()->getDependence() &
+                TypeDependence::VariablyModified)),
       TOExpr(E) {}
 
 bool TypeOfExprType::isSugared() const {
@@ -3416,12 +3418,18 @@ 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,
-           typeToTypeDependence(E->getDependence(),
-                                E->getType()->getDependence())),
+           toTypeDependence(E->getDependence()) |
+               (E->isInstantiationDependent() ? TypeDependence::Dependent
+                                              : TypeDependence::None) |
+               (E->getType()->getDependence() &
+                TypeDependence::VariablyModified)),
       E(E), UnderlyingType(underlyingType) {}
 
-bool DecltypeType::isSugared() const { return !E->isTypeDependent(); }
+bool DecltypeType::isSugared() const { return !E->isInstantiationDependent(); }
 
 QualType DecltypeType::desugar() const {
   if (isSugared())

diff  --git a/clang/test/CXX/drs/dr20xx.cpp b/clang/test/CXX/drs/dr20xx.cpp
index 6e1c0505a5ec..56cc1161a00c 100644
--- a/clang/test/CXX/drs/dr20xx.cpp
+++ b/clang/test/CXX/drs/dr20xx.cpp
@@ -49,18 +49,6 @@ 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 8ce498feb4af..41ca9496de4f 100644
--- a/clang/test/Sema/invalid-bitwidth-expr.mm
+++ b/clang/test/Sema/invalid-bitwidth-expr.mm
@@ -26,7 +26,6 @@ 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 77601402a85c..7a1a7f801c45 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}} expected-error {{base specifier must name a class}}
+struct Crash2 : decltype(Alias<T>()) { // expected-note {{in instantiation of template type alias 'Alias' requested here}}
   Crash2(){};
 };
 
-void test2() { Crash2<int>(); } // expected-note 2{{in instantiation of template class 'Crash2<int>' requested here}}
+void test2() { Crash2<int>(); } // expected-note {{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 dace7e28788d..abdb8e9c4a9f 100644
--- a/clang/test/SemaTemplate/dependent-expr.cpp
+++ b/clang/test/SemaTemplate/dependent-expr.cpp
@@ -129,12 +129,7 @@ namespace PR45083 {
   template<typename> void f() {
     decltype(({})) x; // expected-error {{incomplete type}}
   }
-  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 void f<int>(); // 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 b9a1c933560d..03ef78f8cf14 100644
--- a/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp
+++ b/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp
@@ -115,12 +115,6 @@ namespace Auto {
 
   int n;
   template<auto A, decltype(A) B = &n> struct SubstFailure;
-  TInt<SubstFailure> isf; // expected-error {{template template argument has 
diff erent template parameters than its corresponding template template parameter}}
+  TInt<SubstFailure> isf; // FIXME: this should be ill-formed
   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 9be6f1262b68..57093c1cf5b0 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -12198,7 +12198,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="unreleased" align="center">Clang 12</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="2065">
     <td><a href="https://wg21.link/cwg2065">2065</a></td>


        


More information about the llvm-branch-commits mailing list